Cómo generar un mapa normal a partir de un mapa de altura
Supongamos que H (i, j) representa el valor de altura del píxel (i, j) en el mapa de altura, entonces los vectores tangentes en las direcciones S y T en el espacio tangente se pueden expresar como
S(i,j) = (1,0,H(i 1,j) - H(i-1,j) )
T(i,j) = ( 0,1, H(i, j 1) - H(i, j-1) )
Normal(i, j) = S(i, j) X T(i, j)
H(i 1, j) - H(i-1, j) es la diferencia de altura a lo largo de la dirección S, es decir, la pendiente en la dirección S, H(i, j 1) - H(i , j-1) es la diferencia de altura a lo largo de la dirección T. La diferencia de altura es la pendiente en la dirección T. Cuando la diferencia de altura entre píxeles adyacentes es 0, la Normal calculada (i, j) = (0, 0, 1) significa que la normal es perpendicular al plano, y cuando hay una diferencia de altura, la normal está dirigida hacia S respectivamente.
También es muy sencillo de implementar usando sombreadores. Los códigos VS y PS son los siguientes. La imagen superior izquierda es el HeightMap y la imagen de la derecha es el NormalMap generado por el sombreador a continuación. por este método no es lo suficientemente bueno. En RenderMonkey Hay un ejemplo de llamada a NormalmapFilter, que generará un NormalMap de mayor calidad. Los amigos interesados pueden consultarlo.
VS_OUTPUT main(float4 Pos: POSITION){
VS_OUTPUT Out;
// Limpiar imprecisiones
Pos.xy = signo (Pos.xy);
Out.xy, 0, 1);
// Espacio de imagen
Out.texCoord.x = 0.5 * (1 Pos.x);
Out.texCoord.y = 0.5 * (1 - Pos.y);
return Out;
}
float4 main(float2 texCoord: TEXCOORD): COLOR {
float2 off = 1.0 / HeightMapSize
float Scale =
// Muestra del vecino
float s0 = tex2D(Heightmap, texCoord float2(-off.x, 0)).r;
float s1 = tex2D(Heightmap, texCoord float2 ( off.x, 0)).r;
float s2 = tex2D(Heightmap, texCoord float2( 0, -off.y)).r
float s3 = tex2D (Mapa de altura, texCoord float2(0, off.y)).r;
float3 U = float3(1, 0, s1 - s0); , 1, s3 - s2);
float3 normal = normalize(Escala * cruz(U, V));
// Empaqueta [-1, 1] en [0, 1]
return float4(normal * 0.5 0.5, 1);
}