在游戏中,物体的淡入淡出效果是一种常见的状态转换方式。然而,在某些情况下,我们希望在物体进行fade
切换时能够呈现出更多的色彩层次感,或展示其他特殊的中间状态。这时,就需要通过编写着色器来实现。这种效果不同于简单的淡入淡出,而是被形象地称为"溶解"效果。
效果展示
思路
溶解效果的实现思路相对简单。
首先,需要提取当前纹理的颜色信息,然后选择一个参考通道作为比较标准,通常会选取 RGB 中的某一个通道,例如在本文中我们选择了蓝色通道。
接着,需要动态地调整这个通道的参考值,当纹理贴图的颜色值低于这个参考值时,颜色就会逐渐消失。随着参考值逐渐降低,颜色逐渐融化。当参考值降至0时,颜色完全消失。
这种效果的实现,需要在着色器中完成。在着色器中获取当前纹理的颜色,根据定义的参考通道进行比较和调整。通过逐渐降低参考值,就可以实现颜色的逐渐溶解消失。effect
代码如下:
typescript
void main () {
vec4 color = vec4(1, 1, 1, 1);
#if USE_TEXTURE
color *= texture(texture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
color.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
// 当颜色小于溶解的程度,则直接抛弃
if(color.b < fade_pct) discard;
gl_FragColor = color;
}
如果希望溶解更加有层次变化,还可以对溶解的边缘做一些处理,比如透明度改变,色彩改变等,这就需要代入我们自己的使用场景中,根据实际的需要去调整,比如我们希望溶解的边缘有一些蓝色调的变化:
typescript
if(color.b < fade_pct + 0.1) {
color = vec4(0.92, 0.8, 0.95, color.a);
}
然后我们需要在update
的时候去动态更新并设置fade_pct
,以达到纹理的溶解效果动态变化:
typescript
update(dt) {
this.fadePct += dt * this.speed;
this.material.setProperty('fade_pct', this.fadePct));
}
以上就是溶解效果的核心思路,不同的贴图的溶解效果和我们的溶解条件是直接关联的,先看下图:
这图中色彩比较单一的尾巴和翅膀,由于蓝色通道较窄,变化过程就比较集中而且快,同时用蓝色调处理溶解的边缘效果的过渡也比较融洽。相比鸟的其他部位和开篇的角色,由于色彩比较丰富,用单一的蓝色通道当成溶解条件和过渡就相对来说比较生硬,因此,我们需要视项目的实际情况动态调整。