Triplanar terrain texturing with GLSL
Stretched textures on vertical triangles is a usual bug when texturing terrain. To fix it we need to recalculate texture coordinates in 3 projections: x, y and z.
The main algorithm to apply triplanar texturing is the following. First, we compute the vertex’s normal vector and check what the larger component of the normal is, out of x, y and z. If x is the larger component, we use the geometry z coordinate as the texture coordinate s, and the geometry y coordinate as the texture coordinate t. If z is the larger component, we use the geometry x
coordinate as the texture coordinate s, and the geometry y coordinate as the texture coordinate t.
Here’s how terrain looked like before we used shaders:

Than we apply GLSL shaders:
Vertex shader
varying float v;
varying float xcoord,ycoord,zcoord;
void main ()
{
//Texture Coordinates
xcoord = gl_Vertex.x;
zcoord = gl_Vertex.z;
ycoord = gl_Vertex.y ;
// projection1. y is largest normal component
// so use x and z to sample texture
gl_TexCoord[0] = vec4(xcoord,zcoord,0,0); //first projection
// projection2. x is largest normal component
// so use z and y to sample texture
gl_TexCoord[1] = vec4(zcoord,ycoord,0,0); //second projection
// projection3. z is largest normal component
// so use x and y to sample texture
gl_TexCoord[2] = vec4(xcoord,ycoord,0,0); //third projection
//gl_Normal is the vertex's normal vector.
//We compare it's absolute values with each other to find witch projection to use
float x = abs(gl_Normal.x);
float y = abs(gl_Normal.y);
float z = abs(gl_Normal.z);
if(x > y && x > z)
{
//v is a variable used in fragment shader to distinguish textures
v = 1;
}
if(y > x && y > z)
{
v = 0;
}
if(z > y && z > x)
{
v = 2;
}
gl_Position = ftransform();
}
Fragment shader
varying float v;
uniform sampler2D myTexture0;
uniform sampler2D myTexture1;
uniform sampler2D myTexture2;
void main (void)
{
if ( 0 == v )
{
gl_FragColor = texture2D( myTexture0, gl_TexCoord[0].st);
}
if ( 1 == v )
{
gl_FragColor = texture2D( myTexture1, gl_TexCoord[1].st);
}
if ( 2 == v )
{
gl_FragColor = texture2D( myTexture2, gl_TexCoord[2].st);
}
}
Here’s the result (we used 3 textures in shaders to see the result more easily):

loading...
loading...
No related posts.
4 Responses to Triplanar terrain texturing with GLSL
Leave a Reply Cancel reply
Current project
Recent Comments
Blog Archives
Tags
asp.net aurora bash beta bombardment boomer boost brann brannbil bregnetunet bug bullet physics bullshit c++ cairo certification code communication compile container Dev Fallout: New Vegas file format game Game review gentoo glsl graphics howto Java linux mvc opengl performance predicate programming research shader std terrain test texture tip Visual Studio








[...] on how we fixed it and shader samples here. Be Sociable, [...]
[...] the bug is fixed. More on how here. Be Sociable, [...]
Perfect work you have done, this site is really cool with excellent information.
loading...
loading...
Thanks!
)
loading...
loading...