Skip to main content
GameDev.net gamedev.net
🔒 Locked

Tiled Terrain Rendering

Started by zellix Jun 8, 2010 at 1:16 AM 6 replies 1.7k views
Original Post
zellix
zellix
Hello. This is my first time posting here, so I hope this is the correct forum.

My game is using a heightmap setup for terrain rendering. Each tile has a specific tile type which I am hoping can be 32+ different type. Now I have looked around extensively for ways to smooth the textures on each tiles border, but my problem may be a little different. I did a quick mock up of what I am attempting to do.
http://i49.tinypic.com/1zwgsx2.png
I am hoping each of those tiles could be just 1 quad (2 triangles) and I would be able to bleed the tile next to it on to each tile. I have looked at splatting etc, but it is on a per vertex basis and since I have 4 different possible textures bleeding onto the texture in the middle I don't think a simple alpha method would work. Definitely could be wrong, which is why I am posting this.

The game is based off these tiles, and each tile can be interacted with, so it isn't just purely for looks, which is why I need the actual quad to be the tile type texture, and not just the vertex. So the question is, which would be the best method to achieve the desired effect in my mock up image?
Hodgman
Hodgman
Quote:
Original post by zellix
since I have 4 different possible textures bleeding onto the texture in the middle I don't think a simple alpha method would work
You can pack 4 alpha values into the RGBA vertex colours ;)
zellix
zellix
Thanks for the response. Interesting, I will have to look into that. But off the top of my head, wouldn't this still cause the problem of having the main texture not being the only texture in the middle of the quad? For example, if I have a grass quad surrounded by 4 dirt quads, each vertex would have 50% alpha of both textures, wouldn't that texture the whole quad a 50/50 of grass and dirt?

Here is a mock up of what it should like like with 4 dirt around a grass quad.
http://i48.tinypic.com/2uqnabs.png
Ignifex
Ignifex
Just divide each tile in 4 then, setting the center to 100% grass and the sides to 50/50. :)
shultays
shultays
this will be probably bad an idea but I think it would work. I am not that experienced with shaders and their performance

lets say you have you have 4 textures, give each of them a id, 0 1 2 3. each vertex will need a 2 components for storing texture id and one for weight distrubiton between textures. for triangles, every vertex must have same texture ids but weights will be different. you will pass those to pixel shader, since ids are same they will not be interpolated but weight will be.

in pixel shader you will do something like that

if( id1 < 0.5)
fetch texture1 and store in color1
else if( id1 < 1.5)
fetch texture2 and store in color1
else if( id1 < 2.5)
fetch texture3 and store in color1
else
fetch texture4 and store in color1

same will go for id2. once you do a fetch operation for both textures you will interpolate two color

return lerp(color1, color2, weight)

again, I never tried this and not sure how well it will work or if it will work at all
taytay
Hodgman
Hodgman
Yeah, along the lines of what Ignifex said, you could make your mesh look like this, where the vertex at 1 has 100% grass weighting, the verts at 2, 3, 4, 5 have 50% grass and 50% dirt, and the other verts are 100% dirt
      +-----+      |\   /|      | \ / |      |  x  |      | / \ |      |/   \|+-----+2----+3----+         +--+--+|\   /|\   /|\   /|         |\ | /|| \ / | \ / | \ / |         | \|/ ||  x  |  x1 |  x  |     OR: +--x--+| / \ | / \ | / \ |         | /|\ ||/   \|/   \|/   \|         |/ | \|+-----+5----+4----+         +--+--+      |\   /|      | \ / |      |  x  |      | / \ |      |/   \|      +-----+
Quote:
Original post by shultays
every vertex must have same texture ids but weights will be different.
Seeing the texture IDs don't change, you'd just use uniform samplers as usual (instead of per-vertex IDs). You can move those if statements to the CPU, as "if x fetch a, else fetch b" doesn't perform well in a shader. A lot of GPUs will have to calculate the if part *and* the else part, then once it has both results it will use some math to select the right one (e.g. lerp( else-result, if-result, condition )).

//if the weights aren't normalised (adding up to 1.0) you can do:weights /= dot( weights, float4(1,1,1,1) );//then multiply each texture by it's weighting (4-way lerp)color = fetch tex1 * weights.r +         fetch tex2 * weights.g +         fetch tex3 * weights.b +         fetch tex4 * weights.a;
zellix
zellix
Doing it the alpha way, wouldn't I need to re-render every triangle for each texture used? If so, would using the GLSL method be able to eliminate it, and achieve it in one pass?
Hodgman
Hodgman
With shaders (GLSL) you can do it in one pass by sampling all 4 textures and multiplying the weights (alpha values).

Without shaders, you could also do it in one pass by using multi-texturing and correctly configuring the 'texture environment' to do the right multiplications.

You could also do a multi-pass method where you render one pass per texture (without multi-texturing or GLSL).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.