Thursday, 20 August 2009

3D Texturing

Texturing in 3D is a pesky thing, images are 2D and 3D meshes are obviously 3D! Furthermore 2D images are always rectangular. There are two main ways of texturing a 3D object, neither of them great when you just want a quick seamless texturing job...

1. Simple mapping
For example cube mapping. For these the texture is projected onto the mesh according to very simple rules, for cube mapping this is simply if a face is pointing in the direction of one side of a cube then it gets its texture from that cube face. Mapping in this way has problems of distortion, for example if you try and use cube mapping on a sphere then you get problems of distortion near the cube corners. The texture also has to tile at each edge (ie. top to bottom, top to top, top to side, side to side, etc.) to prevent seams. Other mapping methods which avoid seams (eg. sphere or cylinder) tend to cause more distortion. This mapping is, however, dead easy to do and good procedural texures can reduce tiling problems.

Sphere mapping:

Cube mapping:

2. UV mapping
Here the 3D object is unwrapped to a 2D shape, think about flattening a cardboard box to its net. This can eliminate distortion (just make sure the unwrapping is good and doesn't change the shape of any faces). The big problem is tiling; a face on the 2D image may be isolated from its neighbours in 3D, it is hard to make a texture which links these edges with no errors... Making a logical UV unwrap for a texture artist to work with is very time consuming.

This is where I stepped in! I have been working on a way to let you do 3D texturing on any UV unwrapped model.

3D Texturing
All real life objects are "3D textured", ie. the texture could be calculated for any point in 3D space. Imagine cutting a plank of wood in half to reveal a new face; you reveal a new part of the 3D texture, some new grain, which (obviously) perfectly tiles with the sides around it. It is simple to use procedural textures to make a full 3D texture on a computer, you just need a way to transfer the correct information to the correct object faces of a 3D model.

The Method:
In blender:
1. Take the object you want to texture
2. UV unwrap it (while this method takes care of all distortion it is still best to make sure there are no really tiny faces)
3. Give the object the 3Dtexturingtool texture (this encodes the x,y,z location of every point on every face to a specific RGB colour)
4. Bake the object texture to the UV unwrapped image
OR
3/4. Bake the displacement data

In ImageJ
5. Open the image encoding the x,y,z locations
6. Run a macro which calculates the value of a 3D texture at each x,y,z location and writes that to the imageIn blender
7. Assign the new texture image to the object

This allows 100% tiling 100% distortion free texturing of an object, so far I have only written an ImageJ macro for assigning 3D perlin noise, but it works beautifully!The Limitations
This is limited to a 256x256x256 voxel texture (each r, g and b, so x, y and z, can only take a value of 0-255), so large images or detailed textures will become voxelated. There are ways around this (eg. encoding the x, y and z directions separately using all r,g,b colours for each direction in more detail), but these are significantly more hassle because you would have to bake the texture 3 times per object. I might do this if I ever need more detail!
It is also (currently) cringingly slow... This is because I don't know how to program efficiently and because it uses a macro, not even a proper script. It would probably be over 1000 times faster if you actually programmed it properly!
It is also (currently) useless because you can do this all with blender anyway, however it gives easy access to the tools needed to generate more interesting procedural textures outside of blender; I have planets and asteroids in mind!

Software Used:

ImageJ - Image generation

Blender - 3D modelling, texturing and rendering

No comments:

Post a Comment