I've been messing around with ray-marched geometry for a game engine and recently messed around with a fully ray-driven lighting system. At one stage I had a very nice system that accurately traced rays back to their source and created a moon-like directly illuminated sphere, but I overwrote that code with a "better" ray-marched version (original was ray-traced) that wasn't and now I'm seeing alternating discs of shadowed and unshadowed surfaces. I know from the tutorial here that my lighting algorithm is borked, but I'd still be interested to know how.
Here's my lighting code (float3s are vectors):
float3 lightPos = float3(5.0f, 0.0f, 0.0f);
float3 rayDir = normalize(lightPos - samplePoint);
float currRayDist = 0.00001f;
float3 outputColor = sampleRGB;
for (int i = 0; i < MAX_MARCHER_STEPS; i += 1)
{
float3 reflectVec = samplePoint + (rayDir * currRayDist);
float distToScene = SceneSDF(reflectVec);
float invSquare = (10 / (4 * 3.14159 * (currRayDist * currRayDist)));
if (distToScene < rayEpsilon)
{
// We hit geometry, so this point must be in shadow;
// darken it appropriately
outputColor = sampleRGB * (1 / invSquare);
break;
}
float distToLight = SphereSDF((rayDir * currRayDist), 2.0f, lightPos);
if (distToLight < rayEpsilon)
{
// The ray successfully made it's way back to the light source, so use the
// inverse square law to update the output color :)
outputColor = sampleRGB * invSquare;
break;
}
currRayDist += distToLight;
}
And here's a low-res image of the artifacts: