Category Archives: Tutorial

Tutorial Articles

Nolimits 2 Shaders: Specular Mapping

Specular Maps & Reflection

Before you start this tutorial, I’d recommend taking a look at my first tutorial on specularity. (Blog) Note that since writing that, the NL2MAT editor has changed slightly, the shininess box has been changed to a slider named glossiness, however, it still has the same behaviour.


Download the park package with assets

Continuing the theme of ruining a medieval building, I have littered the nearby area with hazardous materials containers. Using the guidelines I set in that first tutorial, I have created a basic material for this new crate.

It looks pretty good right now, with the specularity conveying the look of painted metal quite well. However, some areas of the texture don’t quite match what I had in mind. I wanted the grey handles on the side to be a mirrored chrome finish, and I wanted the decals on the faces to a plasticised sticker, with more of a sheen than the paint.

We could get the chrome handle finish by separating the crate into two materials, but this wouldn’t work with the decals. We can instead achieve these multiple layers of specularity with specular maps, which specify the specular colour for every pixel on the texture.

How to use specular mapping

If you’re a Crazybump user, it’s very easy to generate specular maps for all of your textures. However, I’d personally recommend using specular mapping on as few materials as you can get away with. If you’re simply running your texture through Crazybump and outputting a specular map, you’ve probably not correctly set up your specular colour and glossiness settings. Instead, specular mapping should be used to represent different physical materials. This makes our crate a good candidate for specular mapping.

For our texture, we’ll basically be working with 3 levels of specularity. Our blue paint is the lowest specularity, with the chrome handles being the highest. The decals lie somewhere in between. In comparison to a Crazybump generated specularity map on the left, our specular map on the right is far simpler.

I’ve simply drawn over the decals in medium grey and the UV areas of the chrome in white. A PSD for this texture is included in the park package if you want to try doing this yourself, It also has the full UV wireframe. The metal is currently black, meaning there would be no specularity, but we’ll fix this by modifying the texture within the shading language.

Shading: Diffuse Textures

The material for this asset is slightly more complex that the previous tutorial, as we have a detail texture included. This is a common technique in games, where we have a “base” texture, which is tiled more times than the main texture (Using a Texture Coordinate Modifier in NL2) to give it more detail when observed up close. In this case, our detail texture is a slightly blemished metal. The normal map for the material also corresponds to this texture, as we don’t need a normal map for the main texture (all the details are in the mesh)

Therefore, the textures we are interested in for the shader are:
Diffuse – Texture unit 0
Specular – Texture unit 0 (alpha channel)
Detail Diffuse – Texture unit 1

Result.rgb = Mul(Tex0, Tex1);

This first line replicates the default behaviour of NL2 materials that have more than one diffuse texture. They’re combined by multiplication, producing the same effect as a multiply layer blend in Photoshop. This is to apply the detail texture on top of our main texture.

Mul (Multiply) is one of the several functions available to you in the shader language. The rest, along with all of the other documentation on the shader language, is available in the NL2 help page titled “NL2MAT Programmable Shader Core Language”. For now, functions take a number of parameters inside the parentheses, separated by commas, this function multiplies each pixel of the textures with the other texture as stated within the parentheses. In this case, we store this resulting texture in “Result”, our diffuse colour for our material. (Read more about this storing in the first shading tutorial)

Colour Values

A necessary tangent here. Calling this blending technique a multiplication operation may seem confusing to any of you who are familiar with Photoshop and digital colour. Multiplying the colour value {128, 128, 128} (50% grey) by itself would surely produce the horrendously unrepresentable {16384, 16384, 16384}, but if you try this in photoshop, the resulting colour value is {64, 64, 64}. (25% grey)

Inside a graphics library such as OpenGL – or in NL2s case, DirectX – colour values are converted from 0..255 ranges into 0..1 ranges. Therefore, 0.0 is black, 0.5 is medium grey and 1.0 is white. Mathematical operations on colours are now much more useful, with an effect being that multiplying two non-HDR images together will always produce a darker (or equal) result. For our example above, rather than calculating 128 x 128, we actually calculated 0.5 x 0.5, resulting in 0.25. When converted back into the 0..255 range, that gave us the result of {64, 64, 64}.

