Preferred Method for Texture Blending in Shader ?
#1 Members - Reputation: 343
Posted 05 August 2012 - 02:44 PM
Because I reuse the geometry for each tile I am unable to pass texture weights through the vertex buffer so intend to pass a Texture2D containing blend weights in the RGB channels, and do the blending using these weights in the pixel shader. However since there are only three (four if you count A) channels available to blend more than 3 textures I would end up passing multiple texture blend maps to the shader which seems very profligate.
What general approach is used to do this ?
1) Assign weights according to each color channel (do I really need 8bits of precision for a texture weight ?)
2) Manipulate the 24bits of color on the blend map as discrete 2bit chunks to fit a lower precision but handle 12 possible texture combinations ?
3) Use some other method, possibly using Hardware Instancing to pass the fixed geometry plus a second VertexBuffer of the texture weights down to a single shader as a 'combined' vertex buffer ?
If the recommendation is (3) is this the route I should use instead of using a heightmap in my Shader as well ?
Thanks in advance for your advice.
#2 Members - Reputation: 1672
Posted 07 August 2012 - 09:34 AM
I'd steer away from the 2bit blending, as that's not going to give you any kind of smooth transitions.
#3 Moderators - Reputation: 13569
Posted 07 August 2012 - 09:44 AM
You should count A. There's no 24-bit GPU texture formats.four if you count A
It's not mentioned in your post whether you're going to sample this weight texture in the pixel or vertex shader, so in case you've not considered it -- you can perform the fetch in the vertex shader, and it's almost equivalent to having the weights as part of the vertex stream.I am unable to pass texture weights through the vertex buffer so intend to pass a Texture2D containing blend weights in the RGB channels
Do you plan on having smooth transitions between textures with vertex granularity (e.g. a vertex that is 50/50 between two textures)?do I really need 8bits of precision for a texture weight ?
N.B. with your 2-bit idea, you'd basically have to perform the weight-texture lookup in the vertex shader, with nearest neighbour sampling, because performing the fetch at the pixel level, with linear filtering, will destroy your packed data.
Instead of R being weight for tex0, G weight for tex1, etc... You can also encode the texture-index in the texture. e.g. So you store 4 weights and 4 indices.to blend more than 3 textures I would end up passing multiple texture blend maps to the shader
Re-visiting your packing idea, you could store 4 4-bit weights, and 4 4-bit indices, which allows you to transition between 16 textures.
Edited by Hodgman, 07 August 2012 - 09:46 AM.
#4 Members - Reputation: 343
Posted 07 August 2012 - 04:21 PM
Are you really going to need more than 4 textures per terrain tile? (I'm not sure how big a "tile" is in relation to player view and interaction). An alternative would be to set up your array of textures in memory, and then define which 4 you want to blend between per tile. This would let you have a terrain with many texture types without sacrificing the range of the blend weights.
I'd steer away from the 2bit blending, as that's not going to give you any kind of smooth transitions.
Thanks for the reply. I find it difficult to restrict myself to only 3-4 textures, but maybe I'm looking at the problem wrong and currently have little in the way of "rocks","boulders" etc to make the otherwise uniform terrain interesting.
#5 Members - Reputation: 343
Posted 07 August 2012 - 04:29 PM
You should count A. There's no 24-bit GPU texture formats.four if you count A
It's not mentioned in your post whether you're going to sample this weight texture in the pixel or vertex shader, so in case you've not considered it -- you can perform the fetch in the vertex shader, and it's almost equivalent to having the weights as part of the vertex stream.I am unable to pass texture weights through the vertex buffer so intend to pass a Texture2D containing blend weights in the RGB channels
Do you plan on having smooth transitions between textures with vertex granularity (e.g. a vertex that is 50/50 between two textures)?do I really need 8bits of precision for a texture weight ?
N.B. with your 2-bit idea, you'd basically have to perform the weight-texture lookup in the vertex shader, with nearest neighbour sampling, because performing the fetch at the pixel level, with linear filtering, will destroy your packed data.Instead of R being weight for tex0, G weight for tex1, etc... You can also encode the texture-index in the texture. e.g. So you store 4 weights and 4 indices.to blend more than 3 textures I would end up passing multiple texture blend maps to the shader
Re-visiting your packing idea, you could store 4 4-bit weights, and 4 4-bit indices, which allows you to transition between 16 textures.
Thanks for the detailed reply.
In terms of 24bit textures, its a complex situation, but the default for SpriteBatch is premultiplied alpha, essentially robbing me of the Alpha channel, and becuase I am sampling the texture weights in the Vertex Shader, I cannot use COLOR semantics but must use VECTOR4 and therefore cannot instruct the sprite batch to render as non-premultiplied. (as you've guessed I am loading my texture map at runtime and rendering to a Texture2D then rather than using the pipeline, essentially to keep the asset size low).
I agree that sampling in the Vertex Shader can be done with a nearest neighbour function and I do this with my heightmap, and its where I currently do my texture weight sampling, to pass onto the Pixel Shader - and I do use blends of varying weights, but rarely more than two textures per voxel. I understand your use of Index and Weight encoded in the texture and I'll experiment with that idea.
Have you used Hardware Instancing to combine fixed and variable geometry into a single shader call ? It seems to me that instead of me mucking about with multiple samples in the Vertex Shader I might just load the weigthtings up as a second VertexBuffer (with the geometry being constant between tiles).
Thanks again for your interesting reply.
#6 Members - Reputation: 1006
Posted 07 August 2012 - 06:07 PM
I definitely suggest mixing it up to make your terrain less repetitive. A few possibilities:
- For simple self-similar textures like rock you can blend the same texture multiple times at multiple scales.
- Add details like rocks etc, which you can do manually, based on a position hash, etc.
- Create two versions of the same texture with minor differences. Put mask values in the alpha channel to allow your shader to mask in or out a whole region as desired, perhaps based on a position hash.
- Create two similar textures and in your editor blend them together with Perlin/Simplex noise.
http://www.gamedev.net/topic/628591-shader-limitations-and-best-practices/
#7 Members - Reputation: 1062
Posted 08 August 2012 - 01:05 AM
http://mtnphil.wordp...terrain-engine/
The big downside is that it means that a particular tile texture always needs to appear next to another - i.e. there is a distinct ordering. In practice this turns out not to be a huge deal, but it might be for your scenario.
Edited by phil_t, 08 August 2012 - 01:06 AM.
#8 Members - Reputation: 343
Posted 08 August 2012 - 03:34 PM
My "take home" message from this is;
1) The texture map can be a different size from my Heightmap texture, having more or less voxels, and use LERP in the VertexShader or PixelShader to get a set of blend weights.
2) I can slice+dice the actual colors in the texture map to mean anything I want - there is no need to consider that each channel contains only one texture's worth of blend information - I can use all 24 bits if I want in any combination, bearing in mind the complexities in LERPing the result.
3) Four textures per tile as base textures seems to be a reasonable limit, but for extra "realism" I need to look beyond bump mapped textures and put in some more geometry - rocks, etc. based on a frustum clipping or other tree to limit their number.
Thanks all. I'll look into the recommended links - I'm not building a game, just love experimenting with real time landscaping techniques as a hobby.
Phil






