Blending multiple textures in GLSL

It's a long time, but I promise it is interesting. :)

I am trying to simulate the texture appearance of another application using jMonkeyEngine. I have a list of vertices and faces (triangles) that make up the "landscape grid", which should be textured with about 7-15 different textures (depending on the landscape "landscape"). Each triangle has a texture code associated with it, which means which texture should consist of this particular triangle. And, of course, the textures should move smoothly between each face.

So, I'm trying to develop a strategy that allows this (which does NOT use pre-created alpha png files, texture alpha should be executed at runtime). Right now, I believe that if I calculated the “strength” of each texture at each vertex (in the vertex shader) - by factoring the landscape types of all neighboring faces (I don’t know how to do this) - I should be able to set alpha values ​​depending on how far the pixel is from the top. The generated alpha map will be used by the frag shader to blend each texture per pixel.

Is this possible, or should I look at a completely different strategy? I have shader code for an application that I am trying to emulate (but it is HLSL and I use GLSL), but it looks like they are doing this mixing step elsewhere:

sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; }; 

I'm not sure if this is an HLSL "MeshTextureSampler", but it looks like this application may have pre-mixed all the textures as needed and created a single texture for the entire mesh based on face / terrain code data. In the pixel / fragment shader, all they really do is the following:

 float4 tex_col = tex2D(MeshTextureSampler, In.Tex0); 

After that, it is just shadows, lighting, etc. - as far as I can tell, no texture mixing, which makes me think that this texture mixing work is done on the processor in advance, I suppose. Any suggestions are welcome.

+6
source share
1 answer

If I understand you correctly, here is what I did first:

Your problem, more or less, is how to distribute your own value among the vertices. This actually looks like a normal generation on a grid: first you have to generate a normal one for each triangle, and then calculate them to the top. Google is a "normal generation" and you will get there, but here's the point. For each adjacent triangle, find the weighting coefficient (often the angle of the angle that the vertex uses, or the surface area of ​​the triangle, or a combination), and then sum the value (whether normal or your "strengths"), multiplied from the weight coefficient to the overall result. Normalize, and you're done.

So, you have your own "strengths" texture, which you can send to your vertex shader. The modern solution would be to use the symbols and the texture array pattern in the pixel shader after you have slightly changed the blending values ​​to give you more pleasant translations.

So, if I understood your problem correctly:

Preprocess:

 forearch vertex in mesh vertexvalue = 0 normalization = 0 foreach adjacent triangle of vertex angle = calculateAngleBetween3Vertices(vertex,triangle.someothervertex,triangle.theotherothervertex) vertexvalue += triangle.value * angle normalization += angle vertexvalue/=normalization 

Rendering time:

pass the value (s) of each vertex to the fragmentshader and do this in the fragment shader:

 basecolour = 0; foreach value basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value) //this is simple, but we could do better once we have this working 

Or, alternatively, you can take a good look at your geometry. If you have a combination of large triangles and tiny ones, you will have uneven distribution of data, and since your data is at the top, you will have more detail where it is more geometry. In this case, you probably want to do what everyone else is doing and separate the texture from your geometry using blend maps. They can be low resolution and should not significantly increase memory consumption or shader runtime.

+3
source

Source: https://habr.com/ru/post/891918/


All Articles