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

如何在JS文件中借助WebGL与GLSL运行来自Shadertoy的着色器?

Shadertoy代码移植到原生WebGL的适配说明

不能直接把Shadertoy的片元代码复制到你自己的WebGL片元着色器里直接用,Shadertoy做了大量底层封装,你需要做以下几处适配调整:

1. 替换片元着色器入口与内置变量

Shadertoy的默认渲染入口是void mainImage( out vec4 fragColor, in vec2 fragCoord ),和原生WebGL的标准结构有差异,你需要做对应替换:

  • 把mainImage函数改成main函数,删除两个参数定义
  • Shadertoy的输出参数fragColor直接替换为原生WebGL的内置输出变量gl_FragColor(WebGL1默认支持,WebGL2需要自行声明输出变量)
  • Shadertoy的输入参数fragCoord对应原生WebGL的内置输入变量gl_FragCoord

示例修改前后对比:

// Shadertoy原版代码
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;
    fragColor = vec4(uv,0.0,1.0);
}
// 适配后的WebGL片元着色器代码
void main()
{
    vec2 uv = gl_FragCoord.xy/iResolution.xy;
    gl_FragColor = vec4(uv,0.0,1.0);
}

2. 手动传入Shadertoy内置uniform变量

Shadertoy默认封装了常用的全局uniform参数,你需要在JS层手动给WebGL程序传递这些值,常用参数包括:

  • iResolution:vec3类型,对应画布的宽度、高度、像素比,每次画布尺寸变化时更新即可
  • iTime:float类型,着色器运行的总时长,单位为秒,每帧渲染时用requestAnimationFrame返回的时间戳换算更新即可
  • iMouse:vec4类型,对应鼠标坐标和点击状态,需要自行监听鼠标事件更新数值
  • iChannel0~iChannel3:采样器类型,对应Shadertoy的4个输入纹理,需要自行加载纹理、绑定到对应纹理单元,再把纹理单元编号传给uniform

JS层传值的示例代码片段:

// 先获取uniform的位置
const iResolutionLoc = gl.getUniformLocation(program, 'iResolution');
const iTimeLoc = gl.getUniformLocation(program, 'iTime');

// 每帧渲染时更新uniform
function render(time) {
  gl.uniform3f(iResolutionLoc, gl.canvas.width, gl.canvas.height, window.devicePixelRatio);
  gl.uniform1f(iTimeLoc, time / 1000); // 时间戳转秒
  // 这里写你的绘制调用逻辑
  requestAnimationFrame(render);
}
requestAnimationFrame(render);

3. 处理语法与特殊功能差异

  • Shadertoy默认使用GLSL ES 300语法,如果你的WebGL环境用的是GLSL ES 100(WebGL1默认版本),需要把texture采样函数改成texture2D,同时删除Shadertoy代码头部的版本声明
  • 如果用到Shadertoy的多Pass缓冲、音频输入、视频输入等特殊功能,需要自行实现对应逻辑,比如多帧缓冲渲染、音频频谱分析等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:39:01