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

8

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

对于法线贴图还不太熟悉,我通过Sobel算子和法线贴图生成(主要感谢这里)来理解如何从像素数据的(2D)数组创建法线数据的(2D)数组。

大部分教程和论坛帖子都是关于3D应用和建模软件的,我想在C++中自己实现这个功能。

  • 获得法线贴图后我该怎么做?
  • 需要将它注册到OpenGL吗?
  • 如果需要与纹理关联,应该如何实现?
  • 如何将它映射到2D纹理四边形上?
  • (是否可以在没有着色器/GLSL的情况下完成?)
3个回答

6
一旦获得了法线贴图,接下来该怎么做?
需要将其作为纹理进行加载。
它需要与纹理相关联吗?如果是的话,如何实现?
如果你指的是与颜色纹理相关联,那么不需要。你需要创建一个纹理,其中包含法线贴图,以便之后在OpenGl中使用。
它如何映射到二维纹理四边形上?
你的法线贴图只是另一种纹理,你可以像任何其他纹理一样绑定并映射它。
法线贴图以切线空间坐标存储法线,因此要计算每个像素的光照,您需要知道切线空间坐标系中光源的相对位置。这是通过每个顶点设置附加参数(法线、切线、双切线),计算光源在切线空间坐标中的位置并沿三角形插值此位置来完成的。在片段着色器中,您查找法线贴图中的法线,并基于插值参数执行所需的光照计算。
(我可以在没有着色器/GLSL的情况下完成吗?)
是的,您可以使用一些传统扩展来编程多纹理环境组合函数。我自己从没做过,但看起来很麻烦。

很好,多重纹理是我想要的(是的,我会选择着色器=))。谢谢! - zyndor

6

我建议你看一下:

这篇关于凹凸贴图的英伟达演示文稿

虽然我有一段时间没有看过它了,但我记得它涵盖了实现凹凸贴图着色器的大部分细节,应该会给你一些启示。

这个使用cg着色语言实现凹凸贴图的英伟达教程

这个凹凸贴图教程也可能会有所帮助

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

此外,虽然着色器语言存在差异,但如果您想使用GLSL,将公式转换成其他语言也不应该太难。

正如ybungalobill所说,你可以不使用着色器,但除非你正在进行教育项目(为了你的教育)或特定的嵌入式设备,否则我不知道你为什么要这样做,但如果你确实需要这里是你需要查看的地方,它是在着色器出现之前编写的,并在后来更新以引用它们。


谢谢,nVidia和3DKingdoms的演示非常棒。我看过paulsprojects的视频,但当它开始涉及立方体贴图时,我就有点迷糊了。 - zyndor

1
这个话题很老了,但我会回答任何寻求帮助的初学者:
1)和2)
您的法线贴图就像普通的漫反射纹理一样,您需要从磁盘加载它,像处理漫反射纹理一样创建您的Texture2D,并将其锁定与其他纹理一起发送到着色器。因此,总的来说,当您在CPU端处理法线贴图、高度贴图等时,它们并没有什么不同...您总是需要加载它们、创建纹理并锁定它们。
3)
法线贴图只是一种在纹理中存储每个片段法线的方法。最好与相应的漫反射纹理一起使用,因为这是您可以伪造小细节的方式。然而,在某些情况下并不总是必要的...例如,上次我正在研究一种渲染水的方法...我使用了一个dudv贴图和一个法线贴图,但没有使用相应的漫反射贴图,因为我使用渲染到纹理以实现反射。
4)
法线贴图与漫反射纹理使用相同的纹理坐标映射...这意味着如果您有一个四边形,它的坐标是0;0,0;1,1;0,1;1,那么这些就是您用来映射两个纹理的坐标。
5)

我想你可以不使用着色器来完成,如果需要的话,甚至可以不使用OpenGL... 着色器是为这些操作设计的,使用着色器将更容易。

所以,法线贴图是将法线向量编码成颜色的纹理... 法线向量是一个三维向量,而颜色也是三维向量。当你使用光照时,通常会从顶点着色器将法线发送到片段着色器,片段着色器将插值得到像素自己的法线向量的近似值。这是默认设置...

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接