【问题标题】:Increasing specular shininess decreases lighting in OpenGL增加镜面反射会减少 OpenGL 中的光照
【发布时间】:2013-02-16 16:16:13
【问题描述】:

在我的 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。

Directx 11:

【问题讨论】:

  • 你能提供截图吗?
  • @LightnessRacesinOrbit:这很好,因为他没有要求调试他的代码。他的问题在于对输出的期望,而不是代码。
  • 这段代码是顶点着色器还是像素着色器?
  • @Nicol 我看不到问题。只有“我的代码有问题。”

标签: opengl graphics lighting specular


【解决方案1】:

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

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

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


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

【讨论】:

  • 感谢您的详细解释。在镜面高光的值大约为 20 之后,如果我将结果乘以 1000,它仍然是完全黑色的。
  • 所以很自然,dot(N.xyz, h) 介于 0 和 1 之间意味着整体镜面高光应该随着其功率的增加而呈指数下降。所以现在我不明白在directx11版本中,高亮中心如何保持在1.0,而其他一切都减少到零。
【解决方案2】:

感谢大家的帮助,

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

代替:

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

我刚刚:

fNorm = vNorm;

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 缺少标点符号、错误的标点符号和错误的信息。我的 -1
      • Phong 反射模型包含一个镜面反射项,可以模拟闪亮表面上的此类高光;它甚至包括一个参数来指定材料的光泽度。光泽度指定高光有多小:越亮,高光越小。来源:en.wikibooks.org/wiki/GLSL_Programming/GLUT/Specular_Highlights我是对的没有?
      • 嗯嗯,20年前我在386上用软件实现过,对模型和计算很熟悉。是的,确切地说——材质越亮,镜面高光就越小。 B.B.B.b.但是,材料仍然会更闪亮!如果你说“如果你增加'shininess',你的材质的镜面高光会更小。”我会马上同意。但你没有,这就是我的意思。所以最后,不!你不正确,但你评论的第二句话确实是准确的。 :)
      • 好的,谢谢你的解释。我确实混淆了闪亮和亮点。
      • 不客气。考虑我的-1票被召回。 (我说“考虑”,因为我现在无法扭转它 - 我投票太久了,所以不会允许它)
      猜你喜欢
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 2021-12-25
      相关资源
      最近更新 更多