Sign in to follow this  

Multiple Textures - One Level Mesh

This topic is 3295 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, and thank you for stopping by! I'm having a small design issue about rendering a single mesh with multiple textures. For a little background on what's going on, I'm designing a render engine for a game. The render engine contains all of the necessary information to render objects in the world: a texture list, a mesh list, a shader list, a lighting manager, and a "render object" list. A render object basically encapsulates render data, including a mesh ID, a texture ID, relevant shader IDs, and a transformation matrix. Everything's working pretty well so far, as I've been using a test level mesh with a single ground texture. Now need to render a single level mesh with multiple textures. I've been considering how to make this happen, and I'm concerned about performance. Right now, meshes consist of a list of unique vertices, polygonal indices, and texture coordinates. I've thought about adding an extra list on a 1:1 ratio with the vertices which also contain a texture ID to bind on a per-vertex basis, but this seems highly inefficient (both in memory and swapping textures constantly). To add to it, I'm going to need to optimize my smaller meshes into VBOs and my larger meshes into glMapBuffers, making the system more hacked. To keep things simple, I am rendering in immediate mode right now. Then, as if that's not enough, I have implemented shader-driven lighting. Ultimately, my texturing solution needs to be in a shader since the GL texture coordinate generation is disabled with the use of GLSL. This is a rather complex problem. Now that you have a little background on the issue, I can simplify it to two smaller questions: What is an efficient method of rendering multiple textures to one mesh and how can I extract this to GLSL? How does maya handle multiple textures on one mesh, and what is a good method of extracting the relevant texture data from it? If you have any example references, tutorials, suggestions, or ideas, they are all appreciated. Thank you!

Share this post


Link to post
Share on other sites
The trick is to assign a texture to a mesh and not to single vertices. If you do this, you have multiple options to realize this:

1) many textures - one texture coord set
This one is quite easy, just assign many textures to your mesh. In glsl you have to declare multiple sampler for each texture one. But beware, texture samplers are often limited by hardware (i.e. just 4 texture units). To access your texture, just use your mesh texture coords or any derived one.

2) many textures - many texture coord sets
This is the case if you want to have one or more standard textures assigned to your mesh (i.e. normal map, skin map) and i.e. a lower resolution lightmap with different texturecoords. In this case you have to assign more than one texture coords set to your mesh. Progress like 1) but access the texture with the according texture coord set.

3) many textures - simple way
Well, it could be easier to divide your mesh up according to its texture. I.e. if you want to use 3 texture divide your mesh into 3 sub-meshes. In this case you have to duplicate the according vertices. This approach is good if you want to handle different surface properties (i.e. different shaders) too, but it's quite weak if you need to do some blending with your textures.

In my engine I use a combination of all three approaches.

--
Ashaman

Share this post


Link to post
Share on other sites
The way that Max does it is that Faces have Materials assigned to them, a Material typically has a Diffuse Map, Bump Map, Normal Map etc (although doesn't require all and can have many others). Then when you are rendering your model, you loop through every face with Material 1, then you loop through every face requiring Material 2 etc.

This approach also means that you can assign different shaders etc to different Materials.

Share this post


Link to post
Share on other sites
These are both extremely helpful posts and greatly appreciated. Thank you very much!

Ashaman:
These are extremely good points! I don't know why I was thinking on a per-vertex level for the texture coordinates, this makes sense to me!

There are, however, a couple questions I have:
I understand using multiple samplers to render multiple textures to one mesh in one pass. However, you said that the hardware often limits the texture sampling? As I may be rendering very large meshes with potentially a dozen or more textures, I will need to support rendering as many textures as I'm given to one mesh. I looked in GLEE version 1.3.1, it supports up to 32 GL_TEXTURE units, so I immediately know that if (heaven forbid) I have more than 32 textures I will need to do multiple render passes. This does not, unfortunately, tell me my hardware limit. If I know my texture unit limit beforehand, I can simple modulate how many textures I have by how much my hardware will allow in one render pass, loop through the supported texture count in the shader, and do multiple render passes as needed. How can I get this limit? Even if I can, is looping in the shader bad design? Also, a lot of how to make this work comes from how Maya internally stores and exports texture coordinates, if anyone has any insight on this it'd be greatly appreciated.

The general concept I have right now is to make it such that a mesh has a texture count, a set of texture IDs, and an array of texture coordinates for each texture. Each ID corresponds to a texture that has been loaded. Each array of texture coordinates tells how to render each texture unit.

Thanks again for the replies, they have been extremely helpful!

Share this post


Link to post
Share on other sites
Quote:
Original post by SeiryuEnder
I understand using multiple samplers to render multiple textures to one mesh in one pass. However, you said that the hardware often limits the texture sampling? As I may be rendering very large meshes with potentially a dozen or more textures, I will need to support rendering as many textures as I'm given to one mesh. I looked in GLEE version 1.3.1, it supports up to 32 GL_TEXTURE units, so I immediately know that if (heaven forbid) I have more than 32 textures I will need to do multiple render passes. This does not, unfortunately, tell me my hardware limit. If I know my texture unit limit beforehand, I can simple modulate how many textures I have by how much my hardware will allow in one render pass, loop through the supported texture count in the shader, and do multiple render passes as needed. How can I get this limit?

Even if I can, is looping in the shader bad design? Also, a lot of how to make this work comes from how Maya internally stores and exports texture coordinates, if anyone has any insight on this it'd be greatly appreciated.

The general concept I have right now is to make it such that a mesh has a texture count, a set of texture IDs, and an array of texture coordinates for each texture. Each ID corresponds to a texture that has been loaded. Each array of texture coordinates tells how to render each texture unit.

Thanks again for the replies, they have been extremely helpful!

There are query commands to get the supported number of texture units, I will try to look them up when I'm home.
But the problem might be, that even highend gfx cards will not support 32. Most cards limit the number of different texture coods transfer between vertex and fragment shader too (i.e. limited to 8).

What is you goal, do you want to make a game or an application like maya ? Maya is not a game and its engine is supposed to render high quality images whereas a game is an realtime application with a major focus on performance. So, if maya supports all this features it might be a bad idea to clone this into a gameengine.

A little tip, dont try to couple texture coords with textures. It is possible, but quite inflexible. Just keep them separated and let the shader decide to access texture n with texture coords m.

There are several approaches to reduce the number of textures and texture coord sets:

- texture atlas:
Put many textures into one single texture. This works as long as you dont try to use repeating textures. So this might be a good idea for environment (think about a level where all door textures are put into a single door-texture-atlas) , characters, items (all weapon texturing put into one single texture).

- derived texture coords:
Think about a character with color and normal map. One option is to use two different textures or to use one texture (containing color/normal map) and two different texture coords.
But what about using just one texture and one texture coord set?
In this case just map your texture in the shader, i.e.:
new_color_x = x * 0.5;
new_color_y = y
new_normal_x = x * 0.5 + 0.5
new_normal_y = y

- terrain:
Well, terrain is quite difficult. There are many approaches to apply variant textures to a terrain. I.e. texture splatting or mega textures.

--
Ashaman

Share this post


Link to post
Share on other sites
You are right, I suppose I have been coupling textures and texture coords too much. There is functionality in the engine to change the texture associated to texture coordinates, with default textures loading from a file, but I do see what you mean.

There is a lot in this render engine that I feel needs to be revised so that it is more robust. Right now it's in a "get it working" stage, but it's definitely coming along.

I think I've got enough information to make this work now. I have to say, Ashaman, you've really been a huge help. I can't thank you enough.

Share this post


Link to post
Share on other sites

This topic is 3295 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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