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

Shadertoy纹理着色器移植到WebGL后运行效果与原版不一致

移植效果偏差原因及修复方案

问题原因

  • 纹理包裹模式不匹配:Shadertoy默认纹理采样超出UV 0~1范围时自动重复,p5.js默认采用边缘截断模式,代码中UV加了时间偏移必然超出范围,导致采样结果完全不同。
  • Y轴坐标未对齐:Shadertoy的UV原点在画布左下角,p5.js WEBGL模式下默认纹理UV原点在左上角,直接采样会导致纹理上下翻转,后续变换全部出错。
  • 矩阵乘法顺序错误:GLSL默认采用列优先矩阵存储规则,原代码中使用行向量乘矩阵的写法,和常规变换逻辑相反,会导致缩放方向异常。
  • 输入参数不匹配:若p5.js传入的time单位为毫秒(而非Shadertoy的秒级单位),会导致动画速度差1000倍;若传入的两张纹理和原版不一致,也会直接导致效果偏差。

修复方案

1. 调整纹理包裹模式

在p5.js的setup函数中,加载完两张纹理后,分别设置重复采样模式:

// 替换为你自己定义的纹理变量名
texture1.wrap(REPEAT);
texture2.wrap(REPEAT);

2. 修正UV坐标

在着色器中计算UV后先翻转Y轴,对齐坐标系。

3. 修正矩阵乘法顺序

将变换行的乘法顺序调整为列优先的矩阵乘向量,保证变换逻辑正确。

4. 校准输入参数

  • 传入着色器的time值使用秒级单位,比如用millis() / 1000替代直接传毫秒值。
  • 确认传入的texture和texture2和原版使用的两张噪波纹理完全一致,不要传错顺序。

修正后完整着色器代码

uniform vec2 resolution;
uniform float time;
uniform float mouse;
uniform sampler2D texture;
uniform sampler2D texture2;

void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    uv.y = 1.0 - uv.y;
    vec4 texCol = texture2D(texture, uv + time / 10.0);
    mat3 tfm;
    tfm[0] = vec3(texCol.z, 0.0, 0.0);
    tfm[1] = vec3(0.0, texCol.y, 0.0);
    tfm[2] = vec3(0.0, 0.0, 1.0);    
    vec2 muv = (tfm * vec3(uv, 1.0)).xy - 0.1 * time;
    texCol = texture2D(texture2, muv);
    gl_FragColor = texCol;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:54:02