Texture format for heightmap brushes

Started by
4 comments, last by TheUnnamable 10 years, 2 months ago

I'm writing a framework which makes it easier for my team to implement procedural terrain generation algorithms. The output would be a nice random-generated heightmap. The basic idea is to share work between the CPU and the GPU, so I've written a texture class which can be used for primitives, drawn onto ( GPU ), and written/read pixel by pixel ( CPU ). I upload/download texture data to/from GPU when needed.

We're targeting DX9-compatible hardware.

When deciding about texture format, I settled for GL_LUMINANCE + GL_FLOAT, since I need only one channel for the height. Later I wanted to add brush support, so I switched to GL_LUMINANCE_ALPHA. I started changing my framework so that it uses the highest available precision ( so GL_FLOAT is more like a hint, no more a requirement ).

I did some empirical research about GL_LUMINANCE_ALPHA's support and realized that it's by far not optimal. On my NVIDIA GeForce 710M it's supported, but drawing it is ridiculously slow. My integrated Intel HD 3000 lacks support for both GL_LUMINANCE and GL_LUMINANCE_ALPHA.

Looking for a more supported replacement, I've noticed GL_RG, which has two components too, but by default doesn't expand the way I need it. I've checked texture swizzling, but it hangs around only since ~2008, which is not optimal for me.

I could expand my data to GL_RGBA which has the most chance to be supported but that way I have two unused channels.

Or I could have two separate GL_R textures, one for the height and one for the alpha. That seems valid, too, but I have to draw everything twice.

I'd appreciate any input on my plans, what method should I use, how much compatibility should I expect, etc.

tl;dr: GL_LUMINANCE_ALPHA not supported, need an alternative that can be used on DX9-compatible GPU's.

Advertisement

What are you using the alpha component for? You said brush support, but I'm not clear on what you mean. Also, GL_LUMINANCE_ALPHA is pretty crappy - GL_R16/GL_RG16 is a much better choice.

incidentally, according to the latest steam hardware survey, DX10 & better account for 96.44% of GPUs in use - maybe looking at DX10 level hardware would be an option.

You can imagine brushes like stamps. A heightmap with an alpha map, for example a hill brush, which has a heightmap of a hill stored, with alpha fading out on the sides. Take a few variations and you can draw a mountain with brushes quite fast utilizing the GPU.

GL_R16 and GL_RG16 are indeed much better choices. Firstly, I use symbolic types, because the precision might vary ( if it's supported use floats, if not use uints, if not use ushorts, etc. ). Secondly, GL_R is absolutely fine for heightmaps. However it lacks alpha. GL_RG has two channels, which is great since it's faster and actually supported compared to GL_LUMINANCE_ALPHA, but GL_RG doesn't have an alpha channel.

Thanks for your input smile.png Sorry for being stubborn, but I'm sticking with DX9-level stuff.

Edit: I'm actually thinking about using two textures, one for height one for alpha. Architecturally it wouldn't complicate things much. That way I could stick with GL_R, and really really hope that the draw count won't be an issue in this case. Still waiting for any inputs tho', there's always a possibility that someone smarter can come up with more elegant stuff :D

All you need to do is multiply R by G, which is functionally equivalent to luminance * alpha, then store R.


I've checked texture swizzling, but it hangs around only since ~2008, which is not optimal for me.

That swizzling is a texture attribute. Samplers in shader scripts can swizzle by their own.

As mark has mentioned above, the only speciality of the alpha channel is that it is set to 1.0 (instead of 0.0) if not present in a texture. Hence there is no reason why not to use the green channel values as an alpha.


You can imagine brushes like stamps. A heightmap with an alpha map, for example a hill brush, which has a heightmap of a hill stored, with alpha fading out on the sides. Take a few variations and you can draw a mountain with brushes quite fast utilizing the GPU.

Could you please explain why you need 2 channels: If colorizing you need to distinguish between black and transparent, hence you need another value like alpha. But for a height map a height value of 0 means just an unaltered height. Perhaps you use it as the map made by the terrain designer to weight a re-useable height brush, but in that case it seems me that the height brush and the map are 2 distinct textures anyway.


That swizzling is a texture attribute. Samplers in shader scripts can swizzle by their own.



As mark has mentioned above, the only speciality of the alpha channel is that it is set to 1.0 (instead of 0.0) if not present in a texture. Hence there is no reason why not to use the green channel values as an alpha.
Seems like shaders are inevitable then, so I'll go with that. Thanks :)

This topic is closed to new replies.

Advertisement