我在改变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);因此,如果将反光率值增加到类似于50,则根本没有照明。顺便说一下,在这段代码中,我只是为了调试问题而显示镜面反射。
编辑很抱歉在解释中缺乏细节,我附上了一些将镜面反光率值从1更改为7的结果的屏幕截图。正如你所看到的,随着镜面高光的尺寸减小(这是我想要的),照明也会褪色(这不是我想要的)。在大约10点之后,它会变得完全黑色。
顺便说一下,我完全是在像素/片段着色器中执行此操作的。
我还添加了一个来自DirectX11测试引擎的屏幕截图,使用与镜面照明完全相同的代码,但具有100的反光度因子。






Directx 11:
发布于 2013-02-16 03:47:07
如果要保持最小的基于照明的照明,则应添加非镜面反射组件。镜面反射组件通常用于向材质添加高光,而不是作为唯一的贡献者。
无论如何,你报告的变暗是指数增加的自然结果。想想看:因为向量是预归一化的,所以dot(N.xyz, h)只不过是1.0。将0到1之间的数字提高到高幂,自然会使结果很快变得非常小……这正是你想要的一个清晰的镜面高光!
当然,减少高光的大小将减少平均镜面反射(当然,除非您将最大镜面反射值设置得更亮...)。但是,很少有实际对象只有镜面反射。而且,如果一个物体只有镜面反射,它看起来会非常暗,除了镜面上的斑点。
另一种看待它的方式:您的公式给出了一个镜面反射亮度,其最大值为1.0 (在某些方面,这对于传统的低动态范围计算机图形来说非常方便,因为在这些计算机图形中,每个颜色通道都在1.0处达到最大值)。但是,在现实世界中,更有光泽的曲面通常会导致镜面高光变得更亮或更小,从而使平均镜面反射亮度保持不变。正是这些与案例之间的对比使情况变得混乱。出于实际目的,该公式是“按设计工作--不会修复”;通常情况下,艺术家只需调整镜面反射指数和亮度,直到获得他想要的外观。
发布于 2013-02-16 09:01:58
我最初是在问题更新之前写下这个答案的。所以在这种情况下,这显然不是正确的答案,但可能适用于有类似问题的人…
为什么镜面照明的强度会随着功率的增加而降低,一种可能的解释是,如果是在顶点级别计算它,而不是按像素计算。如果高光点恰好落在多边形的中间,而不是正好落在顶点上,那么随着它的大小随着反光度的增加而减小,顶点贡献将迅速下降,高光将消失。对于良好的镜面反射(以及通常的良好照明),您需要计算每个像素,并且只插值在多边形上实际平滑变化的东西,例如位置或法线。
发布于 2013-02-16 11:08:18
感谢你们的帮助,
事实证明,这只是顶点着色器中的一个愚蠢的错误:
而不是:
fNorm = vec4(mat3(worldSpace)*vNorm.xyz,0);我刚说过:
fNorm = vNorm;https://stackoverflow.com/questions/14896037
复制相似问题