实现每个顶点的漫反射着色器,不起作用

Posted

技术标签:

【中文标题】实现每个顶点的漫反射着色器,不起作用【英文标题】:Implementing diffuse per-vertex shader, not working 【发布时间】:2012-09-21 18:28:51 【问题描述】:

我正在实现 OpenGL 4.0 Shading Language Cookbook 中的逐顶点漫反射着色器,但为了适合我的项目,我做了些许修改。

这是我的顶点着色器代码:

layout(location = 0) in vec4 vertexCoord;
layout(location = 1) in vec3 vertexNormal;

uniform vec4 position; // Light position, initalized to vec4(100, 100, 100, 1)
uniform vec3 diffuseReflectivity; // Initialized to vec3(0.8, 0.2, 0.7)
uniform vec3 sourceIntensity; // Initialized to vec3(0.9, 1, 0.3)

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

out vec3 LightIntensity;

void main(void) 
    // model should be the normalMatrix here in case that
    // non-uniform scaling has been applied.
    vec3 tnorm = normalize(vec3(model * vec4(vertexNormal, 0.0)));

    // Convert to eye/camera space
    vec4 eyeCoordsLightPos = view * model * position;
    vec4 eyeCoords = view * model * vertexCoord;
    vec3 s = normalize(vec3(eyeCoordsLightPos - eyeCoords));

    // Diffuse shading equation
    LightIntensity = sourceIntensity * diffuseReflectivity * max(dot(s,tnorm), 0.0);

    gl_Position = projection * view * model * vertexCoord;

这是我的片段着色器:

in vec3 LightIntensity;

layout(location = 0) out vec4 FragColor;

void main()
    FragColor = vec4(LightIntensity, 1.0);

我正在渲染一个盒子,我有所有法线的值。然而,盒子只是黑色的。 假设我的制服在渲染时设置正确,我的着色器代码有什么明显错误吗?

与书中的代码相比,我所做的改变是我将模型矩阵用作普通矩阵,并且我在模型空间中传递了我的光照位置,但在着色器中将其转换为相机空间。 em>

渲染的图像,不要被作为纹理的阴影背景混淆:

在片段着色器中使用FragColor = vec4(f_vertexNormal, 1.0); 渲染时的图片:

在眼睛空间建议中使用 tnorm 更新代码:

void main(void) 
    // model should be the normalMatrix here in case that
    // non-uniform scaling has been applied.
    vec3 tnorm = normalize(vec3(model * vec4(vertexNormal, 0.0)));

    // Convert to eye/camera space
    vec3 eyeTnorm = vec3(view * vec4(tnorm, 0.0));
    vec4 eyeCoordsLightPos = view * position;
    vec4 eyeCoords = view * model * vertexCoord;
    vec3 s = normalize(vec3(eyeCoordsLightPos - eyeCoords));

    // Diffuse shading equation
    LightIntensity = sourceIntensity * diffuseReflectivity * max(dot(s,eyeTnorm), 0.0);

    gl_Position = projection * view * model * vertexCoord;
    f_vertexNormal = vertexNormal;

【问题讨论】:

你试过输出一些中间信号吗?如果你用s给盒子上色,它是黑色的吗?如果你用vertexNormal给盒子上色,它是黑色的吗?另外,您会通过模型矩阵转换灯光位置,这对我来说似乎有点奇怪,尽管我认为这不一定会导致它不起作用。 添加了一张我使用顶点法线作为颜色的图片。在我看来是正确的。我同意模型矩阵,不一定。 【参考方案1】:

除了我上面的评论,你dot-ing 一个世界空间矢量tnorm 和一个眼睛空间矢量s。您应该只在同一空间中点向量。因此,您可能还需要考虑将tnorm 转换为眼睛空间。

【讨论】:

我想你的意思是 tnorm 不是 tvec?书中是这样写的:vec3 tnorm = normalize(NormalMatrix * VertexNormal) 添加了一个新代码 sn-p 我将 tnorm 转换为眼睛空间。仍然是相同的黑色结果。 是的,你说得对,我的意思是tnorm,对不起。在书中,我假设 NormalMatrix 是将法线转换为眼睛空间的矩阵,类似于模型视图矩阵。在您的情况下,虽然 normalMatrix 只是转变为世界空间。 @toeplitz 假设我的制服在渲染时设置正确你真的验证了吗?这是一个很大的假设。 我将 tnorm 转换为眼睛空间的更新代码怎么样?

以上是关于实现每个顶点的漫反射着色器,不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Phong 着色器不起作用

OpenGL First Cube渲染不起作用

OpenGL第一个立方体渲染不起作用

vTextCoord 值不起作用 - c# OPENTK

OpenGL,漫反射着色器

此像素着色器中的漫反射和镜面反射