And now... Shadows!
Shadows are one of the best parts of writing a ray-tracer (or ray-marcher, in this case). Raymarchers get perfect shadows at the cost of a couple of lines of code. Unfortunately, they really slow down the render.
To calculate shadows I calculate the impact point for a ray as usual, but before colouring it, I fire a ray from the impact point towards the sun. If the new ray hits the sun, I colour the pixel like normal. If the ray hits anything else, I don't colour the pixel.
If there was more than one light source, I would fire a ray towards each light source, then add the results to decide how brightly I should colour the pixel. I would only decline to colour it if I couldn't hit any of the lights.
When I got to the end of this one, I reviewed the code and discovered a large amount of commented code. Most of the comments were old versions that didn't work, and reading through them is a fascinating look at what I was thinking at the time. And a little bit scary.
Most of the commented out code was in the shading routine, and it shows that I clearly had no idea what I was doing. That's the joy of research!
Here are my initial attempts to implement shadows.
// intensity=intensity+1; <- what the...?
// intensity=intensity/2; <- why?
// intensity = intensity * 256; <- Could be useful, I guess
// intensity = 256-intensity; <- how would that make things look better?
// if ( intensity<50 ) { ret = rgb(50,50,50)}; <- I guess that's one way to stop shadows being too dark
My only explanation is that I usually do this late at night. Very late at night.