9
我從我的切線空間法線貼圖着色器得到了一些非常怪異的結果:)。在這裏展示的場景中,茶壺和格子牆被我普通的Phong-Blinn着色器遮蓋(顯然,茶壺背面剔除使它具有輕微的短暫外觀和感覺:-))。我一直在努力,在正常映射添加到球體,迷幻的結果:切線空間法線貼圖 - 着色器完整性檢查
的光從右邊過來(只是爲黑色斑點可見)。我使用的是在球體上的法線貼圖看起來是這樣的:
我使用AssImp處理輸入的機型,所以它會自動計算切線和雙向法線每個頂點我。
像素和頂點着色器如下。我不太確定發生了什麼問題,但如果切線基礎矩陣有些錯誤,我不會感到驚訝。我假設我必須將東西計算到眼睛空間中,然後將眼睛和光線矢量轉換爲切線空間,並且這是正確的方法。請注意,燈光位置已經進入着色器中。
// 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;
}
...和像素着色器看起來是這樣的:
// 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;
}
編輯:3D Studio的渲染場景的(以顯示UV的是OK的球):
謝謝。我添加了場景的3D Studio渲染,以顯示球體上的UV都是OK。它也使用相同的地圖進行碰撞。 – Robinson 2012-04-05 16:39:18
像往常一樣,你給我一個關於答案datenwolf的好消息。使用color =(u,v,0,1)渲染球體時,它絕對不會在導入該網格時正確處理UV,或者我的着色器未被正確綁定。 – Robinson 2012-04-05 16:53:10
就是這樣。頂點着色器需要:\t vary_TextureCoord = attrib_Texture ;.這樣一個愚蠢的錯誤和準備問題的時間:-)。 – Robinson 2012-04-05 16:57:06