Just bear in mind that in the shading language in NL2, you have to specify all of your colour values in 0..1 ranges. To convert to 0..1 range, just divide the RGB value by 255, and multiply the 0..1 range by 255 to get back to RGB. (You don’t need to convert anything between these two ranges in your shaders, this is just to help you pick colours)

Shading: Specularity

Once your happy with how the two diffuse texture were combined, applying our specular map is straightforward. I’ve stored the specular map in the alpha channel of our main diffuse texture, so all we need to do is assign that channel to “Specular”, another register like Result.

Result.rgb = Mul(Tex0, Tex1);
Specular = Tex0.a;

In my specular map, the metal currently has zero specularity, I can increase that by adding a value across the whole texture. each pixel value is increased by 0.1, and in the case of materials that were already at 1.0, such as the chrome areas, values that exceed 1.0 are clipped back to 1.0 when rendered.

Result.rgb = Mul(Tex0, Tex1);
Specular = Add(Tex0.a, 0.1);

Specularity effects are a lot easier to discern in motion, but you can instantly see an improvement in the metal handles, which look far shinier than the rest of the model. You may also to be able to see that the decal is now more specular that the surrounding metal on the face that is catching the sun.


A cool thing about reflections is that their strength is also mapped to the Specular registers, therefore the specular map is also a reflection map, as long as we have reflections enabled in NL2MAT. You should set the reflection properties for the most reflective physical material in your texture. Becuase I have a chromed handle, I have set the fresnel to 1.0, fully reflective.


One of the great features of NL2 Pro that doesn’t seem to be used that often is the ability to capture cubemap screenshots. These can be fed straight back into the game for improved reflections. NL2 generates a default cubemap based on the environment and terrain, but to include objects and other details, you’ll need to create a custom cubemap, and import it into the box in the interface shown above. (ensure the ordering is the same as listed)

The custom cubemap gains a lot of detail, but because it is captured from a static viewpoint, it becomes incorrect as you move around the scene. You should therefore either use the cubemap on a material where the reflections are heavily distorted by the normal map, or you should blur the cubemap by capturing them with the “Cube-screenshot Filter-Passes” Picture export option set to a high number. (range 0-100 accepted, around >30 for significant blur)

Cubemaps will be a requirement in interior scenes or areas with strong lighting cues. For example, this tile floor in Point solitude uses a custom cubemap reflection:


Nolimits 2 Shaders: Emission Mapping

In my first material tutorial, I mentioned the methods used in rendering by OpenGL/DirectX programs, including Phong specular shading. Whilst diffuse colour depended on the angle between the surface normal and the light surface, and specular colour depended on the reflective angle between the light source and the viewer, emissive colour is constant, regardless of all environmental properties, it is similar to ambient colour in that regard.

The lighting components for such 3D programs could be summarised as:

Resultant Pixel Colour = Ambient + F(Diffuse) + G(Specular) + Emission

where F and G are complex functions which calculate the attenuation due to surface angles.

Don’t worry if you didn’t quite follow any of that, suffice it to say that Emission should be used for materials that, as suggested in the name, would emit light if they were their real-world counterparts. Therefore you’ll mostly be using emission for light bulbs, fluorescent tubes and neon lights. Today, we’re going to desecrate a medieval building by turning it into a fast food vendor, complete with garish neon signage.

Download the package with my assets


I used this texture for this tutorial, you can find more choices here. I recommend picking a texture that shows the illuminated surface turned on, with as dark a background as possible, as this will make the next step easier. You’ll need to create a Diffuse texture, as normal, as well as an emission map.

The emission map should have the illuminated surfaces in white (you can do coloured emission, but white looks better in this instance). You can paint this manually, but for me, I copied the green colour channel and increased its brightness. It should be obvious for your textures which channel will make the best emission map.

My textures, as used in NL2 look like:

Emission Map:

Material setup

Create a texture in the standard way (with standard lighting), you’ll need to enable alpha test if you’re using a transparent texture like mine, and you’ll need to load the emission map into an empty texture slot, and make note of the Texture unit number you’ve loaded each texture into.

You should load this texture into to your scene at this point, to test it’s working as normal. Because we haven’t set the shading method for the second texture, the colours will look odd right now, but as long as the transparency is working as expected, you’re ready to continue.


