【问题标题】:GLSL Normal Mapping (Areas With 0.0 Lambert Gets Lit)GLSL 法线贴图(Lambert 为 0.0 的区域被点亮)
【发布时间】:2013-05-08 20:34:19
【问题描述】:

当我使用模型的法线时,结果很好(有暗区和亮区,正如我对简单的朗伯漫反射着色器所期望的那样)

但是当我使用法线贴图时,黑暗区域会变亮!

我想使用法线贴图并且仍然像这些示例一样获得正确的漫射照明

这里是有和没有法线映射的代码

这是使用法线贴图的代码

顶点着色器

varying vec3 normal,lightDir;
attribute vec3 vertex,normalVec,tangent;
attribute vec2 UV;

void main(){

gl_TexCoord[0] = gl_TextureMatrix[0] * vec4(UV,0.0,0.0);
normal = normalize (gl_NormalMatrix * normalVec);
vec3 t = normalize (gl_NormalMatrix * tangent);
vec3 b = cross (normal, t);
vec3 vertexPosition = normalize(vec3(gl_ModelViewMatrix * vec4(vertex,1.0)));
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, normal);
lightDir = normalize (v);
lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);
gl_Position = gl_ModelViewProjectionMatrix*vec4(vertex,1.0);
}

片段着色器

vec4 computeDiffuseLight (const in vec3 direction, const in vec4 lightcolor, const in vec3 normal, const in vec4 mydiffuse){

float nDotL = dot(normal, direction);
vec4 lambert = mydiffuse * lightcolor * max (nDotL, 0.0);
return lambert;
}

varying vec3 normal,lightDir;
uniform sampler2D textures[8];

void main(){
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
vec4 diffuse = computeDiffuseLight (lightDir, vec4(1,1,1,1) , normalVector, vec4(0.7,0.7,0.7,0));
gl_FragColor = diffuse ;
}

注意:如镜面高光所示,实际的法线贴图可以正常工作

我使用 Assimp 加载模型 (md5mesh) 并使用 Assimp 计算切线,然后将其作为属性发送到着色器

这里是问题代码和截图的链接

https://dl.dropboxusercontent.com/u/32670019/code%20and%20screenshots.zip

这是代码中的问题还是我有误解?

更新的代码和屏幕截图

https://dl.dropboxusercontent.com/u/32670019/updated%20code%20and%20screenshots.zip

现在法线贴图可以与漫反射一起使用,但单独使用漫反射是不正确的

【问题讨论】:

  • 你的#version指令在哪里?
  • 哦,我忘了包括它们,我使用的是 1.10,我会包括它们谢谢 :)

标签: opengl glsl shader assimp bump-mapping


【解决方案1】:

答案见下文。

快速(可能是错误的)观察: 线

vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );

在您的片段着色器中正确地重新调整您的法线以允许负值。如果你的法线贴图不正确,负值可能会出现在你不想要的地方(我假设你的 Y 轴)。法线中的负值会导致反光。

我的问题是:你的法线贴图正确吗?

回答:经过一番讨论,我们发现了问题,我编辑了这篇文章以保持线程干净,Darko 问题的解决方案在这里的 cmets 中。它归结为未初始化的变量,称为 lightDir。

原评论:

lightDir = 归一化 (v); lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);这很奇怪,你立即覆盖它,这是不对的吗?您似乎没有保留正确翻译的 lightDir ...或者我疯了...而且这个 lightDir 是变化的,但您根本没有设置它。所以你从零开始计算一个 v 向量?

【讨论】:

  • 不错的观察 =],但是法线贴图是正确的,我已经从工作示例中尝试了许多法线贴图,我使用的法线贴图与“原始”屏幕截图使用的法线贴图相同
  • 现在我可以发表评论 :),请在此处以及 zip 中上传您的非正常着色器代码,它似乎丢失了。
  • 我会打印(输出)法线、切线和双切线作为颜色,我认为它们不正确并且不能正确转换为切线空间。如果您仔细观察,凹凸贴图阴影也不正确。
  • =D,我想我做到了,zip 文件中不是有 4 个源文件和 4 个图像吗? ,它被称为“withoutNormalMap”
  • lightDir = normalize (v); lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);这很奇怪,你立即覆盖它,这是不对的吗?您似乎没有保留正确翻译的 lightDir ...或者我疯了...而且这个 lightDir 是变化的,但您根本没有设置它。所以你从无到有计算一个 v 向量?
猜你喜欢
  • 2013-08-14
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多