在opengl es的立方体上的镜面光

时间:2014-01-19 08:12:54

标签: opengl-es 3d cube lighting specular

在一些引入照明的教程中,人们将从一个球体的例子开始,由三种类型的灯光点亮:环境光,漫反射光和镜面光。然后可以很容易地看到,例如通过关闭各个灯,周围的灯负责物体的均匀照明,漫反射灯来自特定方向,并且由于镜面光,我们可以观察到表面上的亮点。

我尝试用一​​个更简单的例子重复相同的步骤,一个用户可以任意旋转的立方体。我实际期望看到的是类似的图片:我认为OpenGL应该在某种程度上遵循几何光学规则,并且,如果指定了光源和相机的位置,那么其中一个应该只有一个亮点。立方体面,即将光源直接反射到相机上的面。

然而,我只能获得均匀照明的脸,而不是一个亮点。所以,我的问题是,它真的可以得到它吗?忘记提及,我使用了最简单的三角测量 - 每个面部有2个三角形。另一件事,我正在使用OpenGL ES 1.1,没有着色器。

3 个答案:

答案 0 :(得分:2)

OpenGL中的光照计算是按顶点计算的,然后在每个面的像素上线性地(可能使用透视校正)对结果进行插值。

这意味着如果您只使用四个顶点建立立方体,则无法在面部中间获得明亮的反射点。立方体面部照明将始终仅由两个渐变组成:一个用于两个三角形面中的每一个。

要近似每像素闪电,您需要细分许多小三角形中的面......或者您需要使用其他技术:例如使用“像素/片段着色器”来计算每像素闪电或纹理映射技巧模仿相同。

有关OpenGL ES上片段着色器的说明,请参阅http://www.learnopengles.com/android-lesson-three-moving-to-per-fragment-lighting/

使用纹理贴图技巧(通常称为“环境贴图”方法),甚至可以轻松模拟能够反映环境的令人信服的闪亮物体,而不仅仅是每个像素的光源。

http://raksy.dyndns.org/torus.html是一个Web画布演示,其中使用纹理映射技巧确实计算了闪亮的反射。实际上,代码完全不依赖于任何3d支持,只使用html5画布对象提供的2d变换矩阵绘制三角形。

您可以注意到物体几何形状非常粗糙(环面上的每个贴片只有9个顶点)但是光源反射被定义,您甚至可以看到平铺地板的扭曲反射。

environment mapping trick

答案 1 :(得分:1)

照明很大程度上取决于多维数据集每一侧的顶点数量。 由于您没有使用着色器,因此每个顶点都会对照明进行计算。但是计算取决于垂直于面定向的表面法线,并且每面计算3个顶点。法面对于每个顶点的每个顶点都是相同的,这就是为什么每个顶点的光强度也是相同的,所以你看不到任何灯光效果。 如果正确计算法线,则必须看到立方体不同边的颜色不同。 要在一侧获得某些光斑,您必须增加立方体每一侧的网格分辨率,并且必须为聚光灯的圆锥应用适当的角度,或者最小化聚光灯与立方体的距离。

            n1         n2
           /          /
          /          /
        v1 ---------- v2
         |         / 
         |       /
         |  n3 /    
         | / /
         |//
         |
        v3            v4

看看这个漂亮的教程。它以一种非常容易理解的方式解释了基本机制:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-8-basic-shading/

答案 2 :(得分:1)

您的示例存在一些问题。

您需要区分点光源和定向光源。您没有在您使用的问题中明确说明(编辑:如果光的第4个坐标为0,则获得定向光,否则您获得点光源)

有一张很好的图片显示this question

的差异

http://i.stack.imgur.com/3udUJ.gif(来自okino.com)

如果使用定向光源,那么当然,立方体一侧的所有点都将具有相同的光照计算,因此产生相同的颜色。如果您使用球体,则会获得高光。

如果你使用点光源,那么你会因为OpenGL(ES) - 固定的管道照明模型而遇到麻烦。它计算了每个顶点的光照。由于每个立方体侧面仅使用5个不同的顶点,因此您最终在光照方面几乎没有差异。你可以通过使用每像素照明着色器或将立方体细分为更小的三角形来解决这个问题。

当然还有一些小的“陷阱”,你需要确保你的不同灯光(光源和类型)在组合时不会发出太多光线,这会弄乱你的灯光。还要确保法线设置正确。