You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用glium实现旋转立方体的全面光照效果

Glium旋转立方体单面着色问题排查思路

我用glium实现了一个旋转立方体,但目前只有一个面能呈现颜色。采用Gouraud着色实现光照效果,立方体由24个顶点、6个法线定义,旋转通过以下两个矩阵实现:

let m = [
    [1.0, 0.0, 0.0, 0.0],
    [0.0, t.cos(), -t.sin(), 0.0],
    [0.0, t.sin(), t.cos(), 0.0],
    [0.0, 0.0, 0.0, 1.0f32]
];

let n = [
    [t.cos(), 0.0, t.sin(), 0.0],
    [0.0, 1.0, 0.0, 0.0],
    [-t.sin(), 0.0, t.cos(), 0.0],
    [0.0, 0.0, 0.0, 1.0f32]
];

片段着色器代码如下:

#version 150

in vec3 v_normal;
out vec4 color;
uniform vec3 u_light;

void main() {
    float brightness = dot(normalize(v_normal), normalize(u_light));
    vec3 dark_color = vec3(0.6, 0.0, 0.0);
    vec3 regular_color = vec3(1.0, 0.0, 0.0);
    color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}

光源设置为:

let light = [-1.0, 0.4, 0.9f32];

理论上立方体旋转过程中光线应能照射到其他面,但调整光源方向后没有任何变化,以下是具体排查思路:

  • 检查法线的变换与传递逻辑
    Gouraud着色要求法线必须正确变换到对应空间(世界/视图空间)。顶点用模型矩阵变换时,法线需要用模型矩阵的逆转置矩阵进行变换(旋转矩阵的逆转置等于自身,但需确保逻辑正确)。同时要确认顶点着色器中,是否将变换后的法线正确传递给片段着色器的v_normal变量——如果顶点着色器只传递了原始法线、未做旋转变换,立方体旋转后法线方向仍保持初始状态,自然只有朝向原始光源的面会亮。

  • 验证顶点着色器的实现细节
    顶点着色器是关键环节,需确保两点:

    1. 顶点位置通过正确的矩阵组合(比如将m和n相乘得到最终模型矩阵)变换到裁剪空间;
    2. 法线经过逆转置矩阵变换后,赋值给v_normal输出到片段着色器。
  • 确保光源与法线的空间一致性
    要确认u_light的方向所处空间(世界空间/视图空间)与法线的空间完全匹配。如果立方体在世界空间旋转,但光源方向仍保留在局部空间,两者相对方向不会随立方体旋转改变,后续面自然无法被照亮。

  • 核对法线与顶点的绑定关系
    立方体24个顶点对应6个面法线,每个面的4个顶点应绑定同一个面法线。需检查顶点数据中,是否存在法线绑定错误(比如所有顶点共用同一个法线),这种情况会导致只有该法线朝向光源的面呈现颜色。

  • 修复片段着色器的亮度计算逻辑
    当法线与光源方向夹角大于90度时,brightness会为负数,mix函数会生成异常颜色。可以添加max函数限制亮度下限:

    float brightness = max(dot(normalize(v_normal), normalize(u_light)), 0.0);
    

    这样背面会稳定使用dark_color,避免异常显示。

  • 确认矩阵的组合应用方式
    目前有两个旋转矩阵m和n,需确认是否将二者相乘得到最终的模型矩阵,再用该矩阵变换顶点、用逆转置矩阵变换法线。如果分开应用矩阵但未正确组合,可能导致顶点旋转但法线未同步变换,或旋转方向逻辑错误。

内容的提问来源于stack exchange,提问作者matej.tydli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:37:00