什么是 DOT3 照明?
Posted
技术标签:
【中文标题】什么是 DOT3 照明?【英文标题】:What is DOT3 lighting? 【发布时间】:2009-12-12 18:49:29 【问题描述】:对my question 的回答表明,DOT3 光照可以帮助进行 OpenGL ES 渲染,但我很难找到 DOT3 光照的正确定义。
编辑 1
非常感谢您提供 iPhone 相关信息。
【问题讨论】:
【参考方案1】:DOT3 光照通常被称为逐像素光照。使用顶点光照计算每个顶点的光照,并在三角形上插值得到光照。逐像素光照,顾名思义,就是计算每个像素的光照。
这是在固定功能硬件上完成的,就像 iPhone 使用所谓的寄存器组合器一样。 DOT3 的名字来源于这个渲染状态:
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
查看 Wolfgang Engels 博客上的 this 博客条目,了解有关如何设置的更多信息。
在进行逐像素光照时,也很流行使用所谓的normal map。这意味着对象上每个点的法线都存储在一个特殊的纹理贴图中,即法线贴图。这在游戏 DOOM 3 中由 ID 软件推广,其中使用了相当低的多边形模型,但具有高分辨率的法线贴图。使用这种技术的原因是眼睛对光线变化比对形状变化更敏感。
我在您的另一个问题中看到,出现此问题的原因是您想减少顶点数据的内存占用。确实如此,您只需将纹理坐标的两个分量存储到法线贴图,而不是在每个顶点中为法线存储三个分量。启用每像素照明会带来性能成本,所以我不确定这是否会带来净收益,通常建议是尝试看看。
最后,一个点的漫反射光照强度与表面法线和光的方向之间的夹角的余弦成正比。对于两个向量,dot product 被定义为:
a dot b = |a||b| cos(theta)
其中|a|
和|b|
分别是向量a
和b
的长度,theta
是它们之间的角度。如果长度等于1,|a|
和|b|
被称为单位向量,公式简化为:
a dot b = cos(theta)
这意味着漫反射光照强度由表面法线和光的方向之间的点积给出。这意味着所有漫反射照明是 DOT3 照明的一种形式,即使名称已经指代每像素类型。
【讨论】:
DOT3 照明是否仍然适用于不断变化的视点?法线需要通过逆模型视图矩阵(根据您的观点而变化)进行转换。使用 DOT3 的基于纹理的照明,没有任何变换! @prideout 不是转换法线,而是将光的方向转换到法线贴图的空间中。这可以在 GPU(如果您有着色器)上完成,也可以在 CPU 上完成(如果您使用的是固定功能硬件)。【参考方案2】:来自here:
凹凸贴图是将纹理放在模型上,其中每个纹理像素的亮度定义了该纹理像素的高度。
然后使用每个纹素的高度来扰动整个表面的光照。
法线贴图是在模型上放置纹理,其中每个纹素的颜色实际上是三个值,这些值定义了表面点上的位置方向。
例如,颜色为 (255, 0, 0),可能意味着该位置的表面指向正 X 轴。
换句话说,每个纹素都是一个法线。
Dot3 名称来源于您对这些法线的实际操作。
假设您有一个向量,它指向您的光源指向的方向。假设你有一个向量,它是模型上特定纹素的法线,它告诉你纹素指向哪个方向。
如果你对这两个法向量做一个称为“点积”的简单数学方程,如下所示:
点 = N1xN2x + N1yN2y + N1z*N2z
然后结果值是一个数字,它告诉您这两个向量指向同一方向的程度。
如果值为-1,则它们指向相反的方向,这实际上意味着texel指向光源,而光源指向texel,所以应该点亮texel。
如果值为 1,则它们指向同一方向,这意味着纹素指向远离光源。
如果值为 0,则其中一个向量相对于另一个向量指向 90 度。即:如果您站在地面上向前看,那么您的视图矢量相对于指向上方的地面法线是 90 度。
【讨论】:
以上是关于什么是 DOT3 照明?的主要内容,如果未能解决你的问题,请参考以下文章