第 8 章练习:多个图形与 RGB 叠加

对应教程:08 多个图形与 RGB 叠加
起始示例:三个圆的 RGB 叠加,修改 08-rgb-overlap.js 和需要时的 08-rgb-overlap.html。

练习 1:手算同一片元的三种结果

设某片元的三个遮罩分别为 redMask = 0.8、greenMask = 0.5、blueMask = 0.1,颜色增益为 1.0。

**目标:**分别算出纯 RGB 通道叠加得到的颜色、按红→绿→蓝顺序用 mix 覆盖得到的颜色,以及并集遮罩值。

**完成标准:**能说明三种结果为什么不同;数值允许小数点后两位的四舍五入。

练习 2:改变覆盖顺序

**目标:**新增“红→蓝→绿顺序覆盖”模式,与原来的红→绿→蓝模式并存。

**要求:**保持三个遮罩及圆心不变,只调整 mix 的调用顺序;新增下拉选项。

**完成标准:**三个圆完全重叠的位置在原模式偏蓝,在新模式偏绿;软边仍可看到下层颜色。

<details> <summary>提示</summary>

在遮罩值为 1 的位置,最后一次 mix 会完全覆盖前面的结果。

</details>

练习 3:在重叠处取平均颜色

**目标:**新增模式,把 vec3(redMask, greenMask, blueMask) 视为三个颜色的总贡献;当总遮罩大于 1 时,按总遮罩归一化,使重叠区域不因简单相加而持续变亮。

**要求:**使用 max(total, 1.0) 作除数,避免单个软边区域被额外放大;新增下拉选项。比较它与默认 RGB 叠加模式。

**完成标准:**一个完整圆的纯色区域基本不变;两个完整圆交叠时颜色大致是两色各半;三圆完整交叠时大致为三通道各三分之一。

参考解答


<a id=“reference-answers”></a>

第 8 章练习参考解答

对应练习:多个图形与 RGB 叠加。

练习 1:手算同一片元的三种结果

顺序覆盖每一步都保留前一结果的 1 - mask 部分,再加入当前图形的 mask 部分;它不是直接相加。

练习 2:改变覆盖顺序

在 08-rgb-overlap.html 增加:

<option value="4">按 R → B → G 顺序覆盖</option>

在片元着色器中,把原来的最终 else 并集分支改成 else if (uMode == 3),随后增加:

} else if ( uMode == 4 ) {
  color = vec3( 0.0 );
  color = mix( color, vec3( 1.0, 0.0, 0.0 ), redMask );
  color = mix( color, vec3( 0.0, 0.0, 1.0 ), blueMask );
  color = mix( color, vec3( 0.0, 1.0, 0.0 ), greenMask );
}

三个遮罩都为 1 时,最后一行得到绿色。原 uMode == 2 分支仍按红→绿→蓝的顺序执行,可以直接对照。

练习 3:在重叠处取平均颜色

继续增加下拉选项:

<option value="5">按遮罩总量取平均</option>

在模式判断末尾增加:

} else if ( uMode == 5 ) {
  vec3 contributions = vec3( redMask, greenMask, blueMask );
  float total = redMask + greenMask + blueMask;
  color = contributions / max( total, 1.0 );
}

只有一个完整圆时 total = 1.0,颜色与默认模式一致;两个完整圆交叠时 total = 2.0,两个通道各为 0.5;三个完整圆交叠时 total = 3.0,三个通道各为 1/3。软边若总量小于 1,分母固定为 1,因此不会把微弱边缘放大成满亮度。这是平均贡献的效果,不是物理加光,也不是按顺序覆盖。