Open your material back up, and go to the Shading tab, switching the mode to Custom.

Once you’re in custom shading model, ‘standard’ texture units are no longer automatically combined into the diffuse color of the material. This allows use to use each texture for whatever purpose we want, but that does mean we need to manually state that texture unit 0 is our diffuse texture. Therefore, our first line in our shader will be

Result = Tex0;

‘Result’ is the diffuse colour of the material. We’ll do more interesting things with this in later tutorials, but in this case, we just want it to be our diffuse texture, so we’ve directly assigned texture unit 0. If your diffuse texture was placed in another texture unit, simply replace Tex0 with Tex1, Tex2 or Tex3.

For those of you who don’t program: Assignment is the way we move data about in computer programming. Data is moved from the right-hand side of the equation to the left, so in this instance, we took our diffuse texture, and set it as the resulting colour for our texture. We place the semicolon at the end of each line, for the benefit of the compiler.

Result is known as an “output register”, which I don’t want to go into too much detail here, suffice to say they allow us to modify various aspects of rendering by outputting textures to them. They consist of:


We’ll be using more of these in future tutorials, including a set of temporary registers which we can use for more complex shader calculations. For now, we want to set the Emission register to our Emission map in texture unit 1. Have a go at doing this yourself, the solution is below the image.

//Diffuse color
Result = Tex0;
//Emission Map
Emission = Tex1;

Those //comment lines do nothing in terms of the shader, they’re just there to label your code, you can use them as much or as little as you’d like.


Your texture should now look a fair bit brighter. Because of the way emission lighting works, it’s going to look a lot more noticeable with less ambient & diffuse lighting, i.e. in a dark ride or at night. One final touch, emission lighting only affects the material, not objects around it. To sell the effect, garnish with omni lights, and serve.


If you didn’t use a transparent texture in your version, you can store the emission map in the alpha channel of your diffuse texture, and then you can achieve the same effect with one texture file:


the .rgb and .a select specific colour channels to affect both in Result and Tex0. In this case, we don’t want to change the result colour alpha, and we want to select the alpha channel as the source of our emission map.

In my case, we can do one better! I said that my emission map was created by just increasing the brightness of my green channel. Rather than saving that as a separate texture, we can do the brightness modifier within the shader. With my original Diffuse texture providing the correct transparency.

Emission=Mul(Tex0.g, 2);

This takes the colour in the green channel, and doubles the value, making it twice as bright. We’ll look more into these mathematical operators in the next few tutorials. Just remember that often, clever use of shaders will reduce the number of texture files you need to include in your project.

Nolimits 2 Tutorial: Advice on Texture Sizing

The following is a tutorial for Nolimits 2 Roller Coaster Simulation, containing some general theory for real-time and video game graphic design.

Texture Resolution

The most common question asked about texturing is usually “what texture size should I use?”

First, consider that you’ll want to use a variety of texture sizes in your project; textures might have different aspect ratios, be used only on very small or very large objects, or on objects which are only used in the far distance. Therefore, I’d recommend picking a “standard” texture size for your project. To get a point of reference, below are a few examples of standard texture sizes in real video games in the past couple of decades:

  • Quake (1996) — 128×128
  • Source Games, Half-Life 2 through to Counter-Strike: Global Offensive (2004–2013) — 512×512
  • Counter-Strike: Global Offensive revamped maps (2016–present) — 1024×1024
  • Current generation titles — 2048×2048 (estimated)

I would, therefore, recommend using a standard texture size of 2048×2048 if possible. If however, you are not able to produce all of your texture assets at this size, I would recommend choosing a lower standard texture size, rather than mismatching different texture sizes. The issues of mixing texture sizes will be shown in the following section.



A texel is the name we give to a pixel in a texture map when we consider it in a 3D environment. So why the need for two names for a pixel? let’s take a look a texture:

a 1280x720 texture

Here’s a fairly boring texture, if you view it in its full size you’ll see the individual ‘texels’ in the image. Next, we’ll project it onto a screen that just happens to be the same resolution as the image.

We now have a 1280×720 ‘texel’ image projected on a 1280×720 pixel screen, and hopefully you start to see why we need the distinction between the two names. We now refer to the pixels on the screen as pixels (picture elements), and the pixels in the texture map as texels (texture elements). Currently, our pixels and our texels are perfectly in line, but now lets project the texture onto the scene from a 3d object:

