Smoothing terrain heights

Started by
6 comments, last by JohnnyCode 8 years, 6 months ago
My terrain uses a vertex texture for heights. Because my world texture needs to be 8192x8192, I stream the terrain during normal play which works nicely. At design time, my terrain editing tools allow the user to make very large changes (like raising/lowering) across the entire terrain which means the whole full 8192 x 8192 vertex texture needs to be in the GPU's memory. For raising/lowering, I use a shader which just does an additive vlend to the existing vertex texture but for smoothing, I need to average the surrounding heights which means I need to pass a copy of the vertex texture in when editing in order to access the heights.

Is there a way I can do height smoothing without supplying another 8192x8192x4bytes texture? I'm getting to the limits of GPU memory in my game editor as I also have other 8192 textures loaded like the global normal map (I can't stream this because I'd like to see far away detail - it's a mountain scape). I'm using a geomipmapped terrain so I can't create the normals in the shader as the detail far away would be very lo-res. having lo-res triangles coupled with a hi-res normal map actually makes it look very smooth at distances.
Advertisement

If youre smoothing using gaussian blur, I know you can separate it to vertical and horizontal pass. And for those, you could do one row/column of pixels at a time (so only need to copy that slice of pixels).

So say for the horizontal blur, maybe you first do the top half and then bottom half. Then you only need 8k*4k temporary texture instead of 8k*8k (all the way to 8k*1 if memory is scarce)

This needs ability to read/write to same texture, dont know how well that is supported (I assume at least newer APIs can do something like that)

o3o

I'm using dirextx9 which I think means I can't read from the texture I'm writing to in the same pass

No wait I dont think you need to be able to do that, just copy slice of texture to the temporary, then blur it on one axis (assuming you do separable gaussian blur) writing output to the original...

o3o

No wait I dont think you need to be able to do that, just copy slice of texture to the temporary, then blur it on one axis (assuming you do separable gaussian blur) writing output to the original...


By copy do you mean use GetRenderTargetData? I thought that might be incredibly slow on such a big texture as it'll need to copy the whole surface to system mem in order to lock a small part of it?


By copy do you mean use GetRenderTargetData? I thought that might be incredibly slow on such a big texture as it'll need to copy the whole surface to system mem in order to lock a small part of it?

It doesn't need to leave the GPU. Just use the temporary as a render target and draw the portion of the heightmap texture onto it.

By copy do you mean use GetRenderTargetData? I thought that might be incredibly slow on such a big texture as it'll need to copy the whole surface to system mem in order to lock a small part of it?


It doesn't need to leave the GPU. Just use the temporary as a render target and draw the portion of the heightmap texture onto it.

I was hoping to not have to go the route of copying specific areas out of the texture as it could get a bit fiddly, but this seems like the only option.

Thanks both


I was hoping to not have to go the route of copying specific areas out of the texture as it could get a bit fiddly, but this seems like the only option.

Maybe a more atomic texture then 8K and elements management would be more appropriate- it would partialy also solve the problem you have, and allow this game exist on more general gpu's as well.

This topic is closed to new replies.

Advertisement