I saw an Airbnb ad the other day and was simply fascinated by it. Not by the ad itself, but much more by the animated content … the model, the scene, the lights, the shadows.
Just see for yourself what I mean:
I think you get my point. The trick seems to be that the model is lit brightly enough, but the shadow is only very light.
I know that you can create the models, figures, the scene, the animation and the lights excellently with shadows in Blender. But I wonder if and how this can be realized in Three.js. Suppose I had the models of a house or room like in the advertisement, what and how would I have to add in Three.js (e.g. type of lights) so that the scene looks similar to the one in the advertisement (like the shadows, etc.)
I was thinking of different post processing like SSAA and SSAO and also looked at the two examples from three.js:
If this is not realtime, you can spend days if needed to compute all these light bounces, reflections, soft shadows etc. If it is realtime, you can “bake” these effects. Once the lighting is computed you can put it into a texture.
If you are looking at how to balance key and fill lights with GI, you could perhaps look into “linear workflow for GI”.
For example, vray has some images here:
I know that you can create the models, figures, the scene, the animation and the lights excellently with shadows in Blender. But I wonder if and how this can be realized in Three.js.
It would actually be really hard to create a figure of a human in three.js. Perhaps an abstract stick figure or something made out of ellipsoids, but anything beyond that would be very hard.
Not impossible, thats how they did a Kraftwerk video back in the 70s, but why? Why not use blender?
Even then, it wasn’t just someone coding a bunch of numbers off the top of their head:
Sorry if I didn’t make myself clear. I didn’t mean the figures, but actually just the soft shadows, e.g. as you can see here:
I can’t render the entire scene with Blender because the scene is constantly growing. You can imagine it like a city where new buildings are constantly being added.
Those type of effects are very costly, the best you can do is approximate them. If it’s a city you could have some kind of a module that has its own shadows. I think you should do a bit of research into “baking” (as in “bake textures”) and “light maps”
Thank you mjurczyk for the hint.That looks really good! I don’t know how I could have overlooked this example. I’m happy with that.
I just have one question: can I only use the ContactShadow for the floor, or does it also apply to the models themselves, e.g. a corner or an inner edge?
Only on the floor - since they are not actual shadows. It’s a trick that uses intersection between a ground plane and models to simulate ambient-indirect-kind-of-shadow. These shadows appear only on the said plane, not interacting with anything else in the scene.
contact shadows will not give you what you are after imo. cs are not cast shadows but “halos” underneath an object, it looks good for simple objects on simple surfaces. with a complex scene you’ll just end up with a giant grey halo underneath. what you want are soft shadows.
all of this is trivial in react + three because it has been abstracted into components. in vanilla it often looks bleak, you won’t normally find things like that because they are made with considerable effort and cannot be easily cast into re-usables.
Can you elaborate on this a little bit? Are these two some of the few that can easily be cast into re-usables? Perhaps they just can be cast, but not easily? Are these two special in any way when compared to the rest?
I’m trying to wrap my head around this and all my conclusions seem to end at useContext. Just glancing at this accumulative shadow implementation, i see that it requires the renderer and a camera from which it’s being drawn, which seems to be much easier to organize with three fiber.
there was a thread here about vanilla-drei/accshadow, they were getting is a black square. but they figured it out in the end.
this is essentially a class/oop problem. classes are not re-usable because they either need the outside world to submit to their whims, or the outside world needs to be injected. this is what prompted the erlang creator joe armstrong to state:
The problem with OOP is the implicit environment it carries around. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle
that’s why three.js examples are all apps, not re-usables. accshadow was based on one of them but this is an intricate, wired-together application-show-case, which has to be untangled and slowly adapted to ones needs.
you can drop in <AccumulativeShadows> in your react + threejs app because that component has full awareness of the system. all the complicated code has been made self-contained.