Chidume Nnamdi I'm a software engineer with 6+ years of experience. I've worked with different stacks ranging from WAMP, to MERN, to MEAN. My language of choice is JavaScript; frameworks are Angular and Nodejs.

How to use lighting and WebGLRenderer in Three.js

4 min read 1297

threejs-rendering-lighting

Three.js is a JS graphics library that is used for rendering 3D graphics in browsers. Major graphics organizations use Three.js for creating and rendering 3D scenes for movies, anime, advertisements, and games.

Three.js uses the WebGL engine in the browser for rendering scenes. The API is based on OpenGL (GL stands for graphics library), a desktop graphics API. In this post, we’ll look at types of lights and WebGLRenderer in Three.js.

Lights

First, let’s learn how to use lights in Three.js so we know the types of lighting that can be used and the effect each of them presents.

Three.js offers several different types of light. All lights in Three.js are instances of THREE.Light. They offer us illumination so that we can light up objects in a scene.

Not all material texture in objects in Three.js is affected by lighting. Only objects with MeshLambertMaterial and MeshPhongMaterial material texture can be affected by lighting.

Here are the type of lights available in Three.js:

Ambient

Ambient light is used for the illumination of objects in a scene. It does not point or direct light toward a direction, so it cannot cast shadows.

THREE.AmbientLight(color) 

The objects are illuminated by the color in the AmbientLight. Ambient light affects all lit objects in the scene equally, and is essentially a light that’s color is added to the color of an object’s material.

var cubeGeometry = new THREE.CubeGeometry(20, 20, 20);
var basicMaterial = new THREE.MeshLambertMaterial({
    color: 0x0095DD
});

var cubeMesh = new THREE.Mesh(cubeGeometry, basicMaterial);

var light = new THREE.AmbientLight(0x404040);
scene.add(light);

scene.add(cubeMesh)

For example, this illuminates the cube object with soft white light:

threejs-light-remderer

We made a custom demo for .
No really. Click here to check it out.

var light = new THREE.AmbientLight(0xf6e86d);

This code will illuminate the cube object with a green color.

threejs light renderer example

Directional

As the name suggests, directional light comes from a specific point and is emitted directly to the target.

This light can cast shadows, and the rays are all parallel and behave as though it is infinitely far away, just like the sun.

THREE.DirectionalLight(color, intensity = 1)

For this type of light, all light is parallel and comes from a given direction, as if the source was very far away.

For directional lights, the direction of the light is the direction from light.position to light.target.position; both are vectors that you can change, and the target defaults to the world’s origin.

This is the kind of light we get from the sun down to earth. We know the light source is far away, and the rays are in parallel.

Another example is a torch or lamp in a close hall with a wide range positioned at a far corner of the room. This will direct the rays of light in the hall, illuminating objects in the hall and casting shadows.

The color is the color of the light, and the intensity is how intense/bright the light would be. The default value is 1, which indicates the highest intensity.

var light = new THREE.DirectionalLight(0x404040, 0.5);
scene.add(light);

Hemisphere

Hemisphere light comes directly from above the scene to the ground. The light color fades gradually as it descends from top to the ground, and it does not cast shadows.

THREE.HemisphereLight(skyColor, groundColor, intensity = 1)

Notice that it simulates refractive lighting from the sun, sort of like two opposing directional lights.

The skyColor is the color from the starting point at the sky. The groundColor is the color of the light at the ground. intensity controls the brightness of the color.

var light = new THREE.HemisphereLight(0x404040, 0xFFFFFF, 0.5);
scene.add(light);

threejs light rendering
The light starts from the sky with soft white color and fades to normal light at the ground. See as the top of the cube is illuminated with the soft white color and its sides are in shades of normal light and soft white light.

Here’s another example:

var light = new THREE.HemisphereLight(0xf6e86d, 0x404040, 0.5);
scene.add(light);

threejs light rendering

The light color at the top starts with a greenish color of 0xf6e86d, which is why the top of the cube has a greenish tint. It then fades to the color of 0x404040.

Point

Point light is emitted from a single location and shines in all directions. Objects illuminated by this are the ones that are in its line of rays.

THREE.PointLight(color, intensity = 1, distance = 0)

Just like a lightbulb in a room, the light emanates from a point (i.e., a lightbulb) and spreads to all directions, but only illuminated objects within radius. Point light can cast shadows.

The color arc in the constructor is the color of the light to be emitted. The intensity is the strength of the light, and its default value is 1. distance is the distance the emitted light can travel or the maximum range of the light, the default value is 0, meaning there’s no limit.

Spot

The type of light from this forms a cone of light from a specific point to a specific direction. The cone light increases in size the further it gets from the source. Objects within the cone of light are illuminated, and it can cast shadows on the objects.

THREE.SpotLight(color, intensity, distance = 0, angle = Math.PI/2)

The color is the color of the light. intensity is the strength of the light. distance is how far the light will travel from its source. angle is the max angle of light dispersion from its direction.

WebGLRenderer

Three.js now only uses WebGLRRenderer to render 3D objects in our browser, and it uses the WebGL API of the browser to render objects and scenes. This requires browsers that support WebGL to show a scene. In general, most modern desktop browsers have good support for WebGL, but some mobile devices do not yet support WebGL.

WebGL is fast because it uses the client graphics processing unit to the work. The CPU of the client isn’t doing anything and isn’t part of the render. WebGL is highly performant because the CPU is spared while a dedicated GPU built for graphics rendering does the work.

To use THREE.WebGLRenderer, we first create an instance of it:

var renderer = new THREE.WebGLRenderer({
    antialias: true
});

The antialias option in the object param passed to the constructor that sets off a very powerful feature in Three.js. Antialiasing in Three.js smoothes out jagged edges in objects rendered in our scenes, making the objects in the scene look life-like.

Next, we can set the size of our rendering window by calling the setSize() method:

renderer.setSize(window.innerWidth, window.innerHeight);

The first param is the width of the rendering window. We’ll set it to take the width of the client’s browser. The second param is the height of the rendering window, and we set it to take the height of the client’s browser.

Next, we call the render method on the renderer in order to render our scene.

renderer.render(scene, camera);

A scene contains objects and lights. Here, the first param is the scene we want to render and the second param is the camera we will use to view our objects in the scene.

Finally, the renderer is appended to the page document.

document.body.appendChild(renderer.domElement);

The domElement prop in the renderer holds the DOM element that we append to the document’s body. This makes our scene visible in the browser.

Conclusion

We covered all the types of lighting available in Three.js, starting from horizontal to point lighting, with examples to show how they work. We also learned about WebGLRenderer in Three.js, showing how performant and useful it is.

Three.js is incredibly powerful and fast, so next time you want to build any graphics for your browser, you should consider using Three.js.

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    YesNo
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Are you adding new JS libraries to improve performance or build new features? What if they’re doing the opposite?

    There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.

    LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.

    https://logrocket.com/signup/

    LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.

    Build confidently — .

    Chidume Nnamdi I'm a software engineer with 6+ years of experience. I've worked with different stacks ranging from WAMP, to MERN, to MEAN. My language of choice is JavaScript; frameworks are Angular and Nodejs.

    Leave a Reply