如何将平面着色应用于RGB颜色?

时间:2015-05-26 07:09:33

标签: graphics colors 3d rgb

我正在创建一个小型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)

这似乎有效,但它是否正确?如何在真实的渲染管道中完成?

1 个答案:

答案 0 :(得分:1)

  1. 颜色RGB矢量乘以阴影系数

    您最初假设的余弦值。对数缩放由目标成像设备和人眼完成

  2. 如果你的颜色太暗,可能的原因是:

    • 余弦或角度值被截断为整数
    • 或您的管道没有线性比例输出(某些伽马校正可以做到这一点)
    • 或者你在某处有错误
    • 或您的角度和余弦使用不同的指标(弧度/度)
    • 您忘记将环境光系数添加到阴影值
    • 你的向量是对立的还是错的(在视觉上查看它们的第一个链接如何)
    • 你的矢量不在同一个坐标系中(光通常在GCS和LCS模型中的法向量中,所以你需要将它们中的至少一个转换为另一个的坐标系)
  3. cos(angle)本身通常不是由余弦计算的

    当您将所有数据作为向量时,只需使用点积

    double shade = dot(normal, lightDir)/(|normal|.|lightDir|)
    

    如果向量是单位大小,那么你可以通过大小丢弃除法...这就是正常和光向量被归一化的原因......

  4. 一些相关问题和说明

    GCS / LCS 表示全球/本地坐标系