[HN Gopher] Ray Marching Soft Shadows in 2D (2020)
       ___________________________________________________________________
        
       Ray Marching Soft Shadows in 2D (2020)
        
       Author : memalign
       Score  : 168 points
       Date   : 2025-11-27 07:31 UTC (15 hours ago)
        
 (HTM) web link (www.rykap.com)
 (TXT) w3m dump (www.rykap.com)
        
       | ravetcofx wrote:
       | It's always impressive to see a live demo in a technical blog
       | post like this, especially one that runs so fast and slick on
       | mobile. Kudos.
        
         | keyle wrote:
         | In relative terms your mobile is a superb computer compared to
         | 20 years ago; and it's a small resolution.
        
           | forrestthewoods wrote:
           | > small resolution
           | 
           | My iPhone is 1320 x 2868. That's more than 1080p. So I would
           | not consider it a "small resolution"!
        
         | speedgoose wrote:
         | The iPhone 17 pro is faster in quite a few benchmarks compared
         | to the standard HP Intel notebook my company provides if you
         | prefer windows over MacOs.
        
       | cubefox wrote:
       | This sounds similar to radiance cascades:
       | 
       | https://mini.gmshaders.com/p/radiance-cascades
       | 
       | https://youtube.com/watch?v=3so7xdZHKxw
        
         | s-macke wrote:
         | While the methods are similar in that they both ray-march
         | through the scene to compute per-pixel fluence, the algorithm
         | presented in the blog post scales linearly with the number of
         | light sources, whereas Radiance Cascades can handle an
         | arbitrary distribution of light sources with constant time by
         | benefiting from geometric properties of lighting. Radiance
         | Cascades are also not limited to SDFs for smooth shadows.
        
           | cubefox wrote:
           | Yeah, and I believe Radiance Cascades accurately calculate
           | the size of the penumbra from the size and distance of the
           | area light, which also means that point light sources, as in
           | reality, always produce hard shadows.
           | 
           | The technique here seems to rely more on eyeballing a
           | plausible penumbra without explicitly considering a size of
           | the light source, though I don't quite understand the core
           | intuition.
        
       | flobosg wrote:
       | Probably not that related, but the article reminded me of a
       | shadow casting implementation on the PICO-8:
       | https://medium.com/hackernoon/lighting-by-hand-4-into-the-sh...
        
       | opminion wrote:
       | Note that the first image is an interactive demo. Click or touch
       | it. (It's not obvious from the text at the time of writing)
        
         | QuantumNomad_ wrote:
         | Same goes for a few of the other images too, but not all of
         | them.
         | 
         | The article would probably benefit from having figure captions
         | below each image stating whether the image is interactive or
         | not.
         | 
         | Or alternatively to figure captions about interactivity,
         | showing some kind of symbol in one of the corners of each of
         | the ones that are interactive. In that case, the intro should
         | also mention that symbol and what it means before any images
         | that have that symbol on it.
        
         | esperent wrote:
         | The demo at the top has some bad noise issues when the light is
         | in small gaps, at least on my phone (which I don't think the
         | article acknowledges).
         | 
         | The demo at the end has bad banding issues (which the article
         | does acknowledge).
         | 
         | It seems like a cheat-ish improvement to both of these would be
         | a blur applied at the end.
        
           | kg wrote:
           | AFAIK (I have a similar soft shadows system based on SDFs)
           | the reason the noise issues occur in small gaps is that the
           | distance values become small there so the steps become small
           | and you start ending up in artifact land. The workaround for
           | this is to enforce a minimum step size of perhaps 0.5 - 2.0
           | pixels (depending on the quality of your SDF) so you don't
           | get trapped like that - the author probably knows but it's
           | not done by their sample code.
           | 
           | Small step sizes are doubly bad because low-spec shader
           | models like WebGL and D3D9 have a limitation on the number of
           | loop iterations, so no matter how powerful your GPU is the
           | step loop will terminate somewhat early and produce results
           | that don't resemble the ground truth.
        
           | magicalist wrote:
           | > _The demo at the top has some bad noise issues when the
           | light is in small gaps, at least on my phone (which I don 't
           | think the article acknowledges)._
           | 
           | Right at the end:
           | 
           | > _The random jitter ensures that pixels next to each other
           | don't end up in the same band. This makes the result a little
           | grainy which isn't great. But I think looks better than
           | banding... This is an aspect of the demo that I'm still not
           | satisfied with, so if you have ideas for how to improve it
           | please tell me!_
        
             | esperent wrote:
             | Ah I missed that, thanks. More than a little grainy for me
             | but that might be a resolution/pixel ratio thing on my
             | phone that could be tweaked out.
        
               | black_knight wrote:
               | Not only. There is an inherent aliasing effect with this
               | method which is very apparent when the light is close to
               | the wall.
               | 
               | I implemented a similar algorithm myself, and had the
               | same issue. I did find a solution without that particular
               | aliasing, but with its own tradeoffs. So, I guess I
               | should write it up some time as a blog post.
        
           | wongarsu wrote:
           | However I don't have any issues with the demo in the middle
           | (the hard shadows). So the artifacting has to be from the
           | soft shadow rules, or from the "few extra tweaks".
           | 
           | The primary force behind real soft shadows is obviously that
           | real lights are not point sources. I wonder how much worse
           | the performance would be if instead of the first two (kinda
           | hacky) soft shadow rules we instead replaced the light by
           | maybe five lights that represent random points in a small
           | circular light source. Maybe you'd get too much banding
           | unless you used a much higher number of light sources, but at
           | the very least it would be an interesting comparison to
           | justify using the approximation
        
       | noduerme wrote:
       | This is truly a very clever series of calculations, a really cool
       | effect, and a great explanation of what went into it. I'll admit
       | that I skimmed over some of the technical details because I want
       | to try it myself from scratch... but the distance map is a great
       | clue.
        
       | IsTom wrote:
       | I wonder if it would help if you looked at gradient of the SDF as
       | well - maybe you could walk further safely if you're not moving
       | in the same direction as the gradient?
        
         | dahart wrote:
         | I've seen a paper about this, I'll see if I can dig up a link.
         | I believe you're right and the answer is yes it can help, but
         | it can be complicated to prove what's safe or not. The gradient
         | tells you about the orientation of the nearest surface, but
         | doesn't tell you how fast the orientation is changing, so for
         | nonlinear shapes you need to look at higher order derivatives
         | too. Super interesting stuff, but somewhat gets in the way of
         | the pure elegant simplicity of basic ray marching.
         | 
         | edit: here's one. I'm not sure this is the one I was thinking
         | of, but I think it does validate your hypothesis that you can
         | reduce the number of steps needed by looking at gradients.
         | https://hal.science/hal-02507361/file/lipschitz-author-versi...
        
           | IsTom wrote:
           | That's a pretty cool paper, though it does get more elaborate
           | as you're saying. In 20/20 hindsight lipschitz bounds do make
           | sense.
        
       | ionwake wrote:
       | this looks great but is there no demo link? maybe Im blind and
       | missed it?
        
         | sigmoid10 wrote:
         | They are embedded in the blog. Just click around on the images.
        
           | ionwake wrote:
           | oops - thanks
        
       | rncode wrote:
       | the fact that this runs butter-smooth on webgl while my company's
       | 'enterprise dashboard' struggles to render 50 divs says
       | everything about how much performance we leave on the table with
       | bad abstractions
        
       | aktuel wrote:
       | This is really cool! If I were to work on it, I would make the
       | light source a bouncing ball or something similar (maybe even a
       | fish or a bird) via some 2D physics next.
        
       | IvanK_net wrote:
       | It reminded me this demo that I made in 2012 (computed in real
       | time by Javascript on the CPU)
       | https://polyk.ivank.net/?p=demos&d=raycast
        
       | jasonjmcghee wrote:
       | None of the demos worked for me on mobile but he has a pinned
       | tweet that demonstrates it
       | 
       | https://x.com/ryanjkaplan/status/1308818844048330757?s=46
        
       | dahart wrote:
       | Great looking demo. Someone could use this for a show's title
       | sequence. There's something about the combination of soft shadows
       | and r-squared light falloff that always tickles me.
       | 
       | Fun fact - you can use very similar logic to do a single-sample
       | depth of field and/or antialiasing. The core idea, that maybe
       | this blog post doesn't quite explain, is that you're tracing a
       | thin cone, and not just a ray. You can track the distance to
       | anything the ray grazes, assume it's an edge that partially
       | covers your cone (think of dividing a circle into two parts with
       | an arbitrary straight line and keeping whichever part contains
       | the center), and that gives you a way to compute both soft
       | shadows and partial pixel or circle-of-confusion coverage. You
       | can do a lot of really cool effects with such a simple trick!
       | 
       | I searched briefly and found another nice blog post and demo
       | about this: https://blog.42yeah.is/rendering/2023/02/25/dof.html
        
       ___________________________________________________________________
       (page generated 2025-11-27 23:00 UTC)