2011-04-20 101 views
4

与之前发布的问题有些类似,我试图让法线在我的GLSL应用中正确显示。 为了我的解释,我使用随RenderMonkey提供的ninjaHead.obj模型进行测试(you can grab it here)。现在,在RenderMonkey的预览窗口中,一切看起来不错: RenderMonkey 分别产生的顶点和片段代码:GLSL法线效果奇怪

顶点:

uniform vec4 view_position; 

varying vec3 vNormal; 
varying vec3 vViewVec; 

void main(void) 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 

    // World-space lighting 
    vNormal = gl_Normal; 
    vViewVec = view_position.xyz - gl_Vertex.xyz; 
} 

片段:

uniform vec4 color; 

varying vec3 vNormal; 
varying vec3 vViewVec; 

void main(void) 
{ 
    float v = 0.5 * (1.0 + dot(normalize(vViewVec), vNormal)); 
    gl_FragColor = v* color; 
} 

我根据我的GLSL代码,但我没有得到预期的结果...

My verte X shader代码:

uniform mat4 P; 
uniform mat4 modelRotationMatrix; 
uniform mat4 modelScaleMatrix; 
uniform mat4 modelTranslationMatrix; 
uniform vec3 cameraPosition; 

varying vec4 vNormal; 
varying vec4 vViewVec; 

void main() 
{ 
vec4 pos = gl_ProjectionMatrix * P * modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * gl_Vertex; 

gl_Position = pos; 

gl_TexCoord[0] = gl_MultiTexCoord0; 

gl_FrontColor = gl_Color; 

vec4 normal4 = vec4(gl_Normal.x,gl_Normal.y,gl_Normal.z,0);  

// World-space lighting 
    vNormal = normal4*modelRotationMatrix; 
    vec4 tempCameraPos = vec4(cameraPosition.x,cameraPosition.y,cameraPosition.z,0);  
    //vViewVec = cameraPosition.xyz - pos.xyz; 
    vViewVec = tempCameraPos - pos; 
} 

我的片段着色器代码:

varying vec4 vNormal; 
varying vec4 vViewVec; 

void main() 
{ 
    //gl_FragColor = gl_Color; 
    float v = 0.5 * (1.0 + dot(normalize(vViewVec), vNormal)); 
gl_FragColor = v * gl_Color; 
} 

但是我的渲染产生这个... openGL render

有谁知道什么可能导致这个和/或如何让它起作用?

编辑 针对kvark的评论,在这里是没有任何正常/照明计算显示所呈现的所有三角形渲染模型。 Render flat shading

这里是与用于颜色的法线的模型着色。我相信问题已经找到!现在的原因是它为什么呈现这样以及如何解决它?欢迎提出建议! Normal shading

SOLUTION 好大家的问题已经解决了!感谢kvark对他所有有用的见解,这绝对有助于我的编程练习,但恐怕答案来自于我是一个大规模的山雀......我的代码的display()函数有一个错误,它将glNormalPointer偏移量到一个随机值。它曾经是这样的:

gl.glEnableClientState(GL.GL_NORMAL_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getNormalsBufferObject()); 
gl.glNormalPointer(GL.GL_FLOAT, 0, getNormalsBufferObject()); 

但应该是这样的:

gl.glEnableClientState(GL.GL_NORMAL_ARRAY); 
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getNormalsBufferObject()); 
gl.glNormalPointer(GL.GL_FLOAT, 0, 0); 

所以我想这是一个教训。永远不要盲目地按Ctrl + C和Ctrl + V代码来节省星期五下午的时间,并且...当你确定你正在查看的部分代码是正确的时,问题可能就在其他地方了!

+0

请始终指定您的OpenGL版本。在GLSL中使用'#version'指令也是一种好的做法。 – Kos 2011-04-23 12:58:19

+0

恭喜!最后:) – kvark 2011-05-03 14:45:31

+1

你应该从你的问题中删除解决方案,并添加它作为答案(如果它真的解决了你的问题,接受它)。 – murgatroid99 2011-09-19 02:05:37

回答

1
  1. 什么是您的P矩阵? (我想这是一个世界 - >相机视图变换)。

  2. vNormal = normal4*modelRotationMatrix;你为什么改变参数的顺序?这样做是通过反转旋转来增加法线,这是你并不真正想要的。改用标准订单(modelRotationMatrix * normal4)

  3. vViewVec = tempCameraPos - pos。这完全不正确。 pos是你的顶点在齐次剪辑空间,而tempCameraPos是在世界空间(我想)。您需要将结果放在与法线(世界空间)相同的空间中,因此对于该方程使用世界空间顶点位置(modelTranslationMatrix * modelRotationMatrix * modelScaleMatrix * gl_Vertex)。

+0

感谢您的回复。是的,P确实是世界相机矩阵。我已经对(2)和(3)中提出的修改进行了修改,但没有可见的变化。我无法弄清楚发生了什么事! – 2011-04-21 10:28:52

+0

@克里斯罗宾逊。你的屏幕截图显示一些三角形根本没有绘制。你能用恒定的颜色填充模型来检查这个吗? – kvark 2011-04-21 12:56:12

+0

@kvark当我没有法线渲染时(即平面着色),模型确实被填充并且所有三角形都被渲染。 – 2011-04-21 14:55:24

0

您似乎在混合GL版本有点?您正通过制服手动传递矩阵,但使用固定函数传递顶点属性。嗯。无论如何...


我真诚地不喜欢你在做什么你的法线。看看:

vec4 normal4 = vec4(gl_Normal.x,gl_Normal.y,gl_Normal.z,0);  

vNormal = normal4*modelRotationMatrix; 

一个正常只存储方向性数据,为什么使用它一个vec4它?我相信只要使用vec3就更加优雅。此外,看看接下来会发生什么 - 将法线与4x4模型旋转矩阵相乘...此外,您的法线的第四个坐标等于0,因此它不是均匀坐标中的正确矢量。我不确定这是否是主要问题,但如果这种乘法会给你带来垃圾,我不会感到惊讶。

变换法线的标准方法是将vec3乘以模型视图矩阵的3x3子矩阵(因为您只对方向感兴趣,而不是翻译)。那么,“正确”的方法就是使用该3x3子矩阵的逆转置(当你缩放时这变得很重要)。在旧的OpenGL版本中,它预先计算为gl_NormalMatrix

因此,而不是上面的,你应该使用类似

// (...) 
varying vec3 vNormal; 
// (...) 

mat3 normalMatrix = transpose(inverse(mat3(modelRotationMatrix))); 
// or if you don't need scaling, this one should work too- 
mat3 normalMatrix = mat3(modelRotationMatrix); 

vNormal = gl_Normal*normalMatrix; 

这肯定一件事在你的代码来解决 - 我希望它可以解决你的问题。