Progressive shadow as Floor Shadow Catcher

So react three fiber has turned the progressive shadow example into an excellent shadow catcher

Faucets, select highlight - CodeSandbox
Baking soft shadows - CodeSandbox

Was wondering how i would go about doing the same in three js ? or is this even a valid application ?
and is there any docs available for this class ?

the scene contents will be:

  • a ground plane which receives shadow and acts as the target for progressive lightmap
  • a Gltf model which uses meshStandardMaterial for everything , it will cast shadows but not receive them
  • hdri for environment
  • array of directional light on top of everything spread around to cast ambient occlusion like shadows

update: after turning down the scale and position of the light jitter, the shadows seems more polished

@zalo hi !

using ‘addObjectsToLightMap’ i’m adding the lights , floor and the meshes in the ProgressiveLightMap instance

i don’t want the meshes to participate in receiving shadows , disabling
castShadow & receiveShadow has no effect

any suggestions on achieving this ?

maybe this helps,

this was the topic i opened about it: How can i "bake" a shadow onto a planeGeometry? very informative tips by @gkjohnson that helped a lot

and the new lightmap class, drei/AccumulativeShadows.tsx at 9baf3d86168f14d0a3a4754a037dc5ced00d7fe3 · pmndrs/drei · GitHub

  • removed potpack
  • removed uv2, changed shader into diffuse
  • new uvmat shader discards all pixels
  • removed attach logic, it takes a plane mesh and the regular scene
  • will finally “bake” results when frames run out

it has new methods:

  • clear() clears buffers and collects lights and meshes
  • configure(object) set the plane
  • prepare() sets all lights to 0, all meshes to a new uvmat
  • finish() sets back all lights and meshes to normal

you use it like this:

  • configure(yourPlane) once
  • clear() once the scene has loaded fully

now the loop:

// Switch rando lights on
lights.visible = true
// Shut down all scene lights, all meshes get discard-uv-mat
plm.prepare()

// Jiggle rando lights
lights.children.forEach((light) => light.update())
// Let the LM render
plm.update(camera, 100)

// Switch lights off
lights.visible = false
// Restore scene
plm.finish()
1 Like

i am trying to picture how this could be cast into a vanilla thing but honestly i don’t know … oop doesn’t seem to lend to something like that, where you need interop between so many things. the original LM example, due to all the assumptions it has to make about the scene, lights, etc, was more like an application that you shape into your needs. i would suggest to just use react + three, this is one component out of hundreds that make your live easier, and hundreds more will follow. a component makes sharing naturally easy, hence it grows into an eco system, a class based approach will just never have that. :confused:

1 Like

converting this to class is out of my scope right now , can’t switch to react , will come back to this another day , big thanks !

hope @zalo can figure out an simpler alternative in the future since the potential of this as a shadow catcher is immense

but honestly i don’t know … oop doesn’t seem to lend to something like that … a component makes sharing naturally easy, hence it grows into an eco system, a class based approach will just never have that. :confused:

Three-gpu-pathtracer uses classes to define a similar kind of behavior. And at some point I hope we’ll get lightmap and ao map baking into the project, as well, which is just the path-traced version of this work. You may not be as in love with the OOP patterns for implementing something like but it’s very doable and very usable.

And in terms of share-ability I strongly disagree. Classes are just as easily shared and reused across projects and are arguably more shareable since vanilla (or three.js-only) don’t require users to buy into react in order to use or contribute to them. React implementations can always be made on top of vanilla implementations - the opposite direction is not as simple in my experience.

3 Likes

your library, threejs, the dom, are perfect examples of where classes are useful. but this is not what i am referring to. the lack of re-usability has been discussed since the 80s.

I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. ~ Joe Armstrong

what he alludes to is that a class has no lifecycle, no awareness of its surroundings, it can’t react to anything outside of its own scope and is therefore beholden to injection (the jungle). it has to make heavy handed assumptions that would have the environment conform to its own requirements. a component is the opposite of that. it has a common ground that allows interop between parts that do not know one another, this is what creates eco systems.

a matter of opinions, not so important right now. :slightly_smiling_face:

1 Like

There’s no doubt that good classes can be more complex to write and can easily hide interconnected environment spaghetti dependencies. Those kind of dependencies can be required in functional architectures, as well, but it’s definitely more generally frowned upon there. That’s all to say its easy to write bad code anywhere but it’s true something like a component or functional architecture can more easily promote good practices.

I’m only suggesting here that the effort to make a good architecture with vanilla here is worth it since it opens up the user and contributor base and to say it’s not possible or that OOP intrinsically runs counter to reusable architectures feels disingenuous. This is project might be something I’d be interested in using but given the way I choose to write my code I cannot and I’d be more likely to write my own competing solution instead of improving the one that everyone can benefit from. I see the value and desirability of the component architecture and understand why people use it but to me React is “the entire jungle” here.

1 Like

i am looking at the threejs/jsm example in question, or most jsm examples for that matter, and what i see are classes that make the environment conform to their needs and hence a whole “jungle” has to be built around them. jsm is not something you just use but untangle and adapt to your needs.

can some classes be better, yes, should certain things be classes, most certainly, should complex things that need awareness be turned into classes … maybe :man_shrugging:

if i can help with the shadow catcher, turning it into something more generic, gladly. otherwise, always enjoy to discuss with you!

Yes I agree that some of the three.js examples are not always all that elegant :sweat_smile: But I think this still speaks to the history of them which has classically been legitimate examples vs designed, reusable code. And I agree that making streamlined patterns for classes is more difficult because they’re more open and don’t impose any existing patterns. My only suggestion is that I think it’s worth the effort if only for a more expansive userbase. It’s one of the reasons I try to use as few dependencies as possible in my projects. But as you mention these are just differing perspectives and opinions!

otherwise, always enjoy to discuss with you!

Likewise! :grin:

3 Likes