Multiple textures

Started by
9 comments, last by Kalidor 18 years, 2 months ago
Lets say the on a certain vertex I want to be textured with 50% tex1, 30% tex2 and 20% tex3. How can I do it without the multitexture extention? Thanks.
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the internet, we know this is not true." -- Professor Robert Silensky
Advertisement
One approach would be procedural texturing.
If the application is a terrain, then the particular approach I took was to create a base image (array of RGB data) which I will create an OpenGL texture object from and stretch that across the mesh. Before I create the texture though I run through the image and for every pixel of the image I find the corresponding height on the mesh (might require interpolation if your image width and height is larger than your mesh - which is the case most times). With the height I can then determine the percentages of particular textures (sand, grass, rock etc) I want at that pixel, and color the pixel accordingly. I also factor in the slope (degree from horizontal) to factor in more texture types (rock). Since this is all done at startup you do not take a performance hit when rendering because you are not having to calculate this all the time - just once. I took my method from a book called Focus on 3D terrain programming, by Trent Polak. Very useful book btw if you are inquiring about terrains.

Here is a sample of this used on a terrain.

This approach is very much terrain specific though, butI hope it was helpful.

F451
The only way without multi-texturing is multi pass.
Render your object 3 times each time set it's color to the precentage of the texture.
Another question related.
Let say I have a triangle and I want something like;

vertex 1 - 70% tex1 : 20% tex2
vertex 2 - 35% tex1 : 40% tex2
vertex 3 - 20% tex1 : 65% tex2

How do I do that WITH multitexturing?
You can do it with rendering the object three times and adjust the alpha value of the texture each time and then let the textures blend.

Here is how it could work

for (int i=0;i<MAXTEXTURES;i++)
{
Activate texture i
glcolor4f(r,g,b,AlphaOfVertex1); //set alpha
glVertex1
glcolor4f(r,g,b,AlphaOfVertex2); //set alpha
glVertex2
glcolor4f(r,g,b,AlphaOfVertex3); //set alpha
glVertex3
}

______________________________ohh well what the heck lets try it?
so it cant be done with one pass, even with multitexturing??
Then I wonder, what's the use of it anyway, since all cool effects can as easily be created by photoshop in one texture, and then just rendered once.
Quote:Original post by Kincaid
so it cant be done with one pass, even with multitexturing??
Then I wonder, what's the use of it anyway, since all cool effects can as easily be created by photoshop in one texture, and then just rendered once.


what if you wanted to do something like lightmapping? Say your scene only uses 4 diffuse textures. If you had to photoshop the lightmaps onto the textures themselves then you'd have to use alot more texture memory.

And dweebs example should work with multitexturing.

edit: or maybe it wouldn't work. I don't know, my brains not working tonight.
Quote:Original post by Kincaid
so it cant be done with one pass, even with multitexturing??

It can be done with multitexturing in one pass, its what multitexturing is about.
You have to use ARBMultitexture extension, for example:
ARBMultitexture.GL_TEXTURE0_ARB ---> modulate (rgb info of whole terrain)
ARBMultitexture.GL_TEXTURE1_ARB ---> alpha texture
ARBMultitexture.GL_TEXTURE2_ARB ---> grass, GL_INTERPOLATE_EXT
ARBMultitexture.GL_TEXTURE3_ARB ---> mud

I can't see how to do this easily with multitexturing (i.e. without fragment program / shaders etc).

It may be possible with register combiner extensions, but I can't see how.

The difficulty is setting the weights for each material on each vertex.

With only two different textures, it can be achieved easily enough, I think - by using the fragment primary colour as the "switch" to switch the secondary texture on/off (or blend in different colours).

But because there is only one primary colour which can be set between begin/end, I cannot see how you'd do it with more than two different textures.

It's possible that with a shader you could use the different components of the primary colour (r,g,b,a) to control the opacity of different texture layers. This can probably be done on some shader model or fragment program.

---
A clever person might be able to sus out how to achieve this using the standard combiner extension (GL_ARB_texture_env_combine). I can't :)

Mark
Quote:Original post by markr
I can't see how to do this easily with multitexturing (i.e. without fragment program / shaders etc).

Me either. Blending multiple textures is virtually impossible on older hardware without multiple passes (apparently you can use the register combiners, but I've heard it's more trouble than it's worth).

Quote:
It may be possible with register combiner extensions, but I can't see how.

As you mentioned...

Quote:
The difficulty is setting the weights for each material on each vertex.

The pixel/fragment colour (which you mentioned after this) would work fine.

Quote:
With only two different textures, it can be achieved easily enough, I think - by using the fragment primary colour as the "switch" to switch the secondary texture on/off (or blend in different colours).

I'm not quite sure what you were going on about here, so I'll assume it was the fragment colour as defined by the blending between the vertices. If you're only using 2 textures, you can just use the alpha channel to set the texture weights, and use the colours to actually modify the final colour.

Quote:
But because there is only one primary colour which can be set between begin/end, I cannot see how you'd do it with more than two different textures.

Actually, the colours are set by vertices, not the entire object. There's a lot of things you can't do (change textures for instance) between vertices, but you can change the colours.

Quote:
It's possible that with a shader you could use the different components of the primary colour (r,g,b,a) to control the opacity of different texture layers. This can probably be done on some shader model or fragment program.

Pixel/Fragment shaders could do this fairly easily, just as you said. This still leaves you with 4 textures to work with, which should be more than sufficient for a lot of things (if not everything).

Quote:
A clever person might be able to sus out how to achieve this using the standard combiner extension (GL_ARB_texture_env_combine). I can't :)

I spent a few days trying to figure this one out only to realise that once I actually worked all of the formulas they give you to work with through, it's completely useless for doing this type of thing.

Multiple passes or pixel/fragment shaders would be the way to go. You can always try the register combiners, but it'd be easier to implement the multiple passes or shaders. If you're not aiming for older hardware, scrap the multiple passes and go for the shaders, since it's easier to do than the multiple passes, and you'll still end up with the same result (although chances are it'd run faster too, since you're not re-rendering objects).

[EDIT]
I almost forgot. It is possible to do this with texture combiners if you have access to 4 texture units, but if you only have access to 2 (like me), it's impossible (unless you want to generate the alpha textures and add them to the textures manually at runtime, which isn't the best idea). You'll still have to generate the alpha textures though, but you'll be able to replace the alpha values in the other textures with the ones in your generated textures and blend the resulting textures. Only problem with this is you can still only blend 2 textures together, and since your videocard already supports 4, there's a good chance it supports pixel/fragment shaders too. In any case, the choice is yours.

This topic is closed to new replies.

Advertisement