worldSpace中的定向光依赖于viewMatrix

时间:2017-04-20 12:57:51

标签: opengl glsl

我试着让我的glsl着色器为我计算定向光,但我遇到的问题是方向似乎依赖于viewMatrix,而我想在worldSpace中指定它。 我最初的想法是将worldSpace Vector与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;
}

我对着色器有点新意,所以我不知道该怎么做了。 要指定我得到的效果:应该来自一个方向(在worldSpace中)的方向光来自基于viewMatrix的不同方向

1 个答案:

答案 0 :(得分:0)

我现在感到愚蠢。我发布后就找到了答案。

几何着色器直接传递vertexNormal而不是使用modelViewMatrix复制它。

答案是这样的:

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

而不是:

mvVertexNormal=calculateTriangleNormal();