We’re now looking at the texture on a plane object, with an off-center camera. We’re still showing all 1280×720 texels of the texture map, but we’re trying to fit it in a screen space that is clearly less than 1280×720 pixels. Each pixel consists of several texels. This isn’t really a concern, the graphics engine in the game will blend the pixels using bilinear and anisotropic filtering, giving most textures a realistic look. (although, as in this image, it produces weird effects on geometric textures like our checkerboard)

This looks acceptable, because the filter is removing detail we didn’t need, but what about the other way around. Let’s walk towards the wall and stick our face up against it:

It’s difficult to see what’s happening at a reduced image size, so open it in full size, and you’ll see that our pixels are now blown up and visible. This time, we have 1280×720 screen pixels to populate, but we’re only looking at a fraction of the texture map, the texels are substantially larger than the pixels. The engine is again running bilinear filtering on the image to blend pixels, but as there is no additional detail to be extracting when zooming in on the image, it can only interpolate pixel values, giving a blurred appearance to the image.

This is exactly what we get when we look too closely at our textures. If we consider the hypothetical endpoint of realtime graphics, every texture used would have a resolution so great that we’d alway have a texel density greater than our screen density at any conceivable viewpoint, but this is pretty unrealistic.

Texel Consistency

These goals are in all probability going to be impossible as screen resolutions continue to grow. Instead, we’ll focus on a decent looking standard texture size, and then simply ensure our texel density is consistent throughout our scene.

I mentioned that a source game like Counter-Strike: Global Offensive has a standard texture size of just 512×512, but thanks to the artistic expertise of the development team they can still produce better results than we likely can at 2048×2048.

One thing about the low texture size that is well done is the consistency. The illusion of the graphics is maintained despite the low texture size, but if we introduced a single, higher quality asset into the scene, it might look noticeably jarring, and overall worse than if you’d just reduced the texture quality of that asset. The same is true of the opposite. If the brick texture was over-stretched across the wall, it’d be instantly noticeable.

Analysing a scene

This is best done once you’ve finished a whole area of your scenery, as we’ll be comparing all of our textures. We’ll start by making a full copy of the current project, I’m going to take a look at my first project which had extensive 3D work, Point Solitude, and see how well it holds up to my newly asserted standards.


We want an easy way to visualise the texels in our textures, and whilst we can’t really see or count individual texels, we can make a texture which shows off our texel count more easily.

I’m going to use Adobe Photoshop (CC) for this texture, but any decent graphics package should have the equivalent functionality. Create a new 512×512 image (half this to 256×256 if you chose the 1024×1024 standard texture size). We’re then going to split create a checkerboard in the image as shown:

In brief, turn on snapping and create a selection from the corner, you should see pink lines when you’re dead in the center of the image. Add superfluous bevels/effects as desired. Or copy and paste mine!

We now have a checkerboard pattern where each square contains 256×256 texels. To ensure these texels have consistent density however, we need to tile this checkerboard on an image the size of our textures.

To do this, first select the whole canvas (Alt+A) and go to Edit->Define Pattern, click OK on the dialog that appears. Now, open a new image, starting with the size of our standard texture (1024×1024). Use the fill tool, switch from “foreground” to “pattern”, and then choose the pattern we just saved. Fill the image with pattern.

We now should have a 1024×1024 texture, with squares still measuring 256×256. Follow the same instructions and match all of your used textures sizes, I had textures measuring 512×512, 1024×1024, 2048×2048, 1024×512 and 1024×128. You should have a small agglomeration of textures like mine below:

Now, go to Nolimits 2 and make some very basic materials for each of your textures. Now, replace all of the materials in your scene with these materials, making sure you match the old and new texture sizes. Once this is a done, you now have a scene showing you the texel density for each surface.

The results

Firstly, we want to pick a texture to use as our reference point. The walls of the station are a standard texture size, and looks good even when close up, so we’ll pick this as our ideal texel density. Nearby textures such as the lower wall texture and roof have similar square size, so they’re fine too. (the roof is a double-size texture, it has twice the texels over roughly twice the size, so the texel density is about equal to the smaller textures)

