【问题标题】:When do I have to multiply two colors together when do I have to add them?什么时候必须将两种颜色相乘,什么时候必须相加?
【发布时间】:2014-02-03 14:29:57
【问题描述】:

我已经实现了一个具有以下属性的简单着色器: - 材质(环境、漫反射和镜面反射) - 定义对象颜色的基色 - 浅色

片段着色器:(vColor是对象的基色)

  vec3 lightDir = normalize(vec3($uLightPos.xyz - vPosInEye.xyz));
  vec3 viewerPos = normalize(vec3(-vPosInEye.xyz));
  vec3 specularReflection = normalize(-reflect(lightDir, vNormal));

  float diffFactor = max(dot(vNormal, lightDir), 0.0);
  vec4 Id = $uIdColor * diffFactor * vColor ;
  vec4 Ia = $uIaColor * vColor;
  vec4 Is = clamp($uIsColor * pow(max(dot(specularReflection, viewerPos), 0.0), $uIsShininess), 0.0, 1.0);

  gl_FragColor = (Id + Ia + Is) + $uLightColor;

如您所见,我将材质的环境颜色与对象的基色相乘。这似乎是正确的,因为我想将这些颜色混合在一起。

在“Open GL ES 2.0 Programming guide”一书中,这是以相同的方式实现的。在最后一行中,我添加了灯光的颜色。
我一开始尝试将颜色相乘,但后来我得到了奇怪的结果:黄色 * 蓝色导致黑色(这很清楚,因为黄色是 (1.0, 1.0, 0) 和蓝色 (0.0, 0.0, 1.0) 所以我用 + 替换 * . 这似乎产生了正确的颜色(白色)。

所以我的问题是:当我必须将两种颜色相乘以及何时相加时,是否有经验法则?

【问题讨论】:

  • 你必须根据你想要得到的效果/结果来做!
  • @Günter Zöchbauer 为什么将着色器代码标记为 Dart?
  • 抱歉打错了,看的不够仔细。为什么要添加 dart 标签?
  • 我现在删除飞镖标签。这只是关于图形编程的一般问题
  • 很抱歉,如果有人想知道它们来自哪里,我添加了 dart 标签,因为着色器代码中的 $ 符号...

标签: opengl shader lighting


【解决方案1】:

当您想将一种颜色调制为另一种颜色时,您需要进行乘法运算。 例如,如果你有一个蓝色材质,你想将落在它上面的光乘以材质的颜色,因为它应该只反射蓝光。如果蓝色材料上有黄光,您会期望得到黑色,因为蓝色材料不会反射黄光。 (在现实生活中,您永远不会拥有如此完美的材料,它们可能是 (0.5 0.5, 0.75) ...

例如,如果您有两个光源,那么您可能会添加它们,因为您想合计每个光源的贡献。你看到的光只是两个光的总和,所以把它们加起来。

【讨论】:

  • 所以这意味着 + 是错误的,因为你不希望它是白色的。我想应该再看看“色彩”(-:
【解决方案2】:

jcoder 的回答是正确的。

不过,我认为你可以说得更简单一些。

当光线照射到物体时会发生乘法。 当有来自多个来源的光时,就会发生加法。

我们乘以计算物体-灯光交互的原因是因为正如 jcoder 所说,在这个光照模型中 1)每种光色都是独立的 2) 物体吸收命中它们的光的固定百分比。

好奇的小贴士: 您可以尝试将此模型替换为对象吸收固定量光的模型(减去,而不是相乘 - 显然您需要剪辑为零,因此您不会得到 -ve 光) 结果是当它变暗时,颜色之间的对比度会更大。 不真实,而是一种“比真实更真实”的效果。有点像“下药”的效果。

【讨论】:

    猜你喜欢
    • 2011-10-23
    • 2014-11-08
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 2012-04-26
    • 1970-01-01
    相关资源
    最近更新 更多