Wednesday, 22 April 2015

Blender: Introduction to Textures, UV Maps, and Materials - Part III

By the end of Part II of this series we had learned how to make our very first UV map of a simple rectangular box and we'd learned how to create a material and assign an external texture to it. We're going to continue playing with that box for a little longer before moving on to talk about UV mapping more complex objects.

It occurred to me that while I did show how the UV map relates to the mesh object I may perhaps have failed to emphasize (or at least directly state) how that in turn relates to the object in world.

I uploaded the exact brick texture we're working with in this
tutorial so the screen shot here is using the identical brick.png

At first glance in-world you would think there's no real difference between our uploaded box and a prim cube set to the same dimensions. There is, and this is what I should have made a little clearer at the end of part II:
  • A prim box has 6 SL-faces (one per side) and each SL-face can be selected independently, then given a different texture which you might then scale, rotate or tint using the controls in the Texture tab of your viewer's editor. Each side of the box is "texture-independent" because each is a separate SL-face.
  • Our mesh box has only 1 SL-face because we've only assigned 1 material to it and each material is imported as a SL-face. When we apply a texture that face in-world, the texture is mapped onto the object based precisely on the UV map we've supplied. If we scale or rotate the in-world texture, it affects all sides of the box equally because as far as it's concerned the entire box is just a single SL-face. This takes a little time to get used to working with.
There is an -in-Blender way of setting up the material to allow us to scale the texture on the surface of our mesh to allow us to preview it on the screen, but that's a bit beyond the scope of this tutorial.

As an exercise (that also helps illustrate a number of other points), let's make our box into something that would behave identically in-world to the way a prim cube does. Since this means that we are going to want 6 SL-faces in-world, and each SL-face or a mesh is a different material, this means we're going to need a total of 6 different materials assigned to our mesh box -- one to each side. What is often difficult to grasp as a beginner is that this does not mean that we need to break up our UV map! The map is independent of the material.

To add an additional material to a mesh object, click the small "+" sign on the right-hand side of the list of materials in the Properties pane's Materials tab. This will then add a new material slot to the list for this object and everything else we do is the same as we did when setting up our first material. This time, though, we're just going to give it a different viewport colour but not bother to assign an image texture to it. If you need a detailed reminder of the steps, they're in the picture.

We've added the new material, but nothing has changed on our model. That's because when we assign the very first material to an object Blender automatically assigns it to all faces (Blender-faces) of the object. For any extra materials you add to the object, you need to explicitly tell Blender which faces should use that newly-defined material.

Select all of the faces on the front side of our box. I used face-select mode and the Circle select tool but you can use any method you like (see the Baby Steps series of tutorials). You'll notice that if you're in face select mode the selected material in the list in the Material properties will automatically highlight our previous brick texture because that's the material currently assigned to the faces you're selecting.

Select our "SL-face 2" material from the list, then click the "Assign" button to tell Blender to assign the selected faces to this material instead. As soon as you do so, your selected faces will lose their brick texture and show the purple colour we picked for the viewport display of 2nd material.

Now we need to repeat the above steps to create materials called SL-face 3, 4, and 5. Then add one more called SL-face 1 because in SL the first face actually has the number assignment  "0". Our brick texture can be our SL-face 0 material. You can create all of these extra materials before you assign them since the materials are independent entities.

When you create a material, even through you're doing it this way with an object selected, what you're actually doing is creating an available material for the scene. Because of the (in my opinion very convenient) method we're using, this newly-created material is being added automatically to the select object. That identical material is available to any and all other scene objects and any change you make to the material's properties is automatically reflected in all objects that have that material assigned to it.

To make our box exactly like an in-world prim we'd have to figure out which number to assign to which side of our box but for our purposes let's not take the time and effort to do that. Once you've finished, you could upload two copies of your box -- the one with only 1 material assigned to it and the new one with 6 materials -- and rez them both to the ground then play with textures on them. Your second box will be almost identical to working with a prim cube.

One useful thing to discover at this point is a handy Edit mode selection method that we didn't talk about in the Baby Steps III tutorial. Try selecting none of the faces, then choose (select) one of the materials in the list of materials assigned to the box, then click the "Select" button. It will immediately select just those faces/edges/vertices (depending on which selection mode you're in). You can add to the selection by picking another material and clicking the "Select" button again since this is "add to the current selection" rather than "replace the selection."

