【发布时间】:2026-01-04 01:20:03
【问题描述】:
由于与我之前遇到并发布过的问题有点相似,我试图让法线在我的 GLSL 应用程序中正确显示。 出于解释的目的,我使用 RenderMonkey 提供的 ninjaHead.obj 模型进行测试 (you can grab it here)。现在在 RenderMonkey 的预览窗口中,一切看起来都很棒: 分别生成的顶点和片段代码为:
顶点:
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 代码以此为基础,但我并没有完全得到预期的结果...
我的顶点着色器代码:
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;
}
但是我的渲染产生了这个......
有谁知道这可能是什么原因和/或如何使它起作用?
编辑 为了响应 kvark 的 cmets,这里是渲染的模型,没有任何法线/光照计算来显示所有正在渲染的三角形。
这里是带有用于颜色的法线的模型着色。相信问题已经找到了!现在的原因是为什么它被渲染成这样以及如何解决它?欢迎提出建议!
解决方案 好了大家问题都解决了!感谢 kvark 提供的所有有用的见解,这肯定有助于我的编程实践,但我担心答案来自我是一个巨大的山雀......我在设置 glNormalPointer 偏移量的代码的 display() 函数中有一个错误为随机值。以前是这样的:
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 代码来节省时间并且...当您确定您正在查看的代码部分是正确的时,问题可能出在其他地方!
【问题讨论】:
-
请务必指定您的 OpenGL 版本。在您的 GLSL 中使用
#version指令也是一个好习惯。 -
您应该从您的问题中删除解决方案并将其添加为答案(如果它确实解决了您的问题,请接受它)。