0

我在我的 opengl 4.3 着色器中更改镜面反射功率分量时遇到问题。当我使用介于 0-10 之间的光泽度值时,高光效果很好,但是,随着该值的增加以使材质更发光,光照强度会降低。这是我的代码:

    //Direct Lighting
vec3 L = normalize(worldPos.xyz - lightPos.xyz);
vec3 D = normalize(lightDir.xyz);
float dist = length(-L);
float I = max(dot(N.xyz, -L), 0.0);

vec3 h = normalize(-L.xyz + E);
float specLighting = 0.0;
specLighting = pow(max(dot(N.xyz, h), 0.0),50.0);

fColor.xyz = vec3(specLighting);

因此,如果将 shininess 值增加到 50 左右,则根本没有光照。顺便说一句,在这段代码中,我只显示镜面反射来调试问题。

[编辑] 很抱歉解释中缺乏细节,我附上了一些将镜面反射值从 1 更改为 7 的结果的屏幕截图。如您所见,随着镜面高光尺寸的减小(这就是我想要的),灯光也会变暗(这不是我想要的)。大约 10 分钟后,它会完全变黑。

顺便说一句,我完全在像素/片段着色器中执行此操作。

我还添加了来自我的 directx 11 测试引擎的屏幕截图,使用完全相同的代码进行镜面光照,但光泽系数为 100。

specLighting = pow(max(dot(N.xyz, h), 0.0),1.0);

specLighting = pow(max(dot(N.xyz, h), 0.0),2.0);

specLighting = pow(max(dot(N.xyz, h), 0.0),3.0);

specLighting = pow(max(dot(N.xyz, h), 0.0),5.0);

specLighting = pow(max(dot(N.xyz, h), 0.0),7.0);

directx 11 高光

直连 11:

4

4 回答 4

3

如果要保持基于光照的最小照明,则应添加非镜面反射组件。高光组件通常用于为材质添加高光,而不是作为唯一的贡献者。

无论如何,您报告的变暗是增加指数的自然结果。想一想:因为向量是预先归一化的,dot(N.xyz, h)所以不超过1.0. 将 0 到 1 之间的数字提高到高次幂自然会使结果很快变得非常小……这正是您想要的尖锐镜面高光!

当然,减小高光的大小会降低平均镜面反射(当然,除非您使最大镜面值更亮......)。但是,很少有实际物体只有镜面反射。而且,如果一个物体确实只有镜面反射,那么除了镜面光点外,它看起来会很暗。


另一种看待它的方式:您的公式为您提供最大值为的镜面亮度1.0(在某些方面,这对于每个颜色通道最大为 的传统低动态范围计算机图形实际上很方便1.0)。然而,在现实世界中,较亮的表面通常会导致镜面反射高光变得更亮和更小,从而使平均镜面反射亮度保持不变。正是这些与案例之间的对比使情况变得混乱。出于实际目的,公式是“按设计工作——不会修复”;通常,艺术家将简单地调整镜面反射指数和亮度,直到获得他想要的外观。

于 2013-02-15T19:47:06.730 回答
0

我最初在用足够的信息更新问题之前写了这个答案。所以在这种情况下这显然不是正确的答案,但可能适用于有类似问题的人......

关于为什么镜面光照强度会随着功率的增加而降低的一种可能的解释是,如果您是在顶点级别而不是按像素计算它。如果高光点恰好落在多边形的中间,而不是正好在一个顶点上,那么随着光泽度的增加,它的大小会减小,顶点的贡献会迅速下降,高光也会消失。真正为了良好的镜面反射(通常也是为了良好的照明),您需要计算每个像素,并且只插入实际上在多边形中平滑变化的东西,例如位置或法线。

于 2013-02-16T01:01:57.820 回答
0

谢谢大家的帮助,

原来这只是顶点着色器中的一个愚蠢错误:

代替:

    fNorm = vec4(mat3(worldSpace)*vNorm.xyz,0);

我刚刚:

fNorm = vNorm;
于 2013-02-16T03:08:17.753 回答
-2

如果你增加“光泽度”,你的材料就会变得不那么闪亮。

于 2013-02-15T16:54:58.777 回答