【问题标题】:Specular lights on cube in opengl esopengl es中立方体上的镜面光
【发布时间】:2014-01-19 08:12:53
【问题描述】:

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

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

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

【问题讨论】:

  • 发布您的相关代码。
  • 代码在这里没有帮助,但研究应该模拟的现象。
  • 非常感谢大家!对于这么长时间的中断感到抱歉。经过一些测试,我发现我在这里获得的两个提示都是正确的:首先,镜面光的位置离我的物体表面太远,其次,我的镶嵌太粗糙了。

标签: opengl-es 3d cube lighting specular


【解决方案1】:

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 个顶点),但是定义了光源反射,您甚至可以看到瓷砖地板的扭曲反射。

【讨论】:

    【解决方案2】:

    您的示例存在一些问题。

    您需要区分点光源和定向光源。你没有在你的问题中明确说明你使用的是什么(编辑:如果你的光的第四个坐标是 0,你会得到一个定向光,否则你会得到一个点光)

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

    (来自okino.com)

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多