Note that there are some explanatory texts on larger screens.

plurals
  1. POGLSL Shaders texture alpha splatting
    text
    copied!<p>I'm trying to do shader used to load four textures detail tiles on a terrain by merging them according a a fifth image where r,g,b and a components are used to determine how much of each texture should be blended together. The blending works fine, but when I try adding my "mixmap" image, it fails, because of a problem with texture coordinates I guess.</p> <p>First, here are the shaders:<br> Vertex shader</p> <pre><code>void main() { gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } </code></pre> <p>Fragment Shader<br></p> <pre><code>uniform sampler2D Texture0; uniform sampler2D Texture1; uniform sampler2D Texture2; uniform sampler2D Texture3; uniform sampler2D Mixmap; varying vec3 pos; void main() { vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba; vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba; vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba; vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba; vec4 mixmapTexel = texture2D(Mixmap, gl_TexCoord[0].st).rgba; texel0 *= mixmapTexel.r; texel1 = mix(texel0, texel1, mixmapTexel.g); texel2 = mix(texel1, texel2, mixmapTexel.b); gl_FragColor = mix(texel2, texel3, mixmapTexel.a); } </code></pre> <p>As I said the blending works fine. The problem comes from the fact that the values read from my mixmap aren't the right ones.</p> <p>Here is some more explanation on what I'm doing. I'm building a paging terrain system loading the terrain from heightmaps. Then I want to use my mixmap image to represent with the rgba components how much of each texture should be blended according to height.</p> <ul> <li><p>r is water</p></li> <li><p>g is sand</p></li> <li><p>b is grass</p></li> <li><p>a is rock</p></li> </ul> <p>So I need to be able to get the correct pixel value from my shader to correctly blend my textures.</p> <p><img src="https://i.stack.imgur.com/6S8Ms.jpg" alt="Blending between crate and text"></p> <p>Here is an example of blending between a crate and a text, so that you can clearly see how the texture is applied.</p> <p>Now if I use a simple mixmap image (half red, half green), which should give me the crates on the left side of the terrain, and the text on the right, I get <img src="https://i.stack.imgur.com/mPVhk.jpg" alt="with argb alpha splatting"> <img src="https://i.stack.imgur.com/QWOp4.jpg" alt="example rgba image"></p> <p>Here is part of the terrain generation process: it iterates through an array of vertices and create the terrain triangles</p> <pre><code>void TerrainPage::generateDisplayList() { // create one display list mDisplayListIndex = glGenLists(1); // compile the display list, store a triangle in it glNewList(mDisplayListIndex, GL_COMPILE); glFrontFace( GL_CW ); // Vertex are added clockwise. Used to calculate normals std::vector&lt;Vertex&gt;::iterator it; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE); texShader.enable(); texShader.bindTexture(mTexture0, "Texture0", 0); texShader.bindTexture(mTexture1, "Texture1", 1); texShader.bindTexture(mTexture2, "Texture2", 2); texShader.bindTexture(mTexture3, "Texture3", 3); texShader.bindTexture(mMixmapTexture, "Mixmap", 4); Vertex v; int j=0; glEnable(GL_TEXTURE_2D); //mTexture.bind(); glBegin(GL_TRIANGLE_STRIP); for(int i = 0; i&lt;mVertices.size(); i++) { if(i%(2*mWidth) == 0) glEnd(); glBegin(GL_TRIANGLE_STRIP); v = mVertices[i]; glTexCoord2f(v.texcoords[0], v.texcoords[1]); glVertex3f(v.position[0], v.position[1], v.position[2]); } glEnd(); glDisable(GL_TEXTURE_2D); texShader.disable(); glEndList(); } </code></pre> <p>If needed, I can provide more screenshots, some of my code too.</p> <p>As a follow-on to the answer provided, I tried to do it by calculating the UV in the shader.</p> <p>First, here is the new shader</p> <p>Vertex shader</p> <pre><code>varying vec4 VertexPosition; void main() { gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); VertexPosition = gl_ModelViewMatrix * gl_Vertex;; } </code></pre> <p>Fragment shader</p> <pre><code>uniform sampler2D Texture0; uniform sampler2D Texture1; uniform sampler2D Texture2; uniform sampler2D Texture3; uniform sampler2D Mixmap; varying vec4 VertexPosition; float side = 500.; void main() { vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba; vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba; vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba; vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba; vec4 mixmapTexel = texture2D(Mixmap, VertexPosition.xz/(2.*side)).rgba; texel0 *= mixmapTexel.r; texel1 = mix(texel0, texel1, mixmapTexel.g); //texel2 = mix(texel1, texel2, mixmapTexel.b); //vec4 tx = mix(texel2, texel3, mixmapTexel.a); //vec4 tx = mixmapTexel; //vec4(1, 1, 1, 1.); gl_FragColor = texel1; //if(test &gt; 250. ) // gl_FragColor = vec4(1.,1.,1.,1.); } </code></pre> <p>And here are the results</p> <p><img src="https://i.stack.imgur.com/ePX83.jpg" alt="enter image description here"></p> <p>But if I move the camera:</p> <p><img src="https://i.stack.imgur.com/lDS8j.png" alt="enter image description here"></p> <p>As you can see the crate and text are side by side this time. But it looks like I'm computing in screen coordinates instead of world coordinates. I must have gotten confused again with the coordinate system. I'll try and find the right one! I just want to make sure that I'm in the right direction. I'll look for the multi texture coordinates too, it might be more convenient once I figured out how it works ;)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload