MART Term 2, Lecture 6
Procedural vs Image Mapped Texturing

Different Types of Texture

There are two different ways to texture: image mapping and procedural textures.

Image mapping involves taking a bitmap image (like a jpeg or a tiff), and laying it over the surface of an object to make it look like it's made of a particular material. The image is often made from a scan or photo of the real material, fiddled around with in Photoshop / GIMP, but it can also be painted from scratch.

Procedural texturing involves the use of mathematical functions to produce textures. This may sound scary, but it doesn't have to be: think of them just as patterns, you don't have to worry about the maths behind them. For example, a chequerboard is created by a mathematical function, but we don't really think of it as such, we just think of it as a pattern.

Procedural Textures

[screenshot: MART_T2L06_html_64027b64]Today we're going to look at the differences between procedural textures and image mapped textures by creating a wood texture using each in turn.

In a new scene, get a polygon cube. Scale it up in x & z (ctrl-drag on the y manipulator), and then bevel the edges a little. Whenever making any object, make sure to bevel the edges, even if only slightly, as there is nothing more CG than perfectly sharp edges.

Add a spotlight too, so we have some decent lighting rather than the rubbish default lighting. I turned off my grid too, and turned on high quality rendering.

Save this scene, because we'll use the same scene again when we come to use image mapped textures.

[screenshot: MART_T2L06_html_m6283a1d8]Now assign a new texture to it: a blinn is probably best. From here on in we're going to be working with textures, so let's set up our work area to include a render view. You can do it however you want, but I'm going to use the predefined Hypershade/Render/Persp layout. However you do it, make sure you can easily get to both the render view and the hypershade.

Get the attribute editor of the blinn node up, and click on the chequerboard to attach a node to the Color attribute. Scroll down to 3D Textures, and click on Wood. The example sphere render in the hypershade should now look kind of wood-like, but if we re-render our bevelled cube, this very much doesn't. There is a good reason for that. The default set up for the texture is to line the "tree" up with the z axis exactly: real wood as cut from a tree is usually cut at a slight angle.

[screenshot: MART_T2L06_html_690d3297]Select the new wireframe cube that has appeared at the centre of the piece of wood: this is the place3dTexture node, which, unsurprisingly, lets you choose how to place the 3D wood texture. Rotate it around the x axis by about 2 degrees, and we'll also scale it up (in all axes equally) so that it covers the whole object. Move the camera round so that we have a nice big highlight over the surface. Try changing the component colours if you like: I've made my wood darker and redder.

The problem with the texture now is the specular highlight: it is too perfect (as is often the case in CG). We need to try and break the highlight up a little. What would be good is if the highlight looked sort of like the surface: it should break slightly where there are age rings.

Hover over the connection in the hypershade* between wood1 and blinn1, and you'll notice that it connects wood1.outColor to blinn1.color. Maybe we could just connect it from wood1.outColor into the specular color of the blinn node. Let's try it and see: middle-drag from wood1 to blinn1, and select specularColor from the pop-up menu. Now re-render: our highlight has turned the same colour as our wood. This is not what we wanted: we want the highlight to be the same luminosity as the colour of the wood at that point, but not the exact same colour. Using the same colour tends to give objects a metallic feel.

So we'll use another node. In the list of available nodes, scroll down to Luminance (in the Color Utilities section) and click on it. Now we want to connect this between our wood and our blinn. Firstly, we'll delete the connection between wood1.outColor and blinn1.specularColor: click on the connection, and press delete. Now MMB-drag wood1 onto luminance1, and select Value from the pop-up. Now MMB-drag luminance1 onto blinn1, and select specularColor. A connection editor will pop up. This is because Maya gets confused: we are trying to connect one number (the outValue from luminance1) into three numbers (the specularColor of blinn1). In the connection editor, select Out Value on the luminance node and all three of the Specular Color R, Specular Color G and Specular Color B on the blinn node (don't forget, Maya will try to be "helpful" by making Specular Color grey on grey: you'll have to look very carefully to spot it).

[screenshot: MART_T2L06_html_m8903479]Now re-render. This has started to look better: it feels like the grain of the wood affects the highlight, in the same way that it does in real-life. But we have little control over it: It would be good if we could set the minimum colour for the specular (currently black) and also the maximum colour. Theoretically the maximum colour is currently white, but actually our texture never gets that bright. So our specular colour currently goes from black to around 30% grey.

We want to set this range to something else, so amazingly we're going to use the Set Range node (in the General Utilities section). Bring one in, and put it either between wood1 and luminace1 (slightly easier) or between luminance1 and blinn1 (more correct). Get the attribute editor of the setRange node up, and you'll see that we can change the Old Min and Old Max. These are the values for the range that we are going from. As discussed before, our current range is between <0, 0, 0> (black) and about <0.3, 0.3, 0.3> (30% grey), so put these in as Old Min and Old Max.

