2017-04-20 23 views
0

我嘗試讓我的glsl着色器爲我計算一個方向燈,但我遇到了問題,方向似乎依賴於viewMatrix,而我想在worldSpace中指定它。 我最初的想法是設定方向一致之前剛剛multipy世界空間向量與代碼中的viewMatrix(worldSpace中的方向燈依賴於viewMatrix

Vector4f dir = new Vector4f(dirLight.direction, 1); 
dir.mul(window.getCamera().viewMatrix); 

),但似乎光仍然變化取決於我的viewMatrix,所以我明明做錯事。 我着色器的相關代碼:

//vertex shader 

layout (location =0) in vec3 position; 
layout (location =1) in vec2 texCoord; 
layout (location =2) in vec3 vertexNormal; 
layout (location=3) in vec4 jointWeights; 
layout (location=4) in ivec4 jointIndices; 

out vec3 gmvVertexNormal; 
out vec3 gmvVertexPos; 

uniform mat4 projectionMatrix; 
uniform mat4 modelViewMatrix; 


struct Material 
{ 
    vec3 color; 
    int hasTexture; 
    float reflectance; 
}; 

uniform Material material; 



void main() 
{ 
    vec4 mvPos = modelViewMatrix * vec4(position, 1.0); 
    gl_Position = vec4(position,1.0); 
    gmvVertexNormal = normalize(modelViewMatrix * vec4(vertexNormal, 0.0)).xyz; 
    gmvVertexPos = position; 
} 

//geometry shader 
layout (triangles) in; 
layout (triangle_strip, max_vertices = 3) out; 

uniform mat4 projectionMatrix; 
uniform mat4 modelViewMatrix; 

out vec3 mvVertexNormal; 
out vec3 mvVertexPos; 

in vec3 gmvVertexNormal[3]; 
in vec3 gmvVertexPos[3]; 

vec3 calculateTriangleNormal(){ 
    vec3 tangent = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz; 
    vec3 bitangent = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz; 
    vec3 normal = cross(tangent, bitangent);  
    return normalize(normal); 
} 

void main() 
{ 
    vec4 mvPos = modelViewMatrix * vec4(gmvVertexPos[0], 1.0); 
    gl_Position = projectionMatrix * mvPos; 
    mvVertexNormal=calculateTriangleNormal(); 
    mvVertexPos=mvPos.xyz; 
    EmitVertex(); 
    mvPos = modelViewMatrix * vec4(gmvVertexPos[1], 1.0); 
    gl_Position = projectionMatrix * mvPos; 
    mvVertexNormal=calculateTriangleNormal(); 
    mvVertexPos=mvPos.xyz; 
    EmitVertex(); 
    mvPos = modelViewMatrix * vec4(gmvVertexPos[2], 1.0); 
    gl_Position = projectionMatrix * mvPos; 
    mvVertexNormal=calculateTriangleNormal(); 
    mvVertexPos=mvPos.xyz; 
    EmitVertex(); 
    EndPrimitive(); 
} 

//fragment shader 

in vec3 mvVertexNormal; 
in vec3 mvVertexPos; 

struct DirectionalLight { 
    vec3 color; 
    vec3 direction; 
    float intensity; 
}; 

const int MAX_DIRECTIONALLIGHT = 10; 
uniform int USED_DIRECTIONALLIGHTS; 
uniform DirectionalLight directionalLight[MAX_DIRECTIONALLIGHT]; 

vec4 calcDirectionalLight(DirectionalLight light, vec3 position, vec3 normal) 
{ 
    return calcLightColor(light.color, light.intensity, position, normalize(light.direction), normal); 
} 

vec4 calcLightColor(vec3 light_color, float light_intensity, vec3 position, vec3 to_light_dir, vec3 normal) 
{ 
    vec4 diffuseColor = vec4(0, 0, 0, 0); 
    vec4 specColor = vec4(0, 0, 0, 0); 

    // Diffuse Light 
    float diffuseFactor = max(dot(normal, to_light_dir), 0.0); 
    diffuseColor = vec4(light_color, 1.0) * light_intensity * diffuseFactor; 

    // Specular Light 
    vec3 camera_direction = normalize(- position); 
    vec3 from_light_dir = -to_light_dir; 
    vec3 reflected_light = normalize(reflect(from_light_dir , normal)); 
    float specularFactor = max(dot(camera_direction, reflected_light), 0.0); 
    specularFactor = pow(specularFactor, specularPower); 
    specColor = light_intensity * specularFactor * material.reflectance * vec4(light_color, 1.0); 

    return (diffuseColor + specColor); 
} 

void main() 
{ 


    vec4 totalLight = vec4(0); 
    //directional Light 
    for (int i=0; i<USED_DIRECTIONALLIGHTS; i++) { 
     totalLight += calcDirectionalLight(directionalLight[i], mvVertexPos, mvVertexNormal); 
    } 
    //... 

    fragColor = vec4(ambientLight, 1.0) + totalLight; 
} 

我還挺新的着色器,所以我不知道該怎麼辦了。 要指定我得到的效果:定向光應只來自(在世界空間)一個方向來自基礎上,viewMatrix

回答

0

不同的方向我現在覺得自己很蠢。我在發佈後立即找到了答案。

幾何着色器直接傳遞vertexNormal而不是將其與modelViewMatrix混合使用。

所以答案是這樣的:

mvVertexNormal=normalize(modelViewMatrix * vec4(calculateTriangleNormal(), 0.0)).xyz; 

,而不是這樣的:

mvVertexNormal=calculateTriangleNormal();