2012-04-05 10 views
9

obtengo algunos resultados bastante extraños de mi sombreado de asignación de espacio tangente normal :). En la escena que muestro aquí, la tetera y las paredes a cuadros se sombrean con mi sombreador de Phong-Blinn ordinario (obviamente, el recorte de la cara posterior de la tetera le da una apariencia y sensación ligeramente efímeras :-)). He intentado añadir en los mapas de normales a la esfera, con resultados psicodélicas:Asignación normal de espacio tangente: verificación de cordura del sombreador

Incorrect Normal Mapping on Sphere

La luz viene de la derecha (casi visible como una mancha negro). El mapa normal estoy usando en la esfera se ve así:

Normal Map

estoy usando AssImp para procesar modelos de entrada, por lo que el cálculo de la tangente y bi-normales para cada vértice de forma automática para mí.

Los sombreadores de píxel y vértice están a continuación. No estoy muy seguro de lo que está pasando mal, pero no me sorprendería si la matriz de base tangente es de alguna manera incorrecta. Supongo que tengo que calcular las cosas en el espacio visual y luego transformar el ojo y los vectores de luz en espacio tangente y que esta es la forma correcta de hacerlo. Tenga en cuenta que la posición de luz entra en el sombreador que ya está en el espacio de visualización.

// Vertex Shader 
#version 420 

// Uniform Buffer Structures 

// Camera. 
layout (std140) uniform Camera 
{ 
    mat4 Camera_Projection; 
    mat4 Camera_View; 
}; 

// Matrices per model. 
layout (std140) uniform Model 
{ 
    mat4 Model_ViewModelSpace; 
    mat4 Model_ViewModelSpaceInverseTranspose; 
}; 

// Spotlight. 
layout (std140) uniform OmniLight 
{ 
    float Light_Intensity; 

    vec3 Light_Position;   // Already in view space. 
    vec4 Light_Ambient_Colour; 
    vec4 Light_Diffuse_Colour; 
    vec4 Light_Specular_Colour; 
}; 

// Streams (per vertex) 
layout(location = 0) in vec3 attrib_Position; 
layout(location = 1) in vec3 attrib_Normal; 
layout(location = 2) in vec3 attrib_Tangent; 
layout(location = 3) in vec3 attrib_BiNormal; 
layout(location = 4) in vec2 attrib_Texture; 

// Output streams (per vertex) 
out vec3 attrib_Fragment_Normal; 
out vec4 attrib_Fragment_Position; 
out vec3 attrib_Fragment_Light; 
out vec3 attrib_Fragment_Eye; 

// Shared. 
out vec2 varying_TextureCoord; 

// Main 
void main() 
{ 
    // Compute normal. 
    attrib_Fragment_Normal = (Model_ViewModelSpaceInverseTranspose * vec4(attrib_Normal, 0.0)).xyz; 

    // Compute position. 
    vec4 position = Model_ViewModelSpace * vec4(attrib_Position, 1.0); 

    // Generate matrix for tangent basis. 
    mat3 tangentBasis = mat3( attrib_Tangent, 
           attrib_BiNormal, 
           attrib_Normal); 

    // Light vector. 
    attrib_Fragment_Light = tangentBasis * normalize(Light_Position - position.xyz); 

    // Eye vector. 
    attrib_Fragment_Eye = tangentBasis * normalize(-position.xyz); 

    // Return position. 
    gl_Position = Camera_Projection * position; 
} 

... y el sombreado de píxeles es así:

// Pixel Shader 
#version 420 

// Samplers 
uniform sampler2D Map_Normal; 

// Global Uniforms 

// Material. 
layout (std140) uniform Material 
{ 
    vec4 Material_Ambient_Colour; 
    vec4 Material_Diffuse_Colour; 
    vec4 Material_Specular_Colour; 
    vec4 Material_Emissive_Colour; 

    float Material_Shininess; 
    float Material_Strength; 
}; 

// Spotlight. 
layout (std140) uniform OmniLight 
{ 
    float Light_Intensity; 

    vec3 Light_Position;  
    vec4 Light_Ambient_Colour; 
    vec4 Light_Diffuse_Colour; 
    vec4 Light_Specular_Colour; 
}; 

// Input streams (per vertex) 
in vec3 attrib_Fragment_Normal; 
in vec3 attrib_Fragment_Position; 
in vec3 attrib_Fragment_Light; 
in vec3 attrib_Fragment_Eye; 

// Shared. 
in vec2 varying_TextureCoord; 

// Result 
out vec4 Out_Colour; 

// Main 
void main(void) 
{ 
    // Compute normals. 
    vec3 N = normalize(texture(Map_Normal, varying_TextureCoord).xyz * 2.0 - 1.0); 
    vec3 L = normalize(attrib_Fragment_Light); 
    vec3 V = normalize(attrib_Fragment_Eye); 
    vec3 R = normalize(-reflect(L, N)); 

    // Compute products. 
    float NdotL = max(0.0, dot(N, L)); 
    float RdotV = max(0.0, dot(R, V)); 

    // Compute final colours. 
    vec4 ambient = Light_Ambient_Colour * Material_Ambient_Colour; 
    vec4 diffuse = Light_Diffuse_Colour * Material_Diffuse_Colour * NdotL; 
    vec4 specular = Light_Specular_Colour * Material_Specular_Colour * (pow(RdotV, Material_Shininess) * Material_Strength); 

    // Final colour. 
    Out_Colour = ambient + diffuse + specular;  
} 

Editar: 3D Studio Render de la escena (a la demostración de los rayos UV están bien en la esfera):

enter image description here

Respuesta

3

Creo que sus shaders están bien, pero las coordenadas de su textura en la esfera están totalmente desactivadas. Es como si se distorsionaran hacia los polos a lo largo de la longitud.

+0

Gracias. Agregué un renderizado en 3D Studio de la escena para mostrar que los UV en la esfera están bien. Está usando el mismo mapa para golpe también. – Robinson

+1

Como de costumbre, me das una buena pista sobre la respuesta datenwolf. Renderizar la esfera con color = (u, v, 0, 1) definitivamente no está procesando los UVs correctamente en la importación de esta malla, o mi sombreador no está siendo enlazado correctamente. – Robinson

+1

Eso fue todo. Vertex shader needed: \t varying_TextureCoord = attrib_Texture ;. Un error tan tonto y el tiempo dedicado a preparar la pregunta :-). – Robinson

Cuestiones relacionadas