我正在学习使用OpenGL在2D图形中使用法线贴图(每像素光照?)。
新的法线贴图,我设法绕过Sobel算子并生成法线贴图(主要归功于this),即从(2D)创建(2D)法线数组像素数据数组。
(我发现的大多数教程和论坛帖子都是针对3D使用和建模软件的。我的目标是在C ++中自己实现这个功能。)
答案 0 :(得分:6)
我建议你看看:
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所说,你可以在没有着色器的情况下做到这一点,但除非你正在从事教育项目(你的教育)或特定的嵌入式设备,否则我不知道你为什么要这么做to - 但是如果你确实需要this在你想看的地方,那就是在着色器之前编写,并在以后更新以引用它们。
答案 1 :(得分:5)
- 一旦我得到了正常的地图,我该怎么办?
- 我是否需要在OpenGL中注册?
是的,您需要将其作为纹理加载。
- 是否需要与纹理相关联,如果是,它是如何完成的?
如果你的意思是与颜色纹理相关联,那么没有。您需要创建一个包含法线贴图的纹理,以便稍后在OpenGl中使用它。
- 如何映射到2D纹理四边形?
你的普通地图只是另一种纹理,你可以将它绑定并映射为任何其他纹理。
法线贴图将法线存储在切线空间坐标中,因此要计算每个像素的光照,您需要知道切线空间坐标系中光源的相对位置。这是通过为每个顶点设置附加参数(法线,切线,副法线),计算切线空间坐标中的光源位置并沿三角形插入此位置来完成的。在片段着色器中,您可以在法线贴图中查找法线,并根据插值参数执行所需的光照计算。
- (这是我可以在没有着色器/ GLSL的情况下做的事情吗?)
是的,您可以使用一些旧版扩展来编程多纹理环境组合功能。从来没有自己做过,但它看起来像地狱。
答案 2 :(得分:1)
这个话题已经很老了,但我会回答任何可以在这里寻求帮助的初学者:
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,然后将其用作光照计算中的法线向量。