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

GLSL Waves着色器边缘出现缠绕问题,寻求修复方案

修复ShaderToy中UV坐标超出导致的边缘缠绕问题

你已经明确问题根源:当UV坐标超出[0,1]范围时,ShaderToy默认的纹理采样模式为重复(REPEAT),超出部分会从图像对面边缘衔接,从而出现缠绕现象。以下是几种具体修复方案:

方案1:限制UV范围到[0,1]

使用clamp()函数将偏移后的UV坐标固定在0到1之间,超出部分直接取图像边缘像素,避免缠绕:

const float INTENSITY = 0.5;
const float SPEED = 0.5;
const float SIZE = 0.2;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec4 color = texture(iChannel0, uv);

    vec2 ghostOffset = vec2(cos(uv.y * SPEED * sin(iTime)), sin(uv.x * SPEED));
    // 限制UV在合法范围内
    vec2 sampledUV = clamp(uv + ghostOffset * SIZE, vec2(0.0), vec2(1.0));
    color += INTENSITY * texture(iChannel0, sampledUV);

    fragColor = color;
}

该方案实现简单,但边缘处的虚影效果会被截断。

方案2:使用镜像采样

通过手动计算实现镜像重复采样,让超出部分以翻转方式显示,视觉过渡更自然:

const float INTENSITY = 0.5;
const float SPEED = 0.5;
const float SIZE = 0.2;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec4 color = texture(iChannel0, uv);

    vec2 ghostOffset = vec2(cos(uv.y * SPEED * sin(iTime)), sin(uv.x * SPEED));
    vec2 sampledUV = uv + ghostOffset * SIZE;
    // 计算镜像UV:先取小数部分,再翻转超出0.5的区域
    sampledUV = abs(fract(sampledUV) * 2.0 - 1.0);
    color += INTENSITY * texture(iChannel0, sampledUV);

    fragColor = color;
}

方案3:边缘淡入淡出

根据UV坐标距离边缘的距离,动态降低虚影的透明度,实现柔和过渡:

const float INTENSITY = 0.5;
const float SPEED = 0.5;
const float SIZE = 0.2;
// 边缘过渡区域的宽度,可根据效果调整
const float EDGE_FADE = 0.1;

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec4 color = texture(iChannel0, uv);

    vec2 ghostOffset = vec2(cos(uv.y * SPEED * sin(iTime)), sin(uv.x * SPEED));
    vec2 sampledUV = uv + ghostOffset * SIZE;
    
    // 计算边缘衰减因子:距离边缘越近,因子越小
    vec2 edgeFactor = smoothstep(0.0, EDGE_FADE, sampledUV) * smoothstep(1.0, 1.0 - EDGE_FADE, sampledUV);
    float fadeFactor = edgeFactor.x * edgeFactor.y;
    
    vec4 ghostColor = texture(iChannel0, clamp(sampledUV, vec2(0.0), vec2(1.0)));
    color += INTENSITY * fadeFactor * ghostColor;

    fragColor = color;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:20:18