Red de conocimiento informático - Material del sitio web - Cómo generar un mapa normal a partir de un mapa de altura

Cómo generar un mapa normal a partir de un mapa de altura

De hecho, no es difícil generar mapas normales a partir de mapas de altura en "Métodos de juegos 3D y gráficos por computadora". La idea es construir vectores S y T en un espacio tangente en función de la diferencia de altura entre un píxel en el mapa de altura y los píxeles circundantes, y obtener el vector normal de SXT.

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);

}