Opengl GLSL法线映射闪烁

Opengl GLSL法线映射闪烁,opengl,glsl,Opengl,Glsl,我试图将法线贴图效果添加到我找到的着色器教程中,但运气不好 更新1: 我更新了代码,添加了一个切线空间矩阵 顶点着色器: #version 330 in vec3 inPosition; in vec3 vertNormal; in vec2 vertTexCoord; in vec4 vertNormalMapping; out vec3 fragVert; out vec3 fragNormal; out vec2 fragTexCoord; out vec4 fragNormalMa

我试图将法线贴图效果添加到我找到的着色器教程中,但运气不好

更新1: 我更新了代码,添加了一个切线空间矩阵

顶点着色器:

#version 330


in vec3 inPosition;
in vec3 vertNormal;
in vec2 vertTexCoord;
in vec4 vertNormalMapping;

out vec3 fragVert;
out vec3 fragNormal;
out vec2 fragTexCoord;
out vec4 fragNormalMapping;
out mat3 TBNMatrix;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;

void main(){    

vec3 tangent; 
vec3 binormal; 

vec3 c1 = cross( vertNormal, vec3(0.0, 0.0, 1.0) ); 
vec3 c2 = cross( vertNormal, vec3(0.0, 1.0, 0.0) ); 

if( length(c1)>length(c2) )
{
    tangent = c1;   
}
else
{
    tangent = c2;   
}

tangent = normalize(tangent);

binormal = cross(vertNormal, tangent); 
binormal = normalize(binormal);

mat3 normalMatrix = transpose(inverse(mat3(camera * modelViewProjectionMatrix )));
vec3 n = normalize(normalMatrix * vertNormal);
vec3 t = normalize(normalMatrix * tangent.xyz);
vec3 b = normalize(normalMatrix * binormal.xyz);
TBNMatrix = mat3(t, b, n);



fragTexCoord = vertTexCoord;
fragNormal = vertNormal;
fragVert = inPosition;
fragNormalMapping = vertNormalMapping;


gl_Position  = camera * modelViewProjectionMatrix * vec4(inPosition, 1.0);



}
片段着色器 #330版

precision highp float;


uniform vec3 cameraPosition;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 camera;
uniform sampler2D tex;
uniform sampler2D heightMap; 



uniform float materialShininess;
uniform vec3 materialSpecularColor;

uniform struct Light {
   vec3 position;
   vec3 intensities; //a.k.a the color of the light
   float attenuation;
   float ambientCoefficient;
} light;


in vec3 fragNormal;
in vec3 fragVert;
in vec2 fragTexCoord;
in vec4 fragNormalMapping;
in mat3 TBNMatrix;

out vec4 finalColor;

void main() {

vec3 surfacePos = vec3(modelViewProjectionMatrix * vec4(fragVert, 1));
    vec4 surfaceColor = texture(tex, fragTexCoord);
    vec3 surfaceToLight = TBNMatrix * (light.position - surfacePos) ;
    vec3 surfaceToCamera = TBNMatrix * (cameraPosition - surfacePos);



vec3 normal = normalize(texture(heightMap, fragTexCoord).xyz * 2.0 - 1.0);


//ambient
vec3 ambient = light.ambientCoefficient * surfaceColor.rgb * light.intensities;

//diffuse
    float diffuseCoefficient = max(0.0, dot(normal, surfaceToLight));
    vec3 diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities;

//specular
    float specularCoefficient = 0.0;
    if(diffuseCoefficient > 0.0)
        specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normal))), materialShininess);
    vec3 specular = specularCoefficient * materialSpecularColor * light.intensities;

    //attenuation
    float distanceToLight = length(light.position - surfacePos);
    float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));

//linear color (color before gamma correction)
vec3 linearColor = ambient + attenuation*(diffuse + specular);

    //final color (after gamma correction)
    vec3 gamma = vec3(1.0/2.2);
    finalColor = vec4(pow(linearColor, gamma), surfaceColor.a);

}
结果更好,但现在照明计算错误

//旧的 我试过使用空白颜色纹理和正确的法线贴图纹理,结果是:法线贴图计算正确,但。。。这些线条看起来并不那么酷:-(


知道原因是什么吗?谢谢大家的帮助

mv = camera * transform;//modelview
mvp = proj * camera * transform;//modelviewprojection
mvi = transpose(inverse(mv))//modelview inverse (=gl_NormalMatrix)
因此,您应该将modelView和投影分别传递给着色器来代替modelViewProjectionMatrix,并在顶点着色器中计算生成的mvp


(或者在cpu端预先计算它们)

这条线应该做什么???
normalMap.g=1.0-normalMap.g;
还有,为什么要在frag着色器中乘以顶点坐标(对于每个像素),而nor矩阵和顶点曝光在每个片段中都会发生变化?更多关于切线空间向量(T,B,N)在哪里这是像素空间坐标,对法线贴图至关重要,谢谢@j-p的优化=D我更改了代码。这个'normalMap.g=1.0-normalMap.g;'用于反转g坐标…嗯…如果不还原它也不是wokring,所以这不是问题。嗯…看看a并实现切线空间向量(T,B,N)在你的光照方程中,trickI肯定会理解另一种视觉错误,比如凹凸贴图,而不是whowing或其他东西。但它正在工作……凹凸贴图正在正确显示和计算。我们唯一的问题是它像疯了一样闪烁:-(哇,谢谢你。所以我在做这些GPU方面的工作,让我知道我是否在这里。这就是我要传递给GPU的内容:
MU几何->\uPShaderManager->setUniform(U模型矩阵,\uTMpMatrix);MU几何->\uPShaderManager->setUniform(U摄像机矩阵,\uCamera->view());MU几何->\uPShaderManager->setUniform(U_PROJECTION_MATRIX,_camera->PROJECTION());
我认为Farment着色器中的变量surfacePos现在也是错误的。对吗?sufacePos并没有很好的命名,它是世界空间中的顶点位置(根据其在光方程中的使用),而名为ModelViewProjectionMatrix的矩阵的使用方式类似于ModelViewMatrix,它不应该包括投影(proj似乎在cameraMatrix中),但它的计算对我来说似乎是正确的。