Fixing the texture

Moving down to the grass, you can see that the squares are quite large, almost twice as large, in fact. Now, for each texture that doesn’t meet our standards, we can do several things:

  • Resize the texture
  • scale the UV map for this texture, making it tile more/less
  • a mixture of the two

This is your decision of course. As the grass texture is a very common one across my scene, I’m happy to afford it the extra graphics requirements and I’ll opt to double the texture size to 2048×2048. I’ll replace the texture in the unchanged copy of the project, and I’ll switch the material in this version to reflect the change.

What if I can’t change the UVs on my model?

If this is the case, you’re probably using Sketchup to make your models. I’ll take the opportunity to politely remind you: Sketchup is not a suitable modelling package for realtime graphics modelling. It’s a powerful tool for designing architectural models, and I’d definitely recommend it for designing buildings in conjunction with a optimisation/texturing pass in another program, but you shouldn’t be using it by itself.

Take the time to learn Blender3D, or Autodesk 3DS Max if you have bottomless pockets. The manual meshing and UV controls are critical for your final art pass, and for non-architectural models these programs are just far superior anyway. I shall say no more on the subject for now.

Further examples

This gets quite wordy, read as much as you feel you need to, or skip ahead

The grass’ texel density looks great now, let’s move onto the path texture. This ones a little tricky, as the texture includes a grass border, so we can’t scale it horizontally. We could scale the texture vertically a little, but beware, as scaling directionally will look oddly stretched.

Other than fixing that glaring UV issue on the right, I’d actually keep the texture at the same resolution, halving the size to 512×512 would leave it too blurry for something so close to the player. In addition, the use of the texture in the background is much closer to the density we want, so perhaps just widening the path model would be a sufficient fix?

So you’re aware, the window glass here is about the same density as the station textures from before. Most notably here is the main wall texture. This is a texture not designed to tile much, so has to be spread out quite far. It is currently a 2048×2048 texture, and seeing as it’s the centerpiece of the entire scene, I’d say it’d be worth upping it to a 4096×4096 texture.

This seems a little contradictory, I said before not to have one asset vastly better than any other, as it will look out of place. Remember however it’s the texel density, not count, which gives us our apparent quality at any given time. If we double the texture size, we’re bringing the texel density right into line with the other textures here, so really we’re quite safe to do so. We could also double the tiling in the UV map, depending on how nicely this texture looks tiled.

Very quickly, the black metal is too dense, so we’ll scale that back, as is the window frame, and the railings. Everything else looks fine, the roof doesn’t look very dense, but I’ll come back to that later.

We see the obvious offender here in the cliffs, which are frankly terrible, and I’m embarrassed I ever let this get past me. Let’s take a closer look:

What a convenient worst-case example I’ve provided for you. The path resembles an actual “thing”, but the rock is just a collection of pixels. This calls for both a 2048×2048 texture, and a significant UV tile increase too. I’d also consider a 4096×4096 texture for this also, though a new source texture would need to be found in this case.

An Exception

If you hunt around a game in noclip or a level editor, if distant details are rendered in 3D, they’ll get progressively lower detail as you get further away, this saves performance, and quite simply we don’t need that much detail.

We can apply the same principle here. Whilst mipmaps will ensure the lowest texture resolution possible is chosen, areas such as the distant cliffs in the previous checkboard image (through the fog), or areas of cliffs which aren’t approachable on foot don’t need that much detail, and may look better with reduced tiling. Again, mipmaps will deal with the performance, so concentrate on the correct aesthetic look, the pathway on the cliff shown helps break up the texture, allowing more tiling, whilst on the other side, with sheer walls, that amount of tiling would become too noticeable.

Actual Photographic Scale

Here are two grass textures. What happens if we set the texel density for the first texture, then switch the texture for the second?

The first texture is a distant (almost aerial) grass texture, whereas the second is close-up, almost macro, you can see individual blades of grass in great detail. Remember to consider the distance the photosource was taken at when looking for textures, we really want something between the two. Think of the detail you get out of a good texture, and compare that with your photosource.

For example, in a brick wall texture, we expect to see the shape of the brick and some general detail to the brick surface, but we don’t expect to see individual pores in the brick texture. In a grass texture, we expect to see clumps of grass, and outlines of grass blades, but we don’t expect to see three distinct lines forming the shape of the blade, or really many pixel between the edges of the blade at all.


