2012-04-05 24 views
9

Tôi nhận được một số kết quả khá kỳ lạ từ không gian tiếp tuyến của tôi. Trong cảnh tôi trình bày ở đây, các bức tường ấm trà và tường rô được che phủ bởi bóng râm Phong-Blinn bình thường của tôi (rõ ràng là mặt sau ấm trà cull mang lại cho nó một cái nhìn nhẹ nhàng và cảm nhận :-)). Tôi đã cố gắng thêm trong bản đồ thông thường đối với hình cầu, với những kết quả ảo giác:Bản đồ bình thường không gian ốp - kiểm tra độ mờ của bóng râm

Incorrect Normal Mapping on Sphere

Ánh sáng được phát ra từ bên phải (chỉ là về thể nhìn thấy như một đốm đen). Bản đồ bình thường Tôi đang sử dụng trên mặt cầu trông như thế này:

Normal Map

Tôi đang sử dụng AssImp để xử lý mô hình đầu vào, do đó, nó tính toán tiếp tuyến và bi-normals cho mỗi đỉnh tự động đối với tôi.

Trình tối ưu hóa pixel và đỉnh bên dưới. Tôi không quá chắc chắn những gì đang xảy ra, nhưng nó sẽ không làm tôi ngạc nhiên nếu ma trận cơ bản tiếp tuyến là bằng cách nào đó sai. Tôi cho rằng tôi phải tính toán mọi thứ vào không gian mắt và sau đó biến đổi các vectơ mắt và ánh sáng thành không gian tiếp tuyến và đây là cách chính xác để đi về nó. Lưu ý rằng vị trí ánh sáng đi vào vùng đổ bóng đã có trong không gian xem.

// 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; 
} 

... và các pixel shader trông như thế này:

// 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;  
} 

Edit: 3D Studio Render của cảnh (để hiển thị của tia cực tím là OK trên lĩnh vực):

enter image description here

Trả lời

3

Tôi nghĩ rằng trình tạo bóng của bạn không sao, nhưng tọa độ kết cấu của bạn trên hình cầu hoàn toàn tắt. Nó như thể chúng bị bóp méo về phía các cực dọc theo kinh độ.

+0

Cảm ơn. Tôi thêm một 3D Studio render của cảnh để hiển thị các tia cực tím trên quả cầu là tất cả OK. Nó sử dụng cùng một bản đồ cho vết sưng quá. – Robinson

+1

Như thường lệ, bạn cho tôi một đầu mối tốt về câu trả lời datenwolf. Dựng hình cầu với màu = (u, v, 0, 1) nó chắc chắn không xử lý các tia UV một cách chính xác khi nhập vào lưới này, hoặc trình đổ bóng của tôi không bị ràng buộc chính xác. – Robinson

+1

Vậy đó là nó. Trình đổ bóng Vertex cần: \t varying_TextureCoord = attrib_Texture ;. Một sai lầm ngớ ngẩn như vậy và thời gian chuẩn bị câu hỏi :-). – Robinson

Các vấn đề liên quan