[screenshot: MART_T2L06_html_718817c]I had thought we should go for a highly polished look on this wood (if you prefer, you can leave it how it is), so I'm going to increase the brightness of the highlight. Let's set the minimum to be 20% grey, and the maximum to be 70% grey (much higher and it will just look silly). We'll also have to adjust the specular highlight options on the blinn: if we want it to look highly polished, we'll have to make the highlight much smaller. Increase the Specular Roll Off to 1, and decrease the eccentricity to 0.15.

This improves things slightly, but the specular highlight is still a bit too perfect: a leading factor in this is that the surface of our cube is completely flat. In real-life, no object would be this perfect, so we should add some imperfections to the surface. Rather than subdivide the object to do this, which would add loads of new polygons, we will use something called a bump map. A bump map simulates changes in geometry without actually changing the geometry, which makes it very cheap.

The brightness of a surface depends upon the angle that each light makes with the surface: if the light hits the surface full on it will appear very bright, but if the angle is merely glancing, the surface will be much darker. A bump map fiddles these numbers: for example, it can tell a surface to light itself as if it is facing directly towards light, when the geometry itself is actually at quite a shallow angle. This gives the impression of a bumpy surface, but without the need for expensive extra geometry.

Let's apply this now. Get a 3D Brownian texture: that's what we're going to use as our bump map. Now scroll down to general utilities, and get a Bump 3d. Connect brownian1 to bump3d1, and bump3d1 to blinn1 (as bump map). If you do a quick render now, you'll see that the effect is MUCH too great. Get the attributes of the bump3d1 node up, and change Bump Depth from 1 to 0.02 to distort the highlight only slightly.

If you wanted to make a texture similar to an unvarnished wooden surface, you could have a play with using the wood pattern itself as a bump map (you might not need the specular map in that case).

On the render view, now click on the Keep Image button so that we can compare the two. Save a copy of the scene at this point: we may come back to it later.

Image Mapping

As described before, image mapping is the process of using an image file, such as a jpeg or a tiff, instead of a procedural pattern. Delete the connection between wood1.outColor and blinn1.color, open up the attributes of blinn1, and click on the button to connect to the Color attribute. Make sure As Projection is selected, then click on File. Now click on the button next to Image, and then the one next to Image Name (the folder button). Now find the following file:


[screenshot: MART_T2L06_html_2735cdeb]This projects the image across the scene. Unfortunately the default projection type is to project in the xy plane, but we want the xz plane. Click on the new place3dTexture node (the one that's connected to the projection node*) and rotate it so that it's at about the right angle. Now do another render.

[screenshot: MART_T2L06_html_5537cb79]So we've got the colour of our wood looking right, but the specular is still controlled by the old procedural texture. Swap them over in the hypershade (be sure to plug the projection node in, not the file node), and adjust the range of the setRange1 node as well (I changed the range on mine to:

Old Min <0.4, 0.4, 0.4>

Old Max <0.9, 0.9, 0.9>

Min <0, 0, 0>

Max <0.7, 0.7, 0.7>).

Another way to create a specular / bump map from the original image is to change it in GIMP: make it monochrome, increase the contrast, etc. If we did this, we wouldn't need to use the Set Range and Luminance nodes, but we would need to bring in two separate images, which is slightly inefficient memory-wise. More importantly though, in order to change the range (i.e. brightness) of the image, we would have to edit it in Photoshop / GIMP: we wouldn't have the control over the range within Maya that we have here. We also would not be able to animate the brightness as we could here.


Now compare the two images. This isn't the easiest thing in the world, as the two images produce very different types of wood: the image map gives a weathered feel to the wood, whereas the procedural texture creates a much cleaner wood.

This is generally the case with all procedural vs image-mapped textures: image mapped textures are generally better for aged, weathered looks, as it is very difficult to simulate the process of ageing (of anything: wood, metal, etc) in mathematics. For clean surfaces, such as highly polished woods, metals, plastics, etc., procedural textures can do a great job. Note, though, that no matter how clean the surface, there should always be some imperfection added within the texture, whether procedural or image-mapped.

There is one important benefit of procedural texturing that I haven't pointed out so far. In both of the cases we've tried, create a sphere and apply the wooden texture to it. Because our 3D procedural texture is not dependent on object shape, it fairs much better than the image mapped sphere which gets horrible stretched bits.

As with most things in CG, there is no correct answer: neither procedural nor image-mapped is the "best" way to texture. Some surfaces, generally man-made ones (e.g. plastics) lend themselves very well to procedural texturing. Organic surfaces (e.g. wood) are much more difficult, and are generally carried out using image mapping. It is important to know the strengths and weaknesses of both methods before deciding which to use.

*The bottom pane of the hypershade, by the way, is basically just a cut down version of the hypergraph.

*At this stage, you might want to try Graph → Rearrange Graph in the hypershade.