This isn’t something that absolutely must be done, and it’s a little bit of a hassle to implement given all the manual work needed to switch textures, but it’s a useful way to analyse your work, and identify any glaring issues you’ve overlooked. Hopefully you’ll find this useful, and will give you’re scenes a more consistent look.

Like last time, here are a few summary points

  1. Texture size is unimportant, make your textures consistent
  2. Identify ill-sized textures, and choose the right fix for that situation
  3. Use additional modelling detail to hide tiling when an increase in tiling is necessary
  4. ensure the photosource for your texture was taken at the correct distance from the subject

Nolimits 2 Materials: Specularity and the Shading model

The following is a tutorial for some of the more advanced features of Nolimits 2.

I’ve been guilty of doing this myself, but your method for creating materials in NL2 may well be to create a new material, add the diffuse and normal maps, take a step back and look in wonder at your lovely new texture:

A default normal-mapped texture

If that sums up your method, I’ll silently weep for you when I see your creations. But don’t worry, I suspect most of the people who are using bump mapped textures are doing this now. So, specularity might seem like an unusual place to begin for a series of material tutorials, but it is in one person’s humble opinion, the most important setting in getting a realistic appearance with your material.

NL2 Shading Modes

There are 3 main shading types in NL2:
3 shading modes

  • Constant – All pixels of the object are shaded the same colour, with no shadowing or other effects. Useful for anything that emits light (bulbs/filaments), or things only designed to be seen in-editor.
  • Simple – Affected by shadows and ambience, but otherwise the same colour throughout. The editor is largely correct in saying it’s for decals. Anything gaseous or particulate should use this mode. It also evidently does not like high-poly spheres
  • Lighting – Has both smooth shadow shading, as well as a specular highlight

Options such as Wave or Vertex lighting are essentially “manual” lighting control. Bump lighting is for the purposes of this tutorial identical to regular lighting, bump mapping will be explored in a future tutorial.

Explaining Phong Shading

Taking a look at the specular highlight “dot”, especially on abstract objects like the untextured sphere above, it doesn’t make a lot of sense, or at least, it doesn’t look like any real object. I’ll show some examples in the following section, but now I’ll take a look at what it’s simulating in terms of light waves.

Not all objects look “reflective”, i.e. the mirror finish we refer to when we use this term, but obviously, all objects reflect light, as light is reflected off the object and into your eye, allowing you to see it. This type of light reflection is called “diffuse reflection”, light rays hit the object and disperse more-or-less equally in all directions. this type of reflection is responsible for most of the sphere as we see it above.

When a surface is smooth enough, reflection occurs without scattering, and light is focused directly from the angle of incidence to the angle of reflection, allowing you to see a reflection.

In fact, and it’s not entirely surprising when you think about it in terms of light waves, every surface has both diffuse and specular reflection to some degree, specular reflection just usually occurs at a very specific angle of incoming light.

reflection of light on a surface
As a fun experiment, grab a piece of regular A4 printing paper and hold it perpendicular to your eyes, as if you were a tiny person stood in a giant field of paper. At the right angle, the seemingly matte paper will produce a reflection. If you could hold the paper flat in a very specific orientation, it would reflect like a mirror.

It’s this specific angle of reflection which is responsible for the specular dot we see. Light is reflected far more at this specific angle, usually, this dot is reflecting a light source, causing the white dot.

Phong shading includes an approximation of this effect, it is performed on every pixel on the surface, and at certain angles will cause the specular dot. Its formula for the specularity, if you are interested, is , where Theta is the angle of light hitting the object, and n is the “shininess value you’ve probably seen in the NL2MAT editor. Take a look at the graph for that formula:

sin of angle, power of shininess

Just imagine the height of the line to be the brightness of the specular dot, and you start to see how the formula forms the shape of the dot. full white in the centre and the curved edges cause the light to smoothly drop off around it.

Aside: An odd thing about the NL2 editor is that it allows a range of 0..128 for shininess, which is odd, seeing as sin^0 of anything is 1, meaning the specular highlight will completely engulf the object. Values of up to around 200 are often used in real-time graphics elsewhere. Ole plz fix.


