Opengl GLSL法线随摄影机旋转而改变

Opengl GLSL法线随摄影机旋转而改变,opengl,glsl,shader,lighting,normals,Opengl,Glsl,Shader,Lighting,Normals,我知道同样的问题被问了很多次,但不幸的是我无法找到问题的根源 在教程的帮助下,我编写了一个小型GLSL着色器。现在它可以使用环境光并从法线贴图加载法线。问题是平行光似乎取决于我的视角。 以下是我的着色器: //Vertex Shader #version 120 attribute vec3 position; attribute vec2 texCoord; attribute vec3 normal; attribute vec3 tangent; varying vec2 texCoor

我知道同样的问题被问了很多次,但不幸的是我无法找到问题的根源

在教程的帮助下,我编写了一个小型GLSL着色器。现在它可以使用环境光并从法线贴图加载法线。问题是平行光似乎取决于我的视角。 以下是我的着色器:

//Vertex Shader
#version 120
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
attribute vec3 tangent;

varying vec2 texCoord0;
varying mat3 tbnMatrix;
uniform mat4 transform;
void main(){
 gl_Position=transform * vec4(position, 1.0);
 texCoord0 = texCoord;
 vec3 n = normalize((transform*vec4(normal,0.0)).xyz);
 vec3 t = normalize((transform*vec4(tangent,0.0)).xyz);
 t=normalize(t-dot(t,n)*n);
 vec3 btTangent=cross(t,n);
 tbnMatrix=transpose(mat3(t,btTangent,n));
}


//Fragment Shader
#version 120
varying vec2 texCoord0;
varying mat3 tbnMatrix;
struct BaseLight{
  vec3 color;
  float intensity;
};

struct DirectionalLight{
  BaseLight base;
  vec3 direction;
};

uniform sampler2D diffuse;
uniform sampler2D normalMap;
uniform vec3 ambientLight;
uniform DirectionalLight directionalLight;

vec4 calcLight(BaseLight base, vec3 direction,vec3 normal){
  float diffuseFactor=dot(normal,normalize(direction));
  vec4 diffuseColor = vec4(0,0,0,0);
  if(diffuseFactor>0){
    diffuseColor=vec4(base.color,1.0)* base.intensity *diffuseFactor;
  }

  return diffuseColor;
}
vec4 calcDirectionalLight(DirectionalLight directionalLight ,vec3 normal){
    return calcLight(directionalLight.base,directionalLight.direction,normal);
}

void main(){

    vec3 normal =tbnMatrix*(255.0/128.0* texture2D(normalMap,texCoord0).xyz-255.0/256.0);
    vec4 totalLight = vec4(ambientLight,0)   +calcDirectionalLight(directionalLight, normal);
    gl_FragColor=texture2D(diffuse,texCoord0)*totalLight;
}
我发送给着色器的“transform”(变换)矩阵的计算方式如下:

viewProjection=m_perspective* glm::lookAt(CameraPosition,CameraPosition+m_forward,m_up);
glm::mat4 transform = vievProjection * object_matrix;
“object_matrix”是我直接从物理引擎得到的一个矩阵(我认为它是定义对象在世界空间中的位置和旋转的矩阵,如果我错了请纠正我)

我猜“变换”矩阵的计算是正确的,因为所有的物体都画在正确的位置。看起来问题与法线有关,因为如果我设置gl_FragColor=vec4(法线,0),颜色也会随着摄影机旋转而改变


如果有人能指出我的错误,我将不胜感激

法线是一个向量(方向),而不是一个点,不能用
变换
矩阵进行变换。您可能需要对摄影机矩阵进行单独的反向转置。搜索“法线变换”时,应提供理论、示例等。
n
t
应仅使用
对象矩阵进行变换。然后法线和灯光参数都在世界空间中。@BrettHale谢谢你,我按照你说的做了,并在计算法线时使用了“转置(逆(mat)),我认为它是有效的。至少现在光线明显来自一个方向,不会因为我的相机旋转而改变。网格上有一些奇怪的照明部分,但我认为这是因为现在我无法检查是否应该应用灯光。但基本的立方体模型非常有效。谢谢。