如何在 OpenGL 中应用法线贴图?

Posted

技术标签:

【中文标题】如何在 OpenGL 中应用法线贴图?【英文标题】:How to apply a normal map in OpenGL? 【发布时间】:2010-09-26 14:32:19 【问题描述】:

我正在学习在 OpenGL 的 2D 图形中使用法线贴图(按像素照明?)。

法线贴图的新手,我设法围绕 Sobel 运算符和法线贴图的生成(主要感谢 this),即从(2D)数组创建法线(2D)数组像素数据。

(我发现的大多数教程和论坛帖子都专门针对 3D 用途和建模软件。我的目标是自己用 C++ 实现这个功能。)

恢复正常后该怎么办 地图? 我需要注册吗 OpenGL? 是否需要关联 与纹理,如果是,它是如何 完成了吗? 如何映射到二维 纹理四边形? (这是不是 我可以不用着色器/GLSL 吗?)

【问题讨论】:

【参考方案1】:

我建议你看看:

This nvidia presentation on bumb mapping

我有一段时间没看这个了,但我记得它回顾了实现凹凸贴图着色器的大部分细节,应该会产生一些想法。

This other nvidia tutorial for implementing bump mapping in the cg shader langauge

This bump mapping tutorial might also be helpful.

我知道所有这些都不适用于完整的法线贴图,但它们是一个好的开始。

此外,虽然着色器语言存在差异,但如果您想使用 GLSL,在它们之间转换公式应该不难。

正如 ybungalobill 所说,你可以在没有着色器的情况下做到这一点,但除非你正在从事教育项目(你的教育)或特定的嵌入式设备,否则我不知道你为什么想要到 - 但如果您确实需要 this 是您想要查看的位置,它是在着色器之前编写的,并在以后更新以引用它们。

【讨论】:

谢谢,nVidia 演示文稿和 3DKingdoms 演示文稿很棒。我看过 paulsprojects 之一,但是当它在立方体贴图上开始时我迷路了。【参考方案2】:
获得法线贴图后该怎么办? 我需要向 OpenGL 注册它吗?

是的,您需要将其作为纹理加载。

是否需要与纹理相关联,如果需要,如何实现?

如果您的意思是与颜色纹理相关联,那么不会。您需要创建一个包含法线贴图的纹理,以便稍后在 OpenGL 中使用它。

它如何映射到 2D 纹理四边形?

您的法线贴图只是另一个纹理,您将其绑定并映射为任何其他纹理。

法线贴图将法线存储在切线空间坐标中,因此要计算每个像素的光照,您需要知道光源在切线空间坐标系中的相对位置。这是通过为每个顶点设置附加参数(法线、切线、副法线)、计算切线空间坐标中的光源位置并沿三角形内插该位置来完成的。在片段着色器中,您在法线贴图中查找法线并根据插值参数执行所需的光照计算。

(这是我可以在没有着色器/GLSL 的情况下做的事情吗?)

是的,您可以使用一些遗留扩展程序来编写多纹理环境组合功能。我自己从来没有做过,但看起来很糟糕。

【讨论】:

太好了,多纹理是我的想法(是的,我将使用 shaders=))。谢谢!【参考方案3】:

这个话题很老了,但我会为任何可以在这里寻求帮助的初学者回答这个问题:

1) & 2)

您的法线贴图就像一个常规的漫反射纹理,您需要从磁盘加载它,像使用漫反射纹理一样创建您的纹理 2D,然后将其与其他纹理锁定以将其发送到着色器。 总而言之,法线贴图、高度贴图等在处理 CPU 端时并没有什么不同……它总是在加载它们、创建纹理并锁定它们。

3)

法线贴图只是将每个片段的法线存储在纹理中的一种方式。 最好将它们与相应的漫反射纹理一起使用,因为这是您可以伪造小细节的方式。 然而,在某些情况下并不总是需要...例如,上次我正在研究一种渲染水的方法...我使用了一个 dudv 贴图和一个法线贴图,但不是对应的漫反射贴图,就像我使用的那样渲染成纹理以实现反射。

4)

法线贴图使用与漫反射纹理相同的纹理坐标进行映射... 这意味着如果您有一个四边形,其坐标为 0;0 , 0;1 , 1;0 , 1;1 这些是您用来映射两种纹理的坐标。

5)

我猜你可以不使用着色器来做到这一点……如果你愿意的话,你甚至可以不使用 OpenGL……着色器是为这类操作而设计的,使用着色器会更容易做到这一点。

所以,法线贴图是将法线向量编码为颜色的纹理... 法线向量是 3D 向量,颜色也是 3D 向量。 当您使用光照时,您通常将法线从顶点着色器发送到片段着色器......片段着色器将插入顶点法线的值以找出像素自身法线向量的近似值。 这是默认完成的...

使用法线贴图,您不使用顶点法线向量,而是使用纹理中编码的法线向量。

首先,您必须将光照计算从世界空间转换为切线空间。这是在顶点着色器中完成的。

然后,您将像通常的纹理一样在片段着色器中对法线贴图进行采样。您将获得像素的 RGB 颜色。 您必须将该值转换为法线向量,即,将其乘以 2 并减去 1,即 rgb*2 - 1,然后将其用作照明计算中的法线向量。

【讨论】:

以上是关于如何在 OpenGL 中应用法线贴图?的主要内容,如果未能解决你的问题,请参考以下文章

用于 SceneKit 内容的正确法线贴图格式 - DirectX 还是 OpenGL?

计算机图形学(OPENGL):法线贴图

一步步学OpenGL 26-《法线贴图》

ZBrush功能特性之法线贴图

✠OpenGL-10-增强表面细节

在Unity里添加2D法线贴图 NormalMap