Skip to content

Instantly share code, notes, and snippets.

@ShiftedClock
Last active April 5, 2019 20:14
Show Gist options
  • Select an option

  • Save ShiftedClock/7922bb0c1614ea77d4fc98909ba057bc to your computer and use it in GitHub Desktop.

Select an option

Save ShiftedClock/7922bb0c1614ea77d4fc98909ba057bc to your computer and use it in GitHub Desktop.
Raymarching setup
float distanceField (float3 p) {
float res;
if (scene == 0) {
res = Scene0(p);
} else if (scene == 1) {
res = Scene1(p);
} else if (scene == 2) {
res = Scene2(p);
} else if (scene == 3) {
res = Scene3(p);
} else if (scene == 4) {
res = Scene4(p);
}
return res;
}
bool raymarching (float3 ro, float3 rd, float depth, float maxDistance, int maxIterations, float accuracy, inout float3 p) {
bool hit;
float t = 0;
for (int i=0; i<maxIterations; i++) {
if (t > maxDistance || t >= depth) {
hit = false;
break;
}
p = ro + rd * t;
float d = distanceField(p);
if (d < accuracy) {
hit = true;
break;
}
t += d * _stepSizeScaler;
}
return hit;
}
fixed4 frag (v2f i) : SV_TARGET {
float depth = LinearEyeDepth(tex2D(_CameraDepthTexture, i.uv).r);
depth *= length(i.ray);
fixed3 col = tex2D(_MainTex, i.uv);
float3 rayDirection = normalize(i.ray.xyz);
float3 rayOrigin = _WorldSpaceCameraPos;
fixed4 result;
float3 hitPosition;
bool hit = raymarching(rayOrigin, rayDirection, depth, _maxDistance, _MaxIterations, _Accuracy, hitPosition);
//int hit = raymarching()
//if (hit > 0)
//TODO: Try colouring pixels based on iterationCount, and apply antialiasing on a per-scene basis.
// i.e. when iterationCount is above a threshold value (determined for each scene), add AA to those pixels.
if (hit) {
//shading!
float3 n = getNormal(hitPosition);
float3 s = Shading(hitPosition,n);
result = fixed4(s,1);
//TODO: Put this behind a doReflections flag
//if (doReflections)
#if REFLECTIONS == 1
result += fixed4(texCUBE(_ReflectionCube, n).rgb * _EnvReflectionIntensity * _ReflectionIntensity, 0);
//Reflection
if (_ReflectionCount > 0) {
rayDirection = normalize(reflect(rayDirection, n));
rayOrigin = hitPosition + (rayDirection * 0.01);
hit = raymarching(rayOrigin, rayDirection, _maxDistance, _maxDistance*0.5, _ReflectionMaxIterations / 2, _ReflectionAccuracy, hitPosition);
if (hit) {
float3 n = getNormal(hitPosition);
float3 s = Shading(hitPosition,n);
result += fixed4(s * _ReflectionIntensity, 0);
if (_ReflectionCount > 1) {
rayDirection = normalize(reflect(rayDirection, n));
rayOrigin = hitPosition + (rayDirection * 0.01);
hit = raymarching(rayOrigin, rayDirection, _maxDistance, _maxDistance*0.25, _ReflectionMaxIterations / 4, _ReflectionAccuracy, hitPosition);
if (hit) {
float3 n = getNormal(hitPosition);
float3 s = Shading(hitPosition,n);
result += fixed4(s * _ReflectionIntensity * 0.5, 0);
}
}
}
}
#endif
} else {
// hit == false
result = fixed4(0,0,0,0);
}
return fixed4(col * (1.0 - result.w) + result.xyz * result.w,1.0);
}
}
uniform float4x4 _cubeMatrix;
uniform float3 _cubeScale;
uniform float4x4 _hexagonMatrix;
uniform float _hexagonWidth;
uniform float _hexagonHeight;
float Scene0 (float3 p) {
float res;
float3 cubMat = mul(_cubeMatrix, float4(p,1)).xyz;
float3 hexMat = mul(_hexagonMatrix, float4(p,1)).xyz;
hexMat = opTwistZ(hexMat, _cubeTwist);
float box = sdRoundBox(cubMat.xyz, _cubeScale, 0.2);
float bigHex = sdHexPrism(hexMat, float2(_hexagonHeight*1.4, _hexagonWidth));
box = opIS(box, bigHex, 0.2);
float hex = sdHexPrism(hexMat, float2(_hexagonHeight, _hexagonWidth));
res = opSS(hex, box, 0.2);
res = opU(sdSphere(cubMat, 1.0), res);
return res;
}
float SceneBunny (float3 p) {
float res;
float sphere = sdSphere(_SpherePos, _SphereRadius);
float bunny = GetBunnyPosSomehow(p, other_params);
res = opU(sphere, bunny);
return res;
}
float sdSphere (float3 p, float radius) {
return length(p) - radius;
}
float bunnyPose1 (float3 p) {
// Insert magic sampling code here
}
float bunnyFrame (float3 p, int frame) {
float res;
if (frame == 1) res = bunnyPose1(p);
else if (frame == 2) res = bunnyPose2(p);
else if (frame == 3) res = bunnyPos3(p);
return res;
}
float SceneBunny (float3 p) {
float res;
float sphere = sdSphere(_SpherePos, _SphereRadius);
float bunny = bunnyFrame(p, _BunnyFrameIndex);
// combining the sampled texture with a plain ol' SDF
res = opU(sphere, bunny);
return res;
}
// t : 0-1
float slerp (float d1, float d2, float t) {
//NOTE: For slerp to work properly, d1 and d2 need to overlap.
return (d1 * t) + (d2 * (1-t));
}
float sdSphere (float3 p, float radius) {
return length(p) - radius;
}
float bunnyPose1 (float3 p) {
// Insert magic sampling code here
}
//float bunnyPose2,3,4...
float bunnyFrame (float3 p, int frame) {
float res;
if (frame == 1) res = slerp(bunnyPose1(p), bunnyPose2(p), _BunnyAnimTween);
else if (frame == 2) res = slerp(bunnyPose2(p), bunnyPose3(p), _BunnyAnimTween);
else if (frame == 3) res = slerp(bunnyPos3(p), bunnyPose1(p), _BunnyAnimTween); // loop back to the start
return res;
}
float SceneBunny (float3 p) {
float res;
float sphere = sdSphere(_SpherePos, _SphereRadius);
float bunny = bunnyFrame(p, _BunnyFrameIndex);
// combining the sampled texture with a plain ol' SDF
res = opU(sphere, bunny);
return res;
}
struct v2f {
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 ray : TEXCOORD1;
};
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment