What's the fastest way to use stencil shadows in modern three.js?

There used to be a ShadowVolume. Is there a replacement now? Is there any open-source solution if not in the core three.js?

Are you referring to this example? https://threejs.org/examples/webgl_shadowmesh

Related issue at github:

I’m looking for the modern version of this:

https://cs.calvin.edu/courses/cs/352/files/three.js/mrdoob-three.js-25dddd2/examples/webgl_stencil.html

ShadowMeshes just work with a planar shadow, but I’m looking for volumetric stencil shadows. Note how in the demo above the shadows of the torus on the cube and vice versa.

It used to be called a “ShadowVolume”, but it looks to have been deprecated some versions ago. Looking for the modern equivalent?

I couldn’t find an example so I built one.

For anyone in need in the future:

4 Likes

Here’s a live version of you demo :slight_smile:

I put together a small little shadow volume experiment awhile ago that does shader based geometry projection:

https://github.com/gkjohnson/threejs-sandbox/tree/master/shadow-volumes

And the demo:

https://gkjohnson.github.io/threejs-sandbox/shadow-volumes/index.html

The geometry is modified to create bridge polygons between all connected triangles and extended based on face normal in the vertex shader. I’m sure it’s entirely impractical especially with complex geometry but maybe it’s worth sharing anyway.

I’m curious as to what your use case for shadow volumes is! I haven’t seen them used in awhile.

3 Likes

Currently 3D platformer game shadows that run nicely on mobile.

Do you per chance know how this works? Looking at the code, I cant understand how just the matrix is enough to make the volume.

Wait, are they just projecting on the plane there???

@dyarosla damn, that is cheating, too - you just use another mesh here, right?

I was looking for someone who did something like this (output).

My code is just for the stencil shadow itself; if you want to generate it for an arbitrary mesh you’d do that separately and use that generated mesh as the input. Either way you are going to be using a second mesh, either static (like my example) or dynamically generated to use if you’re going to use stencil shadows.

That’s exactly what I’m doing in the example I posted above:

image

Which looks like a similar / the same approach used in the old ShadowVolume.js file that used to be in three.js. It would be possible to update in javascript but would probably only be performance with dynamic lights on simple meshes.

@gkjohnson I get 12 fps on torus and 1 fps on dancer, I assumed that was javascript -based volume.

I explained above that it’s shader based. I haven’t done anything to make sure that it runs well on mobile but I get 60fps for torus on my phone and 30-45 for dancer. The shaders being used are the standard shaders which are expensive and resizing the window to be smaller on my integrated graphics laptop gives significant performance improvements, which seems like a pixel fill issue. Each shadow adds 4 passes which is a lot of overdraw and could lead to that. There are “separate” functions that let you set the stencil operations for front and back pixels separately and would take the draw call count down to 2 but they are not supported in three.js.