Sign in to follow this  
Squirm

Texturing arbitrary surfaces

Recommended Posts

When a procedurally generated heightmap landscape is rendered, it can be easily textured, despite the fact that the exact shape is unknown at the time the texture is drawn, because each vertex maps neatly onto a 2D coordinate without much stretching. When the surface is no longer a heightmap, and contains overhangs and cliffs and caves, the stretching is terrible. This is a very old example, with textures mapped to X/Z and the stretching very noticeable on near-vertical faces. It's rather old, but it shows the problem. Image Hosted by ImageShack.us Now, a couple of years ago I asked around and thought about it and couldn't come up with anything better than 3 textures, each rendered perpendicular to a separate axis. It works, kind of, but still gives nasty stretched bits. Add a desire to do detail textures and alpha tricks and things, and suddenly you need a ridiculous number of rendering passes aswell. Can anyone think of any cute tricks I could play to texture something like that? [edit - smaller friendlier image] [Edited by - Squirm on November 30, 2004 7:33:55 AM]

Share this post


Link to post
Share on other sites
Hmm, I need to think about this more, but I would approach it as trying to maintain a constant texel density over every face in the mesh. This density would be given by the area of the face in u,v space divided by the area in x,y,z space. In order to make sure the texture isn't streched in either axis, we'll actually want to consider the ratio of the length of each edge of the face in x,y,z to the length of that same edge in u,v.

The trick is to adjust the u,v coords of each vertex to obtain the proper density, without disturbing the adjacent faces.

To begin with lets assume the texture will be tiled to give us an infinate texture space to work in. If we started with a single face, it should be easy to adjust the u,v coords to give the desired edge ratios for the texel density we want. Then for each adjacent face that shares an edge with the first face we only need to find u,v coords for the third vertex of that face. (The shared edge should be of the same length for both faces so the existing u,v coords used for the first face will work for the second.) We can continue to preform this operation on each face sharing an edge with a processed face. Eventually for a closed surface we would come to faces that have all three edges shared with existing faces, but since the edge lengths are the same the ratios should already be correct.

If you don't want the texture to tile you could take the min and max u,v values and scale all of the u,v coords down into the range you want (0,1).

Anyone see any problems with that?

Share this post


Link to post
Share on other sites
Unfortunately, yes - the texture would tear - when you worked your way along a bunch of edges and got to a triangle you had been to before, the textures would be very unlikely to line up.

There is a guaranteed solution using a 3D texture, but the last I heard these were very slow and had no hardware support?

It also occurred to me recently that I could use 3 textures as before, and set the alpha of each vertex according to its normal, so that it is mostly the texture which is in the best orientation for it. The stretched textures would be barely visible this way.

I'm not sure how expensive it is to specify a different material for each vertex. I'm also not sure how to do it without needing 3 separate rendering passes, instead of 1 pass with 3 textures :/

[Edited by - Squirm on November 30, 2004 5:33:50 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this