Opengl 世界空间中的平行光取决于viewMatrix

Opengl 世界空间中的平行光取决于viewMatrix,opengl,glsl,Opengl,Glsl,我试图让我的glsl着色器为我计算平行光,但我遇到了一个问题,即方向似乎依赖于viewMatrix,而我想在worldSpace中指定它。 我最初的想法是将世界空间向量与viewMatrix进行多重叠加( )在设置方向之前的代码中是一致的,但是看起来灯光仍然根据我的viewMatrix而变化,所以我显然做了一些错误的事情。 我的着色器的相关代码: //vertex shader layout (location =0) in vec3 position; layout (location =1

我试图让我的glsl着色器为我计算平行光,但我遇到了一个问题,即方向似乎依赖于viewMatrix,而我想在worldSpace中指定它。 我最初的想法是将世界空间向量与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;
}
//顶点着色器
vec3位置的布局(位置=0);
vec2 texCoord中的布局(位置=1);
vec3 vertexNormal中的布局(位置=2);
vec4接头中的布局(位置=3);
ivec4接缝中的布局(位置=4);
out vec3 gmvVertexNormal;
输出vec3 GMVVERTExps;
均匀mat4投影矩阵;
统一mat4模型视图矩阵;
结构材料
{
vec3颜色;
内部结构;
浮动反射率;
};
均匀的材料;
void main()
{
vec4 mvPos=模型视图矩阵*vec4(位置,1.0);
gl_位置=vec4(位置,1.0);
gmvVertexNormal=规格化(modelViewMatrix*vec4(vertexNormal,0.0)).xyz;
GMVVERTExps=位置;
}
//几何体着色器
平面布置图(三角形);
布局(三角形带,最大顶点=3)输出;
均匀mat4投影矩阵;
统一mat4模型视图矩阵;
输出vec3mvvertexnormal;
输出vec3mvvertex;
在vec3中,gmvVertexNormal[3];
在vec3中,gmvVertexPos[3];
vec3 CalculaterAngleNormal(){
vec3 tangent=gl_in[1]。gl_Position.xyz-gl_in[0]。gl_Position.xyz;
[2]中的vec3 bitangent=gl_。gl_Position.xyz-gl_in[0]。gl_Position.xyz;
vec3法线=交叉(切线、双切线);
返回正常化(正常);
}
void main()
{
vec4 mvPos=modelViewMatrix*vec4(gmvVertexPos[0],1.0);
gl_位置=投影矩阵*mvPos;
mvVertexNormal=CalculaterAngleNormal();
mvvertexos=mvPos.xyz;
发射顶点();
mvPos=modelViewMatrix*vec4(gmvVertexPos[1],1.0);
gl_位置=投影矩阵*mvPos;
mvVertexNormal=CalculaterAngleNormal();
mvvertexos=mvPos.xyz;
发射顶点();
mvPos=modelViewMatrix*vec4(gmvVertexPos[2],1.0);
gl_位置=投影矩阵*mvPos;
mvVertexNormal=CalculaterAngleNormal();
mvvertexos=mvPos.xyz;
发射顶点();
EndPrimitive();
}
//片段着色器
vec3mvvertexnormal;
在vec3mvvertex中;
结构定向光{
vec3颜色;
vec3方向;
漂浮强度;
};
const int MAX_DIRECTIONALLIGHT=10;
使用统一的int_方向灯;
均匀方向光方向光[最大方向光];
vec4计算方向灯(方向灯、vec3位置、vec3法线)
{
返回calcLightColor(灯光、颜色、灯光、强度、位置、规格化(灯光、方向)、法线);
}
vec4 calcLightColor(vec3灯光颜色、浮动灯光强度、vec3位置、vec3至灯光方向、vec3正常)
{
vec4 diffuseColor=vec4(0,0,0,0);
vec4 specColor=vec4(0,0,0,0);
//漫射光
浮动漫射因子=最大值(点(正常,至光照方向),0.0);
漫射颜色=vec4(光颜色,1.0)*光强度*漫射因子;
//镜面反射光
vec3摄像机方向=标准化(-位置);
vec3 from_light_dir=-to_light_dir;
vec3反射光=规格化(反射(从光方向,法线));
浮动镜面反射系数=最大值(点(相机方向、反射光),0.0);
镜面反射系数=功率(镜面反射系数,镜面功率);
镜面颜色=光照强度*镜面反射系数*材料反射率*vec4(光照颜色,1.0);
返回(漫反射颜色+specColor);
}
void main()
{
vec4-totalLight=vec4(0);
//平行光

对于(inti=0;i我现在觉得自己很愚蠢。我在发布后才找到答案

几何体着色器直接传递顶点法线,而不是将其与modelViewMatrix相乘

所以答案是:

mvVertexNormal=normalize(modelViewMatrix * vec4(calculateTriangleNormal(), 0.0)).xyz;
与此相反:

mvVertexNormal=calculateTriangleNormal();

我现在觉得自己很笨。我刚发帖就找到了答案

几何体着色器直接传递顶点法线,而不是将其与modelViewMatrix相乘

所以答案是:

mvVertexNormal=normalize(modelViewMatrix * vec4(calculateTriangleNormal(), 0.0)).xyz;
与此相反:

mvVertexNormal=calculateTriangleNormal();