我正在创建一个小型3D渲染应用程序。我决定对我的三角形使用简单的平面着色 - 只计算面法线和光源之间的角度余弦,并用它来缩放光强度。
但我不确定应该如何将该着色系数应用于我的RGB颜色。
例如,想象一些与光源成60度角的表面。 cos(60度)= 0.5,所以我应该只保留发射光的一半能量。
我可以简单地按该系数缩放RGB值,如下面的伪代码:
double shade = cos(angle(normal, lightDir))
Color out = new Color(in.r * shade, in.g * shade, in.b * shade)
但即使在较小的角度下,所产生的颜色也会变暗。经过一番思考后,这似乎是合乎逻辑的 - 我们的眼睛会感受到光能的对数(这就是为什么我们可以在明亮的白天和夜晚看到它们)。 RGB值已经代表了对数刻度。
我的下一次尝试是使用线性/对数洞察力。理论上:
output energy = lg(exp(input energy) * shade)
可以简化为:
output energy = lg(exp(input energy)) + lg(shade)
output energy = input energy + lg(shade)
因此,这样的阴影只会将阴影系数的对数(负值)添加到RGB值:
double shade = lg(cos(angle(normal, lightDir)))
Color out = new Color(in.r + shade, in.g + shade, in.b + shade)
这似乎有效,但它是否正确?如何在真实的渲染管道中完成?
答案 0 :(得分:1)
颜色RGB矢量乘以阴影系数
您最初假设的余弦值。对数缩放由目标成像设备和人眼完成
如果你的颜色太暗,可能的原因是:
cos(angle)
本身通常不是由余弦计算的
当您将所有数据作为向量时,只需使用点积
double shade = dot(normal, lightDir)/(|normal|.|lightDir|)
如果向量是单位大小,那么你可以通过大小丢弃除法...这就是正常和光向量被归一化的原因......
一些相关问题和说明
dot
GCS / LCS 表示全球/本地坐标系