Texture splatting and Normal mapping

Started by
2 comments, last by Andr 4 years, 6 months ago

Hello!

So i am currently using a splatmap which is constructed in the geometry shader based on the height. This, however is very simplistic and doesnt look realistic so i am transitioning to a splatmap texture with each texture weight encoded in the RGBA channels (sand, grass, etc). This is blended in the fragment(pixel) shader with the diffuse textures according to the read weight at the current texture point.

My issue is with the normal mapping.

So from the heightmap, it is possible to generate a normal map (using GIMP normalmap for example) and this is being read and works okay. But i want to add more detail to the splatted textures by using their normal map as well as the terrain normal. So for example we have the terrain normal which will be blended with the sand normal (using the sand normal map) to create more detail.

How would the blending go in the fragment shader? So for the diffuse texture color i am currently using this:


vec3 tex0, tex1, tex2, tex3;
vec3 color = texture(TexBase, gs_patchTexCoord).rgb;

if (gs_splatMap[0] > 0)
{
	tex0 = texture(Tex0, gs_patchTexCoord).rgb;
	color = tex0 * gs_splatMap[0] + color * (1.0 - gs_splatMap[0]);
}
if (gs_splatMap[1] > 0)
{
	tex1 = texture(Tex1, gs_patchTexCoord).rgb;
	color = tex1 * gs_splatMap[1] + color * (1.0 - gs_splatMap[1]);
}
if (gs_splatMap[2] > 0)
{
	tex2 = texture(Tex2, gs_patchTexCoord).rgb;
	color = tex2 * gs_splatMap[2] + color * (1.0 - gs_splatMap[2]);
}
if (gs_splatMap[3] > 0)
{
	tex3 = texture(Tex3, gs_patchTexCoord).rgb;
	color = tex3 * gs_splatMap[3] + color * (1.0 - gs_splatMap[3]);
}

which works okay for the diffuse part but how would i insert the normal variation into this structure?

I am already calculating the TBN matrix before in the Tesselation Evaluation Shader.

The language is OpenGL but this would also apply to DirectX

Many thanks!

Advertisement

So i managed to apparently fix it by using a simple mix:


gNormal = mix(gNormal, computeNormalMapTex0(), gs_splatMap[0]);

with:


vec3 computeNormalMapTex0()
{
		vec3 normal = texture(tex0NormalMap, gs_patchTexCoord).rgb;
        normal = normalize(normal * 2.0 - 1.0);

        // Transform from tangent space to viewSpace
        return normalize(gs_tbnMatrix * normal);
}

However with just two normal maps the frame time increased by 1ms!

So now i have three questions: 

- Is the mix the best way to do it?

- Is it worth it to use normal maps for the detail textures or this frametime would be better applied somewhere else?

- Does the normal and TBN computation (in the TES) look good?


void calculateNormal(vec2 texCoord, mat4 mvMatrix)
{
	vec4 samp = 2.0 * texture(TexTerrainNormal, texCoord) - 1.0;
		
	normal_GS_in = normalize(mvMatrix*vec4(samp.rbg, 0.0)).xyz;
	
	vec3 tangent = normalize( vec3( normal_GS_in.z, 0, normal_GS_in.x ) );
	//tangent = normalize(tangent - normal_GS_in * dot(normal_GS_in, tangent));

	//vec3 bitangent = normalize( vec3( 0, normal_GS_in.z, normal_GS_in.y ) );
	vec3 bitangent = cross(normal_GS_in, tangent);
	
	tes_tbnMatrix = mat3(
        tangent,
        bitangent,
        normal_GS_in
    );
}

 

1 year later bump :D. Would i even need a TBN matrix in this case?

This topic is closed to new replies.

Advertisement