Sign in to follow this  

Mapping a 2^n texture to a 2^n+1 terrain

This topic is 3299 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 there! I have a randomly generated terrain with a resolution of 2^n+1 square (requirement both for the Diamond-Square algorithm used for creating the basic heightmap and for some gameplay elements). The terrain takes the randomly generated heightmap and turns it into a grid of vertices, including position, normal, tangent, bitangent and UV-coordinates for texture mapping. Now, I generated some textures for that terrain, too: A normal map calculated based on a higher res heightmap and a blend map, used for splatting textures on the terrain, also based on a higher res heightmap. My current implementation generates textures that also have a size of 2^n+1 square. I think current graphics card shouldn't have a problem with that, but it just feels a bit odd to have 513x513 textures around, so I thought about creating 2^n textures for my terrain. The problem I've ran into is two-fold: a) Let's say I have a heightmap with a resolution of 513x513. My current implementation would create a 2049x2049 heightmap based on the low-res one and generate matching textures, making sampling the values for the texture straight-forward (each value of the high-res map maps straight to one pixel of each texture). Now, the high-res heightmap has to have a size of 2^n+1, how would I sample the values for a 2^n texture based on that height map? I thought about doing steps over the high-res map of the size 2^n / (2^n + 1), instead of 1, and using bilinear interpolation to get a value that represents the value of the heightmap at the current position, but this could get rather expensive. So, any other, simpler ideas would be appreciated. b) How would I have to adjust the UV-coordinates of the terrain's vertices so that the textures are still mapped correctly? Would I have to adjust them at all?

Share this post


Link to post
Share on other sites
The solution is quite easy: you don't need to map it at all :)

The reason is, that your heightmap and your texture represents different properties of your terrain:
The heightmap represents vertices of your terrain, whereas the texture represents the color of a face(quad) of your terrain, so you need (n+1)x(n+1) vertices (=heightmap) to define (n)x(n) quads (=texture).

Example:
Heightmap 3x3, texture 2x2
vertex texture coord
0,0 0,0
1,0 0.5,0
2,0 1,0
0,1 0,0.5
...

x_textureCoord(v) = v / heightmap_width
y_textureCoord(v) = v / heightmap_height

--
Ashaman

Share this post


Link to post
Share on other sites
a) (2^n+1) x (2^n+1) heightmap contains 2^n x 2^n 'cells' that can be mapped to the texture directly - the last value doesn't get 'lost' because it's also the first one in neighbor square

b) you don't need to adjust - edges of the texture lie on the outer edges of mesh

Share this post


Link to post
Share on other sites
What i do in case of (e.g.) a normalmap with dimensions 2^N which keeps per-vertex normals for a 2^N + 1 heightmap is to ignore the last column and row of the heightmap. That way, you can map texels to vertices directly by using

texel_xy = vertex_xy % (2^N)

and the last column and row of the heightmap would get the same values as the first row and col. It's not correct but normally you shouldn't be able get the camera that close to the terain edges, so it's not actually a problem.

For texture coordinates you can use

vertex_uv = (texel_xy + 0.5) / (2^N - 1)

Hope that helps (and i haven't done any mistakes).

HellRaiZer

Share this post


Link to post
Share on other sites
thx all for your replies.

@cameni and Ashaman:
You're right, a heightmap of size (2^n+1)² will turn into a terrain with (2^n)² quads.


The problem is: I want to calculate the textures based on the terrain, too. Currently, as I said, I simply generate a higher resolution heightmap and evaluate the vertices of the resulting terrains directly. Simple, but it results in a (2^n+1)² texture.
If I want to sample the quads of the higher res terrain for my textures, I'd have to interpolate between the vertices of the terrain, right?
I've thought about that again, and to me, there's no way around interpolating between vertices if I want the texture resolution to be different from the heightmap resolution (except of course HellRaiZer's probably very feasible suggestion of ignoring the last row and column of vertices).

But your hint with the quads combined with HellRaiZer's UV calculation actually was a bit of a eye-opener... I was thinking about mapping the whole 2^n of the textures to the whole 2^n+1 of the heightmap, which would have resulted in pretty ugly mappings. Your tips reminded me that UV-coordinates of (0,0) don't actually correspond to the center of the top-left pixel, but to the top-left corner of it. So, mapping quads to pixels is actually more accurate and simple than I had originally thought, since I only need to sample the center of each quad (which actually corresponds to the center of the pixel) of my high-res terrain and that's that.

Thanks again!

Share this post


Link to post
Share on other sites

This topic is 3299 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