GLSL法线贴图闪烁

时间:2014-03-23 01:51:19

标签: opengl glsl

我试图将正常的地图效果添加到我找到here的着色器教程中,但没有运气。

更新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);



}

片段着色器     #version 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);

}

结果更好但现在照明计算错误O.O wrong light

// OLD 我试过一个空白的颜色纹理和一个正确的法线贴图纹理,结果如下:正常的地图计算正确,但......这些线条看起来并不那么酷: - (

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

1 个答案:

答案 0 :(得分:1)

为了清楚起见,

张贴在这里......

mv = camera * transform;//modelview
mvp = proj * camera * transform;//modelviewprojection
mvi = transpose(inverse(mv))//modelview inverse (=gl_NormalMatrix)

所以你应该取代modelViewProjectionMatrix分别传递给着色器modelView和投影,并在顶点着色器中计算得到的mvp。

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