Overview
Defining a detail texture: a texture that contains commonly occuring high frequency surface variations.
Why might you want to use this technique?
- As a fall-back for lower end hardware
- In circumstances where mid-ranged detail is more important than up close
The Technique
Requirements:
- RGB Color Map
- RGBA Opacity/Blend Map
- RGBA Composite Detail Textures
GLSL Code |
vec3 col = texture2D(__ColorMap__, texCoords).rgb;
vec4 blend = texture2D(__BlendMap__, texCoords).rgba;
vec4 detVal = texture2D(__DetailComposite__, texCoords * 200.0).rgba;
float dotValue = dot(detVal, blend);
float sVal = 1.0 - (dotValue * 2.0);
col += (-sVal);
|
The objective of the technique is to use the channels of an RGBA image to hold four different grayscale detail texture maps which are extracted by the dot product of the vectors for the composite image and its corresponding RGBA blend, dominance, opacity, w/e map.
Because multiplication against a range of 0 to 1 can only reduce the brightness of a texture the consequence of repeating this with multiple blends and/or overlapping layers is that the surface will continually get darker. By transforming the detail from a range of 0 to 1 to a range of -1 to +1 addition can be used to make it possible to darken the texture by adding a negative value to it and lighten it by adding a positive value. The last five lines of the shader can be repeated for any number of blend and composite maps.
The line:
float sVal = 1.0 - (dotValue * 2.0);
accomplishes this objective, however it inverts the light and dark values making it necessary to add the opposite of "sVal" to invert it again so the textures will behave as expected.
The technique is very fast and ideal for use as a material fallback for machines with lower end hardware. With the addition of 1D color lookups for some of the detail maps it could also add small highlights such as flowers and sea-shells, this would require the addition of 1D textures to Horde3D, so it is not currently an option at the moment, but is worth thinking about. 2D textures could be used however.
Full GLSL Fragment Shader for Terrain Lighting Context |
uniform sampler2D tex0, tex1, tex2, tex3;
varying vec4 pos, vsPos;
varying vec2 texCoords;
void main( void )
{
vec3 colMap = texture2D( tex1, texCoords).rgb;
vec4 blendMap = texture2D(tex2, texCoords).rgba;
vec4 blendTex = texture2D(tex3, texCoords * 300.0).rgba;
float detResult = dot(blendTex, blendMap);
detResult = 1.0 - (detResult * 2.0);
colMap += (-detResult);
vec4 texel = texture2D( tex0, texCoords ) * 2.0 - 1.0;
float ny = sqrt( max( 1.0 - texel.b*texel.b - texel.a*texel.a, 0.0 ) );
vec3 normal = vec3( texel.b, ny, texel.a );
gl_FragColor.rgb =
calcPhongSpotLight( pos.xyz, normalize( normal ), colMap, 0.0, 16.0, -vsPos.z, 0.3 );
}
|
Example Result

To-Do List for this Article
- Add more pictures
- Figure out proper Wiki formatting for code and lists
- If in some spots something that isn't as clear as it could be, edit it or point it out please - Posted by AcidFaucet, for fastest response in regards to this article: send a PM
|