Sign in to follow this  
RobMaddison

Blending 3 textures across a triangle

Recommended Posts

RobMaddison    1151
Is it possible to render a triangle with a blended texture at each vertex (like you can with colours) without using an alpha mask? It feels like it should be a simple thing to do but I can't seem to grasp how it's done with shaders in once pass (ps/vs_3_0). I would like to just store a texture id at each vertex and then do the texture lookup in the pixel shader. For that to happen in the pixel shader, I'd need to be passed the interpolated uv coordinates of the textures (we'll assume for this excercise that all three textures are the same size and so only pass one set), the id of each texture (so I can perform a lookup into an atlas or whatever) and how much of each texture needs to be added at that point. I guess this could be achieved by passing a 24 bit colour register, using each value as the blend alpha for each texture - e.g. blue for one vertex of the triangle, green for another and red for the third. The problem with this is that it's for a grid of quads with shared vertices, so blue for one vertex may need to be red for the same vertex in neighbouring triangles. Has anyone done this before? Thanks

Share this post


Link to post
Share on other sites
Darg    213
I think what you want to do is use multitexturing.

The way I have my terrain set up I have 2048x2048 points. Each of these points stores the vertex location, it's uv, it's normal and it's texture weight.

The texture weight is read in from an image file where I use the following:

Red - Sand
Green - Path
Blue - Mud
Alpha - Rock
Remainder (black) - Grass

When I go to draw it I pass through these values, position, uv, normal and texture weights (float4) in one structure and pick those up in the vertex shader and pass them through to the pixel shader.

Then in the pixel shader if the value for any of the diffuse textures is greater then 0 I sample the appropriate texture and multiply it by the correct amount. I then add all these together to get the right colour for that pixel.

So if you have a float4 of (0.2, 0.1, 0.1, 0.2) you'd have the following:

Sand Sample * 0.2
Path Sample * 0.1
Mud Sample * 0.1
Rock Sample * 0.2
Grass Sample * 0.4 (remainder)

I'm afraid I don't have the code with me atm to show you exactly how I do it but hopefully you can see it from that.

Share this post


Link to post
Share on other sites
RobMaddison    1151
Thanks, Darg. I have previously implemented that method of multi-texturing but it takes up too much memory for my requirements and the texture count is a bit limited. Also, if you're using shaders, you don't need to store all that info with the vertex as it can take up too much memory (especially at 4096x4096) - at the moment, my vertex definition is simply a 16bit vertex texture which stores the height at each point - everything else is calculated in the shader - easy if it's a regular grid.

My current method of blending uses indirect texture lookups and tiled atlas blendmaps which works really well and allows you to have any number of textures per patch but still takes up more memory than I'd like. I'm trying to streamline it even further now and my current idea is to just store an 8bit material (texture) index with the vertex. Then you can simply blend the texture into the corners of each triangle and use patterns in the underlying base texture to supply the main colour of the texture (that way you can give the impression that blending is at a finer granularity than what it actually is - at triangle level).

My question is if you have a texture id per vertex, how do you pass the correct information to the pixel shader in order to blend the textures? I think this would probably be fairly straight forward with one single triangle as you can just store a colour with each vertex in order to get the correct interpolated blend, but when you have multiple triangles sharing the same vertices, that won't work.

The information I need in the pixel shader is:

a) for this exerise, one set of interpolated UV coordinates

b) 3 texture ids - one for each of the vertices involved in the triangle being processed. If any of the ids are zero, the texture used will be the base texture (which is at a much lower resolution). These ids are obviously not interpolated.

c) an interpolated RGB value (or 3 seperate values) pertaining to the blends required for each texture.

Once in the pixel shader, I use each texture Id as an index into an atlas, grab the sample at the correct coordinates (using the interpolated UV coords passed in from the VS) and do an additive blend on each sample to produce the final colour.

Am I missing the trick with the data that gets sent to vertex shaders? I thought they operated on a triangle-by-triangle basis.

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