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

如何在Three.js中使用ShaderToy着色器?求转换与配置协助

ShaderToy着色器转Three.js适配实现

顶点着色器(vertexShader)

使用全屏平面的基础顶点着色器即可,代码如下:

void main() {
    gl_Position = vec4(position, 1.0);
}

如果需要传递UV坐标用于后续计算,可使用:

varying vec2 vUv;

void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

片元着色器(fragmentShader)转换

针对目标ShaderToy着色器,按以下规则修改核心逻辑:

  1. 参数映射:
    • ShaderToy的fragCoord → 替换为gl_FragCoord.xy,结合resolution做坐标归一化:vec2 uv = gl_FragCoord.xy / resolution.xy;
    • ShaderToy的iTime → 对应Three.js的time uniform(传入秒级时间值)
    • ShaderToy的iResolution → 对应Three.js的resolution uniform(传入窗口宽高)
    • 原mainImage(out vec4 fragColor, in vec2 fragCoord)入口改为Three.js的void main(),最终将结果赋值给gl_FragColor

转换后的片元着色器示例(基于目标ShaderToy代码适配):

uniform float time;
uniform vec2 resolution;

// 复制原ShaderToy中的所有自定义函数(如噪波、颜色计算逻辑)
float noise(vec2 p) {
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}

// 原ShaderToy中的其他函数...

void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    // 若原ShaderToy使用从下到上的Y轴,添加反转:uv.y = 1.0 - uv.y;
    
    vec4 fragColor = vec4(0.0);
    // 复制原ShaderToy中mainImage内的计算逻辑,替换fragCoord为uv相关变量
    float n = noise(uv * 10.0 + time);
    fragColor = vec4(vec3(n), 1.0);
    
    gl_FragColor = fragColor;
}

Uniforms配置

在Three.js中定义并初始化所需uniforms:

const uniforms = {
    time: { value: 0 },
    resolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) }
    // 若原ShaderToy使用iMouse,添加:
    // mouse: { value: new THREE.Vector2(0, 0) }
};

完整使用流程

  1. 创建ShaderMaterial:
const shaderMaterial = new THREE.ShaderMaterial({
    vertexShader: 上述顶点着色器代码,
    fragmentShader: 上述转换后的片元着色器代码,
    uniforms: uniforms
});
  1. 添加全屏平面到场景:
const geometry = new THREE.PlaneGeometry(2, 2);
const plane = new THREE.Mesh(geometry, shaderMaterial);
scene.add(plane);
  1. 动画循环更新时间:
function animate() {
    requestAnimationFrame(animate);
    uniforms.time.value = performance.now() / 1000; // 获取精确秒级时间
    renderer.render(scene, camera);
}
animate();
  1. 窗口resize时更新分辨率:
window.addEventListener('resize', () => {
    uniforms.resolution.value.set(window.innerWidth, window.innerHeight);
    renderer.setSize(window.innerWidth, window.innerHeight);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:30:13