光照在 OpenGL 中不显示

Posted

技术标签:

【中文标题】光照在 OpenGL 中不显示【英文标题】:Lighting doesn't show in OpenGL 【发布时间】:2014-03-16 20:47:59 【问题描述】:

我正在尝试使用我的教科书示例在 OpenGL 中进行点源定向照明。我正在显示一个以原点为中心的矩形,并在着色器中进行照明计算。矩形出现,但即使我尝试在其上放置彩色灯,它也是黑色的。矩形的法线都是 (0, 1.0, 0)。我没有做任何非均匀缩放,所以常规模型视图矩阵也应该转换法线。

我有代码为着色器设置灯光参数(作为制服)和材质参数(也作为制服)。没有每个顶点的颜色信息。

void InitMaterial()

    color material_ambient = color(1.0, 0.0, 1.0);
    color material_diffuse = color(1.0, 0.8, 0.0);
    color material_specular = color(1.0, 0.8, 0.0);
    float material_shininess = 100.0;

    // set uniforms for current program
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "materialAmbient"), 1, material_ambient);
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "materialDiffuse"), 1, material_diffuse);
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "materialSpecular"), 1, material_specular);
    glUniform1f(glGetUniformLocation(Programs[lightingType], "shininess"), material_shininess);

对于灯:

void InitLight()

    // need light direction and light position
    point4 light_position = point4(0.0, 0.0, -1.0, 0.0);
    color light_ambient = color(0.2, 0.2, 0.2);
    color light_diffuse = color(1.0, 1.0, 1.0);
    color light_specular = color(1.0, 1.0, 1.0);

    glUniform3fv(glGetUniformLocation(Programs[lightingType], "lightPosition"), 1, light_position);
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "lightAmbient"), 1, light_ambient);
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "lightDiffuse"), 1, light_diffuse);
    glUniform3fv(glGetUniformLocation(Programs[lightingType], "lightSpecular"), 1, light_specular);

片段着色器是一种简单的直通着色器,它将颜色设置为来自顶点着色器的一个输入。这是顶点着色器:

#version 150 

in vec4 vPosition;
in vec3 vNormal;
out vec4 color;

uniform vec4 materialAmbient, materialDiffuse, materialSpecular;
uniform vec4 lightAmbient, lightDiffuse, lightSpecular;
uniform float shininess;

uniform mat4 modelView;
uniform vec4 lightPosition;
uniform mat4 projection;

void main() 

    // Transform vertex position into eye coordinates
    vec3 pos = (modelView * vPosition).xyz;

    vec3 L = normalize(lightPosition.xyz - pos);
    vec3 E = normalize(-pos);
    vec3 H = normalize(L + E);

    // Transform vertex normal into eye coordinates
    vec3 N = normalize(modelView * vec4(vNormal, 0.0)).xyz;

    // Compute terms in the illumination equation
    vec4 ambient = materialAmbient * lightAmbient;

    float Kd = max(dot(L, N), 0.0);
    vec4 diffuse = Kd * materialDiffuse * lightDiffuse;

    float Ks = pow(max(dot(N, H), 0.0), shininess);
    vec4 specular = Ks * materialSpecular * lightSpecular;

    if(dot(L, N) < 0.0) specular = vec4(0.0, 0.0, 0.0, 1.0);

    gl_Position = projection * modelView * vPosition;

    color = ambient + diffuse + specular;
    color.a = 1.0;
 

【问题讨论】:

您提到您的矩形具有 (0,1,0) 法线并且位于原点并且您的光位于 (0,0,-1) 这意味着您的光源垂直于您的对象,因此光矢量和法线的点积将为 0。您可以尝试移动光或矩形,看看是否有区别。 法线在模型空间是(0, 1, 0),但是光照位置是在眼睛空间。我尝试更改灯光位置无济于事。 我不太确定问题出在哪里,但您可以尝试一些不同的方法来缩小范围。首先要尝试将顶点着色器中的颜色变量设置为硬编码颜色,以验证颜色是否正确地从顶点传递到片段着色器。第二组要尝试的事情是分别检查照明的每个组件。首先将颜色设置为环境色,然后只是漫反射和镜面反射,以检查每个组件是否按预期计算。 谢谢,我试试看。 【参考方案1】:

好的,现在可以了。解决方案是用 glUniform4fv 替换 glUniform3fv,我猜是因为 glsl 对应物是 vec4 而不是 vec3。我以为它能够识别这一点并简单地在末尾添加一个 1.0,但没有。

【讨论】:

以上是关于光照在 OpenGL 中不显示的主要内容,如果未能解决你的问题,请参考以下文章

numpy.float128 在 windows 中不存在,但从 OpenGL 调用

C ++ OpenGL Cube未显示在屏幕上

openGL中不正确的遮挡,正面剔除

OpenGL 光照位置固定在不想要的位置

问题理解 OpenGL 中的光照

OpenGL植物建模(附完整代码注释清晰分步讲解)