So, we know the “shininess” value in the NL2mat editor affects the size of that odd-looking white dot, we’ll take a look at various values for that now:
spheres of various shininess'

Despite allowing you to choose a shininess between 0 and 128, there aren’t any times you’d want to go below 4 or so, and interestingly enough there are times when you’d want to go higher than 128, but the allowed range is fine for most real objects. A high value would be reminiscent of a Malteser chocolate, and a low value might be reminiscent of a ball made of velvet. The reason for the slightly tortured comparison there is that low shininess materials often need to be combined with a lower specular colour, as they reflect less specular light in general.

Back to our texture

If you’d like to try this yourself, download the texture and mesh here

A default normal-mapped texture
Here’s our texture from before. The texture work isn’t too bad if you don’t mind me saying, but it looks noticeably wrong in some aspect. The highlights are completely blown out to white, (try find that in a photograph) which also exaggerates the detail in the bump map. Rookie Mistake: Your normal map won’t magically make a texture look 3D, so don’t try and make it do so, use meshes to add large detail to your materials, and bump mapping for minute detail.

Think about our shininess values from before. The rock clearly isn’t polished like a Malteser, but also doesn’t have the odd ‘all-over’ reflection of velvet. I went with a value of 8 (changes are more sudden at the lower end, so this is quite different to 4). I also reduced the specular colour to 70-grey, as the rock wouldn’t have much of a specular reflection at all. The result looked like so:

adjusted version of our old texture
Specular highlighting is still there, but it’s so subtle you only notice it when told it’s there; looking at the areas which were blown out white before, they’re now just gently brightened. This is now pretty realistic. Bump mapping looks a little harsh in the shadow, we can either smooth the normal map, or we can

increase the ambient colour (best to do this in the env, not the NL2MAT, as that’s a global change).

As one final experiment, we’ll change the rock to look like it’s been out in the rain. It’s going to gain shininess now. I chose a value of 96, which would be suitable for a rock that had been quite thoroughly rained upon. I upped the specular colour slightly to 90-grey, but be careful not to go overboard with that, in most cases we never want the specular highlight to be blown out to full white. I also darkened the diffuse colour a little, which helps give it a damp look. This isn’t necessary if your entire scene is wet, but if you have a dry and a wet version of an object near to each other, it will make the transition more believable.
adjusted version of our old texture

As before, subtlety was kept a priority. Specularity hasn’t wildly increased, but the highlights are now tighter, and more localised to the cracks and crevices of the surface, rather than the flatter areas, which wouldn’t be covered in a film of liquid.

An in-Scene Case Study

an example scene
If I asked you to describe the wooden floor shown below, hopefully, a word along the line of “polished” or “shiny” would come up pretty soon. This clearly isn’t some antique oak plank with cracks showing, it’s a smoothly finished modern flooring. In the past, I have jumped to conclusions with wooden textures. Wood isn’t reflective, besides, the NL2 wooden supports aren’t shiny, why would I make my floor shiny? Think about your materials not only in terms of the physical material they represent, but think of the various forms and finishes this material takes, and which one of these your texture map best represents. I also mixed in a little cubemap reflection, as seen on the far right, more on that later.

(shininess:64, specular colour:default)

You may have noticed, by the way, that there are several specular highlights in the floor here. Each light casts its own highlight on the surface. I haven’t created a light fixture model for this scene, but they’re omni lights placed directly between each beam, for reference.

an example scene
The plaster looks especially nice in motion. The broad specularity just looks like the light hitting the surface, but bumps in the surface still show noticeable highlights

(shininess:16, specular colour:50,50,50)

Concluding points

hopefully, that’s given you some things to consider when making your materials, and some new insight on how the shading model actually works. Some concluding hints to refer to when making your materials would be:

  • Think about the variations the physical material you’re mimicking can take. For example, don’t say “This is rock”, but “This is well eroded and smooth rock, but not polished”.
  • Set your shininess value to the right value before touching the specular colour, this will result in a more realistic result.
  • If in doubt, image search and find a reference photograph for the object. Spot the diffuse and specular reflections on the surface, and compare them to the examples I’ve shown.

If you have any questions or any specific materials you’d like suggestions for, comment below.