Similarly, you could select the entire box then select the name of a material and click the "Deselect" button to deselect those faces or edges or vertices. The selection method you're using when you deselect a material is important because vertices and edges will have more than 1 material assigned to it if it's at the boundary between two materials. If you're in vertex select mode and deselect the SL-face 1 material, you'll also be deselecting some vertices that belong to some of the other textures which will affect which faces are selected. If you do the same thing in in face select mode only the faces assigned to that specific material are deselected.

As a general rule of thumb to avoid mistakes, it's not a bad idea to switch to face select mode before using either button, then switch back to vertex or edge select mode if you need to do an operation with a vertex or edge context.

This also illustrates that it might often be convenient to assign materials to faces even if you haven't yet UV-unwrapped your object because then you can use them to speed up your workflow if you need to rapidly select or deselect parts of the object while working with it. For a complex object you could conceivably create dozens of different "working materials" to make selection easy; then delete them later to get yourself back within SL limits.

Speaking of deleting a need to be aware that there are two "contexts" and therefore two methods for deleting a material.
  • delete a material from being assigned to an object
  • delete a material from the scene
To do either of these you must be in Object mode with the object selected.

If you just want to delete a material from this object you select the material in its list and click the "-" sign. This well remove it only from this object and any faces that were assigned to this material will now be automatically assigned to the next material above it in the list. If you delete the very first material in the list, they'll be assigned to the material that now becomes the 1st material. If there are no materials left in the list, your object will be back to having no materials assigned to it and look the way it does immediately after you've added the mesh object to the scene. This has absolutely no impact at all on the object's UV map because that's a completely separate, independent entity.

If you want to completely delete a material from the entire scene, select that material in any object that uses it and click the "X" symbol to the right of the location that you rename it. Be careful though! This deletes the material from every single object in the scene that uses it so all faces that used that material will then be reassigned to whatever material was above it  in that object's list (which might not be the same as the material above it in this object's list).

Generally speaking it's a lot safer to only delete a material from an object rather than the scene, even if no other objects are using it, just to avoid accidents. Blender does some "smart culling" of materials when you save a file. If there's a material that isn't being used by any object in the scene it won't bother saving it so the next time you load the file it will disappear. In the meantime, the material will still be held in memory and could be used for some other object.

You can even persist an unused material in the file by flagging it using the little "F" button beside its name. This tells Blender to store it even though it has no current users. If you've flagged a material, you need to hold down the shift key when you press the "X" button if you want to completely delete it from the scene and have Blender stop saving it.

While all of this is great for showing you how to create new materials, delete materials, and so on, it's not showing you any of the power of using mesh even for something as simple as a mesh box. If our goal was a box that's identical to a prim cube we'd just rez a prim cube. Let's do one very simple example of something that we can only do with a mesh box that will also introduce you to a concept about UV maps that is a little mind-bending when you first encounter it.

