3

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

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

但是,我只能获得均匀照明的面孔,而不能获得亮点。所以,我的问题是,真的有可能得到它吗?忘了提一下,我使用了最简单的三角剖分——每个面 2 个三角形。另一件事,我使用的是 OpenGL ES 1.1,所以没有着色器。

4

3 回答 3

2

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

这意味着,如果您对一个只有四个顶点的立方体进行建模,那么您将无法在面的中间获得一个明亮的反射点。立方体面照明将始终仅由两个渐变组成:两个三角形面各一个。

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

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

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

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

您可以注意到对象的几何形状非常粗糙(圆环上的每个补丁只有 9 个顶点),但是定义了光源反射,您甚至可以看到瓷砖地板的扭曲反射。

环境映射技巧

于 2014-01-19T09:02:06.340 回答
1

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

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

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

于 2014-01-19T08:35:02.320 回答
1

您的示例存在一些问题。

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

有一张很好的图片显示了这个问题的不同之处

http://i.stack.imgur.com/3udUJ.gif(来自冲野网)

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

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

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

于 2014-01-19T08:39:36.850 回答