Skip main navigation
We use cookies to give you a better experience, if that’s ok you can close this message and carry on browsing. For more info read our cookies policy.
We use cookies to give you a better experience. Carry on browsing if you're happy with this, or read our cookies policy for more information.

Skip to 0 minutes and 19 secondsSo, in the previous lesson, we loaded in a mesh from a Wavefront.obj file, and now we’re gonna load in the texture. .obj files do come with materials, and you can load in the texture directly from the material, but we're gonna do it the manual way because not all file formats come with materials associated and, in fact, not all .obj files come with associated materials, that’s an optional thing. So we’re gonna load in all the different materials as separate images, see how that works, and we’re just gonna mess around a little bit with shadows as well so you can see how the resolution of the shadow map can affect the quality of the final render.

Skip to 1 minute and 2 secondsOk, so, in the last lesson we loaded in an object. Now, we’re gonna modify the simple material we had up here, make it a little bit more complicated. So what we’re gonna do, what we’ve done several times before is, we’re going to make a texture.

Skip to 1 minute and 25 secondsAnd we’re going to create

Skip to 1 minute and 33 secondsan “ImageLoader", as we've done before,

Skip to 1 minute and 38 secondsand we're gonna load in, oops, not sure what's that, an "ImageLoader", and we’re gonna load in some textures. The first texture that we’re going to load in is the defused texture, the colour texture. So that’s stored in my assets folder.

Skip to 1 minute and 56 secondsAll these textures are available to download on the course website. This is code that by now we should be fairly comfortable writing. You’ve written it several times now. We’re going to set the image. Should be the image that’s been just downloaded, and we’re gonna inform the scene graph that this will need updating. “needsUpdate = true”. So now we have our defused texture. We’re also going to load in a normal texture to give our face a little bit more depth. I’m gonna copy and paste and see if we can, “normalTexture”,

Skip to 2 minutes and 44 secondsand that is going to be

Skip to 2 minutes and 49 seconds“lee_normal_tangent”, tangent space normals. And we’re just gonna update this texture. When we create the material, now we’ve. Previously, we’ve created the material and then assigned the textures later on, we said “material.Map = “ so-and-so, “material.normalMap = “ whatever. Here we’re gonna do all in the javascript object we passed the material when we started up. So we’re just gonna have more properties here,

Skip to 3 minutes and 20 secondsmap of the texture we’ve just made, this one here at the top the "normalMap" is the "normalTexture"

Skip to 3 minutes and 32 secondsand the "normalScale", if you recall from the last module, the "normalScale" was the influence how much of the "normalMap" we apply. We’re just gonna create a new "Vector2", and we’re just gonna make it slightly less strong than it was before. Ok? Now the material is set, so if we check that, hm there’s an error, let’s see where it is, in line 66, ah yes of course, we don’t put semicolons in our object definitions. And there now we have our scene, as you can see, the "normalMap" is loaded as well, so our face is now looking a little bit more realistic.

Skip to 4 minutes and 13 secondsWhat we’re gonna do though, you could add a specular map here as well, we’re not gonna add a specular map cause it’s the same code just repeated loading in this texture. What we’re gonna do is control the shadow map a little bit. If you’ve noticed, this mesh is currently, the light is coming from up here to the character’s left, and in front of him obviously, but his nose is not casting any shadows, there’s no shadows being cast. It may look like the shadows, that’s just because the light is not hitting the face of this mesh here and there are no shadows being cast.

Skip to 4 minutes and 47 secondsSo what we need to do, if you recall, we need to explicitly state that this mesh is capable of both casting and receiving shadows because, in the previous module or in module 3, I think it was, we casted shadows and on to a plane from a sphere, and we set the sphere could cast a shadow and the plane could receive a shadow, whereas here we’re going to say that this mesh that we’ve loaded can both receive a shadow

Skip to 5 minutes and 22 secondsand also that it can cast a shadow.

Skip to 5 minutes and 29 secondsOk? So, if we refresh that now,

Skip to 5 minutes and 35 secondswe see there are shadows in our application. But, to be honest, they look rather ugly, that really looks horrible, and that’s because of the shadow map size, the light here is at a very oblique angle and it’s casting a very narrow shadow here and it looks really rubbish, and that’s because of the low resolution of the shadow map. So, what we can do is, when we create our spotLight, we can actually increase the resolution of the shadow map to reduce this horrible pixelation effect that we have here. So, here in spotLight we’re going to say

Skip to 6 minutes and 15 seconds"spotLight.shadowMapWidth”,

Skip to 6 minutes and 22 secondsand you can start with “1024”.

Skip to 6 minutes and 31 secondsUsing a pair of two textures, the “shadowMapWidth” and the “shadowMapHeight" are the same, the pair of two is a square texture, and you can see the effect is now a little bit better but still a bit pixelated, so why not ramp it up again to “2048". Obviously, the higher you do this, the more your memory usage will be, but I think for one mesh, we can get away with it. And now, our nose and our eyelids are casting shadows and that pixelated effect is going. You can activate some more advanced shadowing algorithms which do affect your rendering, but for now I think we’ve come up with a reasonably nice rendering of our face.

Loading textures and casting shadows

At this point, you should have loaded a complex mesh into your scene. In Alun’s example, we have a model of a human head.

In this step you will learn how to add complex textures to your 3D scene and program higher-quality shadows.

Remember that in Week 3 we learned that the scene looks more realistic when an object can both cast and receive shadows. The same applies to your mesh in this scene.

To improve the resolution of your shadow map, you can alter the width and height settings.

Share this video:

This video is from the free online course:

3D Graphics for Web Developers

Pompeu Fabra University Barcelona

Get a taste of this course

Find out what this course is like by previewing some of the course steps before you join:

  • Getting to know WebGL studio
    Getting to know WebGL studio
    video

    State-of-the-art tool for 3D graphics development, WebGLStudio. Watch Javi Agenjo explains basics of 3D graphics using WebGLStudio.

  • Learn 3D scene post-production
    Learn 3D scene post-production
    video

    Apply more effects, algorithms to have more realistic scene and learn about post-production. Watch Javi Agenjo explains more.

  • Implementing a basic 3D scene
    Implementing a basic 3D scene
    video

    Learn how Three.js API can be used to create 3D graphic scenes. Explore more about Three.js after watching Alun Evan's video lesson.

  • Creating complex 3D objects
    Creating complex 3D objects
    video

    Learn how to create complex 3D objects instead of simple spheres and planes. It uses external resources also. Watch Alun Evans explains more.

Contact FutureLearn for Support