You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shadertoy如何实现图像黑白与彩色效果的循环切换?

实现黑白/彩色循环切换的Shader(基于iTime控制)

核心思路

利用iTime生成周期性变化的因子,通过插值函数在彩色原图和黑白效果之间完成切换,支持硬切换或平滑过渡两种模式。


硬切换版本(瞬间切换)

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{    
    vec2 xy = fragCoord.xy / iResolution.xy;
    vec4 texColor = texture(iChannel0, xy);
    
    // 控制循环周期:0.5对应每2秒完成一次黑白<->彩色循环,调大数值可加快循环速度
    float cycle = fract(iTime * 0.5);
    // 当cycle超过0.5时切换为黑白,否则保持彩色
    float switchToGrayscale = step(0.5, cycle);
    
    vec4 grayscaleColor = (texColor + texColor.yzxw + texColor.zxyw) / 3.;
    // 根据切换因子混合两种颜色
    fragColor = mix(texColor, grayscaleColor, switchToGrayscale);
}

平滑过渡版本(渐变切换)

如果想要更自然的过渡效果,用smoothstep代替step,让切换过程产生渐变:

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{    
    vec2 xy = fragCoord.xy / iResolution.xy;
    vec4 texColor = texture(iChannel0, xy);
    
    float cycle = fract(iTime * 0.5);
    // 在cycle从0.4到0.6的区间内完成平滑过渡,区间宽度可自行调整
    float smoothTransition = smoothstep(0.4, 0.6, cycle);
    
    vec4 grayscaleColor = (texColor + texColor.yzxw + texColor.zxyw) / 3.;
    fragColor = mix(texColor, grayscaleColor, smoothTransition);
}

关键代码解释

  • fract(iTime * 0.5):提取时间的小数部分,生成0到1之间循环的数值,以此控制切换周期。
  • step(threshold, value):当value大于等于threshold时返回1,否则返回0,实现瞬间切换效果。
  • smoothstep(edge0, edge1, value):在edge0到edge1区间内生成0到1的平滑过渡值,避免切换过于突兀。
  • mix(a, b, t):根据t值在a(彩色)和b(黑白)之间线性插值,t=0取彩色,t=1取黑白。

内容的提问来源于stack exchange,提问作者PrettyCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:55:19