【问题标题】:Surface Normals OpenGL曲面法线 OpenGL
【发布时间】:2015-01-11 04:04:24
【问题描述】:

所以,我仍在开发 OpenGL ES 2.0 地形渲染程序。 我在山脊顶部发生了奇怪的绘图。我猜这是因为没有应用表面法线。

所以,我计算了法线。 我知道在其他版本的 OpenGL 中,您只需激活普通数组,它将用于剔除。 要在 OpenGL ES 中使用法线,我可以只激活法线还是必须在着色器中使用光照算法?

谢谢

【问题讨论】:

  • 你能提供任何截图吗?
  • 在 SO 上,计算机图形学更像是一个利基市场。但是,对于经验丰富的开发人员来说,一张图片可能会告诉一千多个单词。

标签: opengl-es


【解决方案1】:

OpenGL 不使用法线进行剔除。它根据投影三角形的顶点是顺时针还是逆时针排列来进行剔除。具体决定基于 (i) 您所说的哪种方式被认为是通过glFrontFace 面向前方的; (ii) 您要求通过glCullFace 剔除哪个正面和/或背面三角形; (iii) 是否通过glEnable/glDisable 启用剔除。

剔除在 ES 1.x 和 2.x 中是相同的。这是一个固定的硬件功能。它在可编程管道之外(事实上,在 ES 2.x 可编程管道中很难重现,因为没有对每个三角形进行监督的着色器)。

如果您没有启用剔除,那么您更有可能在山脊处看到深度缓冲冲突,因为背面朝向相机的脸部和正面朝向相机的脸部在山脊附近的深度非常相似并且有限的精度会使它们无法正确区分。

ES 1.x 中的光照是根据法线计算的。逐顶点光照会在硬脊处产生奇怪的问题,因为顶点的法线通常是在该顶点连接的面的平均值,例如形状像\/\/\/\/\ 的固定网格最终在每个顶点处具有完全相同的法线。但是,如果您不使用 1.x,那么就不会发生这种情况。

要在 ES 2.x 中实现光照,您需要在着色器中执行此操作。因此,由于法线没有用于任何其他目的,因此没有正式的方法可以将法线指定为任何特殊的东西。它们只是另一个顶点属性,您可以随意使用它们。

【讨论】:

  • 我使用的是 ES 2.0。我确实启用了剔除,并且我的缠绕顺序很好。有趣的是,在 1.0 中,光照是根据法线计算的。我听说过一些关于 Z 战斗的事情,这可能是个问题。
  • ... 在这种情况下,后续问题将是您的投影矩阵是否尽可能最大程度地使用可用的深度范围,如果您正在做地形,它是否排列得足够常规模式(例如,它是一个高度图),您可以在没有深度缓冲区的情况下正确渲染它。如果是这样,那么可能最聪明的事情可能是用正确的值填充深度缓冲区,然后用轻微的偏移从后到前渲染。所以front仍然在有歧义的地方透支,但启动希望丢弃大部分昂贵的片段计算。
  • (在实际绘制过程中禁用了深度写入,因此您可以照常渲染非地形对象)
  • 我的地形以足够规则的模式排列,因为它们是高度图文件中以米为单位的 z 值。 “用正确的值填充深度缓冲区,然后用轻微的偏移从后到前渲染”是什么意思?另一方面:在构建投影矩阵时更精确地计算近端和远端剪裁平面是否会增加深度缓冲区的精度?
  • 如果您在没有深度缓冲区的情况下从前到后渲染,您将获得正确的视图,但您将在片段着色上花费很多时间来处理许多从未见过的片段。如果您首先使用完全简单的着色器进行绘制(并且 glColorMask 设置为禁用某些东西),那么您会将正确的值放入深度缓冲区。如果您在启用深度测试、正常着色器和轻微的glPolygonOffset 的情况下从后到前绘制,那么您将获得正确的绘制顺序,大多数不可见片段将被丢弃而不进行处理。
猜你喜欢
  • 2018-11-21
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多