How to get photorrealism (light + shadows) in three js

Hello everyone,

I was trying to reach photorealism in my three js environment as in the following picture that I found on internet.

As far as I know, this is made using lightmap, how I can use this technique in my scene in order to reach similar shadow effects? Should be dynamic, cause my application is interactive.

Is there an alternative to lightmapping in three js that can give me similar results?

By other hand, I want to have realistic reflections in some sub objects of my models (for example, the following ceramic)

Which is the best way to do this in three js? I found that I can create a material from a CubeCamera like in the following examples provided by three js:

But that implies that these materials must be applied to each sub-object of all the objects in the scene that should have reflections. Is there a better way to do It?

Thank you for your time!

Yep, tons of tricks and years of work :’) The point is that there’s more to light than just light - what makes scene look realistic is the light that bounces of the objects, not the one that comes from a light source.

To create actual photorealistic shadows - take a look at progressive shadows. It does take a few seconds to generate, but the effect is similar to the one you’d get from raytracing.

To create realistic light - you’ll need some kind of global illumination approximation.

i collected some here: Performant soft shadows THREE Js - #2 by drcmda

there is about no chance you will get a scene like that without baking, threejs isn’t a raytracer and the existing runtime solutions are either painful to use or very expensive, or both.

baking unfortunately comes with some limitations (you can’t move objects around much). baking is very complex, one of the few tutorials that’s really going into detail is bruno simons threejs journey. in that course he’s baking scenes, and at the same time introduces dynamic elements to it, which might be what you’re looking for.

Thanks both of you for the replies guys,

I think that for the shadows+lights it is going to be hard to apply the lights dynamically and see the effect of the shadow in real time with a good efficiency.

But for the reflections

Which way do you think I should take?

Thank you!

Reflections are easy and look stunning, you need PBR materials + environment map.

1 Like

One thing you didn’t research (and I also haven’t experimented with much) is lightprobes and lightprobe volumes, which should be more useful for moving objects.

Sounds super interesting, do you know an example for this?

Light Probe volume maybe no bug
With bug
With bug

1 Like

Yeah, I only know the examples @Chaser_Code shared, aside from the couple of official examples that are not very interesting.

There was some cool work done on this around 2019 when the functionality was added to three.js - but there was never any good documentation or killer examples so I don’t think many people know about it, or how to use it, outside of the 3 or 4 people involved in writing the code. I don’t even know if it’s production ready or if the implementation was completed yet.

right, i have no idea what this is or does, never heard of it but would love to try it. from how it looks these spheres are just in debug, and they … pre-calc emission or something so that it’s not so expensive? but can it do shadows?

ive dug out a quick test case with reflections and simple shapes: Camera pan - CodeSandbox would it be possible with a lightprobe for these objects to pick up one anothers colors? like the sphere in the middle would be a little yellow on the side due to the plane on the right etc? and does anyone know how? that would be an amazing tool to have.

You need this: three.js webgl - light probe from cubeCamera
Its generate colors by screening 6 ways like envmap.

1 Like

That’s the idea. Especially if you can bake the lightprobes offline (much cheaper than CubeCamera online) you can pick up diffuse colors from surrounding (static) objects. Once you have a volume there are basically two ways to apply that light to the object:

  • (A) on the CPU, interpolate SH values for the center of the object from the nearest ~4 probes
  • (B) on the GPU, interpolate SH values at each vertex or fragment

In this demo you’re seeing (A), it works well for small dynamic objects and is very cheap. For larger objects (B) would look better as there’s more lighting variation across the object.

I’ve been asking for Blender to expose a Python API for baked light probe irradiance (it bakes that data already, but doesn’t have an API to access it) at Access baked lightprobe / irradiance volume data from Python? - Python API - Blender Developer Talk.


i’ve been trying to implement it from your demo, but these classes don’t seem to exist in threejs, for instance lightprobevolume. when i tried to port they’ve unfortunately fallen behind, they were not easily compatible with class based threejs. is this from an unresolved pr?

The PR is LightProbeVolume: Baked lighting for dynamic objects by donmccurdy · Pull Request #18371 · mrdoob/three.js · GitHub

oh wow, thank you @donmccurdy and @looeee for the pointers. i also never got what lightprobes in blender are for but now it makes sense.