1

我已经制作了一个 GLSL 着色器,用于在场景中进行逐像素 blinn phong 照明,但我遇到了一些关于场景中光线投射的问题。每个灯光的效果似乎都有一个非常硬的边界(在随附的屏幕截图中,您可以在底部平面上看到灯光的边界 - 灯光(其世界位置相当于场景中悬挂的黑色球体)悬挂在上方飞机和法拉利模型,但由于某种原因,仅将光线适当地投射到/朝向/相机,而不是向前,远离相机。

我觉得我犯了一些错误/对眼睛方向如何影响 blinn phong 照明模型缺乏一些了解。我是否搞砸了我的计算,或者我根本不明白这个特定的照明模型应该如何工作?

我的着色器代码在这里: https ://gist.github.com/1040417

效果截图:场景中的灯光边界截止

4

1 回答 1

2

您对半向量的计算似乎是错误的。半向量是光线方向和视线方向(相机方向)之间的向量,也是眼睛方向影响光照的部分。但是由于您是在世界空间而不是在视图空间中计算光照,因此您不能只使用视图空间位置作为眼睛方向,而是需要将世界空间中的查看器/相机的位置作为着色器的输入。哦,别忘了在计算半向量之前对光向量进行归一化(还要对归一化的光向量进行插值)。所以替换

halfVectors[i] = normalize(lights.allLights[i].position + lightDirections[i]);

uniform vec3 viewerPos;
...
vec3 eyeDirection = normalize(viewerPos - worldPosition.xyz);
...
lightDirections[i] /= dist;
halfVectors[i] = normalize(eyeDirection + lightDirections[i]);

应该做的伎俩。眼睛方向不再需要变化,因为它在片段着色器中不需要(它隐式保存在半向量中)。

我不确定插值半向量是否与在片段着色器中插值眼睛方向和计算半向量给出完全相同的结果(这样你也可以避免许多变化)。但至少它现在应该可以工作了。

编辑:与衰减因子相同。由于它与光线的距离是非线性的,因此您可能不会得到与按片段计算它时完全相同的结果。但这可能是可以容忍的,取决于镶嵌质量。

于 2011-06-22T22:50:49.847 回答