Looking for someone to help teach me lighting

I am new to Three.js and would like a knowledgable instructor to teach me lighting best practices. Some scenes I am trying to emulate are below.

Try this page,
https://sbcode.net/threejs/lights/
and the next pages after it discussing the ambient, directional, hemisphere, point, spot, and different types of shadows. The pages have working examples with guis.

Your example images look like the materials are using flatshading, and the light is directional (ie, not a point), with the directional shadow. The top image appears to be using the orthograhic perspective.
The objects may also be using the MeshToonMaterial with about 7 tones. https://sbcode.net/threejs/meshtoonmaterial/ although you could get that effect with most of the other materials.

The bottom image appears to be using a post processing shader of some sort for the blur. Perhaps its the depth of field shader used here. https://threejs.org/examples/?q=post#webgl_postprocessing_dof

2 Likes

Does anybody have any good resources for reading about lighting in 3D from an artistic perspective?

There are any number of resources describing how to use IBL/direct/ambient/light probes etc. from a purely technical standpoint.
But it’s much less common to find information on how to put it all together to create a beautiful scene.

3 Likes

I totally agree. I would love to see more resources on artistic usage of those.

As far as low poly goes, I wholeheartedly recommend this Wonderful Article. It has a big section on not only lighting, but also usage of post-processing to compliment it.

8 Likes

There is lots of material available for photography and i can highly recommend it. Don’t look for digital stuff, just a raw explanation of how light affects surfaces: hard light, soft light, light modifiers, big light sources, small light sources, position: front light, fill, strip light, etc.

If you know some Blender basics you can immediately put this into practice: https://www.youtube.com/watch?v=AO1wS1Yr0Wo

The simplest advice is: never put the main light in front or on top. It has to come from an angle to create shadow and thereby depth.

2 Likes

Thanks for all the resources. I actually come from blender and I feel pretty confident in my lighting skills there, I’m just having a tough time translating it into 3js code

If you are already confident in blender then I would do as much of the lighting as possible there. For example, a baked ambient occlusion map will get you 50% of the way towards your screenshots above. Along with a DirectionalLight and/or HemisphereLight it might be all you need.

You could also try baking shadows (for static objects in your scene) and maybe even an environment map, although that is less useful for non photorealistic scenes. You could also try baking a lightmap, although to be honest I don’t have much experience doing that - any experiments I’ve tried with lightmaps haven’t given great results.

Yeah, it’s been my thinking too. I’ve learned some good stuff that way.
I did at one point try setting up scenes using the front/back/fill standard studio setup, and it gives ok results. The thing is, the examples in the linked video are rendered offline using path-tracing which automatically gives you indirect lighting, ambient occlusion, and shadows, so it looks great.

For example, this simple shot in blender with just two lights:

00

Gives this amazing result:

There’s no way the same setup in three.js (or any real-time engine) would look that good. You need to at least add an ambient light and an ambient occlusion map to get something close to that.

1 Like

Nice, thank you. That really makes me think we have some progress to make in post processing with three.js.

I wish that there was a simple color pass we could add that does everything - tone mapping, gamma correction, color correction and grading, brightness and contrast. That seems to be the final step required to make things look amazing, and it should be much easier than it currently is to set this up with three.js.

That, and a baking workflow.

1 Like

My objects will be dynamic (like a game), so this wont work, right? Here is a basic blender object I am trying to render in three js.

Light setup (only one directional light)

Renderer settings and output

“BasicLights”

import { Group, DirectionalLight } from 'three'

export default class BasicLights extends Group {
	constructor(...args) {
		super(...args)

		const dir = new DirectionalLight(0xffffff, 2)

		dir.position.set(-40, 100, -40)
		dir.target.position.set(0, 0, 0)
		dir.castShadow = true

		this.add(dir)
	}
}

Loading the GLTF object

I am not sure how to get even a basic blender light setup to look remotely good in Three.js.

Try to use a lower intensity value like .5 or so.
Best is also to use the dat.GUI as helper for realtime value changes:

        import { GUI } from 'three/examples/jsm/libs/dat.gui.module.js';

        let gui = new GUI()
        gui.add( this.hemisphereLight, 'intensity', 0.0, 1 )
        gui.addFolder('Top')
        gui.add( this.topDownSpotLight, 'intensity', 0.0, 1 )
        gui.add( this.topDownSpotLight.position, 'x', -50, 50 )
        gui.add( this.topDownSpotLight.position, 'y', 0.0, 50 )
        gui.add( this.topDownSpotLight.position, 'z', -50, 50 )
        gui.add( this.topDownSpotLight.shadow, 'bias', -.001, .001 )
        gui.add( this.topDownSpotLight.shadow.camera, 'near', 0, 100 )
        gui.add( this.topDownSpotLight.shadow.camera, 'far', 0, 100 )

I think its even possible to export lights from blender? but dont know how good that works

2 Likes

You should set renderer.physicallyCorrectLights = true as well.

I think it would be great to have a single example that features:

  • Color Correction Shader Pass
  • Brightness / Contrast Shader Pass
  • Hue / Saturation Shader Pass
  • Vignette Shader Pass
  • Colorify Shader Pass ( optional ? )
  • Color Encoding/Gamma Correction Shader Pass ( optional ? )
  • Tone Mapping Shader Pass ( optional ? )

and importantly, provides datGUI sliders for each effect. As of now, the only example to use Color Adjustments is Node Materials, which isn’t very clear to understand in that regard.

I don’t think any of those require depth, so maybe we wouldn’t even need to build a scene, and just provide some image texture for the background.
Perhaps it would also have the benefit of showcasing an example of image processing using Three, and as you were saying, could provide a basis for the “Complete Color Pass” that does all color related stuff in one.

.

Also side note, personally I’d like to see a Bloom Pass example, that isn’t just about glowing objects, but rather an environmental feature, used in a similar fashion to this or that. Might try to get around for that in the nearest future

2 Likes

This is the right approach in my opinion. This would be called a color grading pass, similar (although simpler) to how Unity and Unreal do it.

1 Like

@looeee check out the lighting series by Blender Guru, he also mentions some books

3 Likes

nah, these are just two strip lights, one a bit hotter than the other, with a fill. :slight_smile: sure, three doesn’t have these neat reflections, but you still can do some damage.

livedemo: Performance scaling - CodeSandbox

5 Likes

Thanks everyone for their help, I’m taking everyone’s advice but still not getting there.

The ground plane is closer to the true color it should be but the plants seem to lighten at a different rate than the ground:

At a high intensity for the lights we can see the plants; however

  1. The colors are still off (renderer.physicallyCorrectLights is set and the gammaFactor is 2.2)
  2. The ground becomes washed out

The ground is a “MeshLambertMaterial” and the plant materials are defined in blender and imported using GLTF

That’s pretty odd for the lighting to be so inconsistent. Does using a per-pixel-shading material (for example Phong) for the ground help? Perhaps try exporting an additional object, to see if its the blender models, or the floor that is incorrectly lit.

Also I believe since r115 it is recommended to use renderer.outputEncoding = sRGBEncoding instead of gamma. That’s the way the official GLTF example is setup.

Nice! That’s much better than I expected :heart_eyes:

Although it has to be pointed out, RectAreaLights are really slow. I’d like to see how that works out for a scene with animation that has to run on mobile devices.

The phong helped! I set the sRGBEncoding but I’m still getting these pretty harsh colors that aren’t similar to my blender file.