Delete all of the additional materials we just created except for our original brick material one one other (it doesn't matter which other one you keep) and rename that extra one "picture." If you kept SL-face 2 and made yours purple like mine is, you'll have something like this:

Now switch back into edit mode. select all faces and use the "Assign" button to assign them all back to the brick texture (leaving no faces currently assigned to the "picture" texture. Now deselect all faces and then select only the four faces in the center of the top of the box and assign only those four faces to the "picture" texture instead.

Let's think for a moment what would happen if we import this in-world and texture it. If we pick the mesh "prim" and apply a texture to it, it will look exactly the same as it did when it only had the single material assigned to it because the UV mapping is keeping everything nicely aligned and we're telling it to use the same texture in-world for both SL-faces. But what if I switch to the viewer's "Select (SL-)Face" mode and pick just that small rectangular part that we've assigned to our "picture" material and apply this picture to it instead:

Picture I took of my Hedonism dance club in Refugegrid
You are free to save a copy to work with for this tutorial

The following screenshot from in-world shows exactly what happens, with both being the identical mesh box. The one on the left is assigned only the brick texture so it's being assigned to both of the SL-faces of the mesh. Because they use the identical UV map which defines the entire mesh surface they're perfectly and seamlessly aligned. If I change the scale or rotation or any other aspect of the texture, they'll both be affected identically.

The Box on the right is something that's impossible to do with a single prim unless you make a special texture for the one side of it that has our Hedonism picture embedded into it, then apply that texture to that face. But if I later change my mind and want to use a different surrounding texture I'd have to go back and create a whole new special texture for that side. The same would be true if I changed my mind about what picture to display...I'd have to go and make a special texture for the whole side again. And then if I decided I wanted to scale my bricks to make them very small, I'd be back into PhotoShop again to make yet another special texture and be jumping through hoops to get everything nicely aligned.

I could achieve something like this using two prims -- the one with the picture raised above the surface of the other as is commonly done with picture frames in-world -- but this is just an extremely simple example to illustrate the point so the difficulty of replicating the effect using only prims isn't hard at all. Also, any time I have to use 2 or more prims to make something I'm immediately presented with the issues of adjusting and possibly scripting a linkset later rather than a single prim.

"But wait," I hear you thinking, "we're only seen a small part of the Hedonism picture in that space." Yes, that's true and let's demonstrate why. Take a copy of my Hedonism picture (or use some other picture you already have stored on your computer instead, if you prefer) and use the same method we used in Part I of this tutorial to assign it to our picture material. Then in the UV/Image Editor pane select it from the drop-down list of loaded images so it's displaying in the pane, and select the four faces you assigned to the "picture" material on your mesh.

This explains what we're seeing in-world when our viewer's texture is still set to scale with x and y at once per dimension. This maps the entire image texture to fit the horizontal and vertical dimensions of the entire UV map instead of just this small section of it.

One solution to this is to adjust the in-world scaling (and vertical and horizontal offsets) of that SL-face until the image displays correctly. It would take a bit of fiddling around with it until you got it just right, but it's possible to do. Wouldn't it be handy if there was an easier way? Happily, there is, but first we need to take care of a second issue that would be a problem no matter whether we were working with prims or mesh: the "aspect ratio" of the image.

If we want to fill our material area with this perfectly square image we can't do it without distorting it. If we keep the rectangular shape our material, our Hedonism picture would have to be stretched (quite a lot!) left-to-right to make it fill that width. That means we need to fix our material area to make it square.

We're going to move our existing edges to do this and I'll just give you a fast "step by step do this" set of instructions rather than explain exactly what we're doing or why since that's more in the subject of modeling techniques.
  • In the 3D View pane, switch to edge selection mode
  • Hold down the ALT key and select one of the two left edges of our picture material. This will select the entire "edge loop" that runs all the way around the box.
  • Hold down the SHIFT key and ALT key and select one of the two right edges of our picture material. This will add that edge loop to our selection.
  • Use the hotkey combination S X 0.5 to scale our selection along only the x-axis by a factor of 50% which will result in the picture area now being square

Now we have a nice square area for our picture to go into (although it's a bit small for the overall size of the object but for this tutorial that's fine) but you'll notice that something odd happened to our materials displayed on the mesh. The bricks along those outer faces are now stetched quick badly, and the bricks along the inner faces and in our picture are are now squished left-to-right. That's because changes to our mesh do not change their corresponding locations on the UV map that we've already made. If you select all you'll see down in the UV map that they're all evenly distributed exactly as before so when our textures are mapped the get stretched as required on the mesh to match the mapping.

To resolve that, the easiest thing to do in this case is simply repeat the same method with our map that we just used on our mesh.
  • In the 3D Pane select all (hotkey A) so we can see our entire UV map
  • In the UV/Image Editor pane switch to edge UV selection mode
  • ALT + select one of the inner left edges to select that entire loop
  • SHIFT + ALT + select one of the inner right edges to add that entire loop to the selection
  • Scale them using the hotkey combination S X 0.5 (we have to use x, not u for the hotkey even though we're technically scaling the u-axis not the x-axis)

This resolves our brick-stretching issue and gives us a nice square area for our picture material. There are other methods we could have used achieve this but doing it the way we did allowed me to show you the effect of editing parts of the mesh after you've already mapped it.

Now we get to the part I referred to earlier as being a little "mind-bending" about UV maps. While our picture material is now nice and square, it is still mapped to only a very small portion of the total image area. To make our in-world texturing job incredibly easy, it would be nice if we could just cut that little part out and map it differently than the rest of the mesh to make it fill the whole space. We can!

In the 3D View pane switch to face select mode and select only our four picture material faces. Then use the UV Unwrap drop-down and pick "Unwrap" again. If you recall, in Part II of this tutorial I was very careful to explicitly say "Blender's unwrap functions only unwrap and optimize the unwrapping for the currently selected faces" which means when we do this second unwrapping of just these four faces it tries to fill the image area with it as best possible while minimizing the stretching. Since the image area is perfectly square and so are our combined 4 faces, they fit perfectly in the entire map.

You'll now see the entire Hedonism picture filling the area of the picture material because we've now remapped them to do so. The mind-bending part for a novice Blender user is that this in no way affects our existing UV map for all of the other faces. I won't show a picture of it here because it would look a little confusing, but try selecting the entire object again in the 3D view pane and then look closely at the UV map. The square we just cut out is now missing from the original map portion and is super-imposed on the entire image area, but all of the other faces on the map are unchanged.

This means our vertices around the outer edges of the image which belong to the picture material are also the same vertices as the ones outlining the hold we cut into our original map and belong to the brick material -- they're in two places at once! Although confusing, this doesn't cause any issues at all and is not at all uncommon to see on some UV maps where you're mixing multiple materials on the same map and maximizing the resolution and ability to seamlessly scale textures on their surfaces. Here's what our box looks like in world after this remapping.

I should point out that this overlapping UV practice is generally discouraged for "real" Blender artists where there are none of the constraints we face with mesh uploads for SL/Opensim. For render output directly from Blender they would normally prefer to keep their maps much cleaner (for ease of editing) and approach this sort of thing in a different way that works perfectly in Blender but would result in a fairly horrible appearance if uploaded in-world.

The important point to take from this exercise is how little Blender cares about the relationship between the shape of the mesh and the way it's UV mapped. The Opensim viewer shares that feeling. All they really care about is that each Blender-face has a valid UV mapping assignment. You could, in fact, individually map all 96 faces of our box separately even if they were all assigned to the same material. In Blender, you could even create 96 different materials and make each face of the mesh into a unique one. For upload in-world, you're limited to 8.

Although I'd hoped to show a little bit about unwrapping a couple other objects (a cylinder and sphere) in this part of the tutorial, I realize that it's already getting pretty lengthy so let's leave that until Part IV and end this one with one more, different, approach to unwrapping our box just to show you another aspect of even a simple object's unwrapping.

Use the tab hotkey to switch to Object mode and delete the picture material (using the "-" sign). Notice that even though we've deleted that material, the mapping hasn't been lost and your brick texture will appear on the surface of the entire box looking like it does on the left-hand box in my in-world picture. Now tab back into Edit mode.

Deselect all and switch to edge selection mode, then select the 6 box side edges that you haven't already marked with seams and then mark them

Now select all and unwrap the entire box again using the same unwrap method we've been using for all of our previous unwrapping. Now look at the results in your UV/Image editor pane (you'll want to switch back to displaying the brick texture here since that's the one being used by our material). You may also want do select none with the mouse pointer in this pane, then switch to island selection mode so you can click on each one individually to see it a little more clearly. You can also select one side of the box in the 3D Image pane to see its corresponding location on the UV map.

This is quite a marked different mapping of a box and is extremely common for Blender artists. It's also an approach you would typically take if you're making a single custom texture to go on the object instead of using multiple in-world textures or tiling seamless textures.

When you isolate part of a mesh by marking seams around it, Blender approaches its "unwrap" method of unwrapping it a little differently. Each part of the mesh that has been separated from the rest by being enclosed by seams is now unwrapped and optimized separately. Then once all pieces are done, Blender scales them all to match one another and then arranges them to try to best fit them in the overall available space of the image area of the map. This will often result in individual pieces being rotated in unexpected ways and (as far as I can tell) there's a very convoluted logic in the positioning and rotation of the individual pieces.

You'll often find that if you unwrap the same (complex) object several times in a row, it might arrange them a little differently. Further, immediately after unwrapping you can change the Method in the Most Recent Action section of the Toolshelf to see if there's any benefit to using the Conformal rather than Angle Based method. To be perfectly honest I'm not entirely clear on the difference between the two although my understanding is that it affects the logic Blender uses to determine the "least stretching" and "best arrangement" and "equal scaling" goals of the the Unwrap method.

All of this means that your result could easily be different than my picture above, and your result might even vary a little if you unwrap again. The maps will be "right" but the rotations and arrangements might be different.

As a part of your workflow, expect that you'll have to do some work on individual islands after unwrapping; moving and rotating them as necessary to get them into a useful arrangement for import in-world. Again, these are concerns that Blender artists don't have...they are working directly with it in Blender that issue simply doesn't exist for them.

I'll conclude this part of the tutorial by urging you to play around some more with the things we touched on in Part III. UV mapping and materials assignments are a critical part of what makes mesh so appealing to work with in-world but so difficult to master. There's an art to it that, quite frankly, has a long slow learning curve. I'm still learning new things or approaches with almost every new project I undertake.

In Part IV we'll shift our attention to things that aren't as nice and convenient a shape as a simple box. Brace yourselves, it gets even more entertaining...

No comments:

Post a Comment