网易首页 > 网易号 > 正文 申请入驻

350行代码造浏览器着色器编辑器

0
分享至

有时候你只是想快速试一段着色器代码,不想开Shadertoy,不想配构建流程,什么都不想要。只要一个文本框、一块画布、实时刷新的循环。这个项目就是干这个的:约350行原生JavaScript,固定一个全屏四边形的顶点着色器,片段着色器随你现场编辑。编译错误带行号返回到界面;URL哈希能完整保存你的代码,分享到Twitter直接点开就能用。

在线演示:https://sen.ltd/portfolio/shader-playground/
GitHub仓库:https://github.com/sen-ltd/shader-playground


核心功能很直白。顶点着色器是写死的——两个三角形拼成满屏四边形。片段着色器交给用户编辑。页面在每次按键后220毫秒防抖执行gl.compileShader(...),编译成功就热切换程序。三个uniform自动绑定:u_resolution(绘制缓冲区尺寸)、u_mouse(WebGL像素坐标系下的光标位置)、u_time(页面加载后的秒数)。编译错误从驱动的info log解析出来,带上行号显示在界面上。着色器源码用base64url编码塞进location.hash来回传递,所以分享永久链接在任何浏览器都一致可用。

就这些。下面列的是实现过程中踩到的小坑。

WebGL上下文——两个值得设置的标志

const gl =els.canvas.getContext("webgl", {antialias: true,premultipliedAlpha: false,els.canvas.getContext("experimental-webgl");

两个几乎总会遇到的标志:premultipliedAlpha: false决定"画布是不透明的绘制表面"还是"画布与背后的DOM混合"。如果忘了这个,即使片段着色器写gl_FragColor = vec4(rgb, 1.0),某些浏览器上还是会看到页面背景透过来——然后你会花十分钟想不明白为什么。显式设置掉这个意外。antialias: true虽然是默认值,但显式写出来让你记得它存在。交换链上的MSAA让图形边缘干净,不需要逐片段的MSAA逻辑。

experimental-webgl回退现在基本只剩历史意义(Android Chrome 2014年左右,IE11)。多写个||的成本,所以我留着。

解析编译错误日志

驱动(大部分)输出这样的行:

ERROR: 0:5: 'foo' : undeclared identifierERROR: 0:12: 'bar' : assignment to const variableWARNING: 0:3: implicit conversion

0是文件索引,单源字符串时几乎总是零。5是源码行号,后面是人类可读的消息。

const ERROR_RE =/^\s*(ERROR|WARNING)\s*:\s*(\d+)\s*:\s*(\d+)\s*:\s*(.+?)\s*$/i;export function parseShaderError(infoLog) {if (!infoLog) return [];const out = [];for (const rawLine of infoLog.split(/\r?\n/)) {const line = rawLine.trim();if (!line) continue;const m = line.match(ERROR_RE);if (m) {out.push({severity: m[1].toUpperCase() === "ERROR" ? "error" : "warning",line: Number(m[3]),message: m[4],} else {// Mali / Adreno 经常前置一段自由格式的摘要行。别丢掉。out.push({ severity: "error", line: 0, message: line })return out;}

Mali和Adreno GPU的驱动喜欢在前面加一段总结性文字,正则匹配不上,但信息有用,所以兜底存为行号0的错误。

防抖与热重载的时序

220毫秒的防抖间隔是打字节奏和编译延迟的折中。太短会频繁编译失败闪烁;太长反馈迟钝。用setTimeout+clearTimeout实现,没有拉第三方库。

热切换程序时要注意:WebGL不允许直接替换着色器,必须重新链接着色器程序。旧程序要gl.deleteProgram释放,否则显存泄漏。新程序编译链接成功后,再解绑旧程序、绑定新程序、重新设置uniform位置。这个顺序错了会导致一帧黑屏或报错。

URL哈希的体积与编码

base64url相比标准base64,把+换成-/换成_、去掉填充=,这样不需要额外URL编码就能塞进hash。一段几百行的着色器编码后通常几KB,在浏览器URL长度限制内(约2MB)。

解码时要处理两种异常情况:hash不存在(首次打开)、base64损坏(用户手动改了URL)。前者回退到默认示例着色器,后者同样回退并控制台报个错,保证页面不崩。

鼠标坐标的坐标系陷阱

u_mouse直接传event.clientX/event.clientY是错的,因为WebGL的绘制缓冲区尺寸和CSS显示尺寸可能不同(Retina屏、页面缩放)。正确做法是用gl.drawingBufferWidth/gl.drawingBufferHeight计算比例,或者直接用event.offsetX*canvas.width/canvas.clientWidth转换。

这个项目选了后者,因为offsetX/Y已经相对于canvas元素,省去再算相对位置的麻烦。

为什么不用Shadertoy

Shadertoy功能丰富:多通道、音频频谱、纹理上传、社交功能。但有时候这些全是噪音。你想快速验证一个 signed distance function 的变形,或者调一个噪声函数的参数,350行的自托管方案没有学习成本、没有账号、没有加载时间、没有"Trending"标签分散注意力。

代码结构也适合当教学材料:没有构建步骤,没有npm依赖,打开HTML文件就能读。顶点着色器固定、片段着色器动态,这个模型覆盖了90%的实时图形原型需求。

项目用原生模块(

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
被两个老外拐跑的出租车司机

被两个老外拐跑的出租车司机

南风窗
2026-05-13 13:18:49
张本美和不再沉默!说出全日本不想承认的事实:孙颖莎没任何弱点

张本美和不再沉默!说出全日本不想承认的事实:孙颖莎没任何弱点

小兰聊历史
2026-05-14 12:31:57
北大才子将癌症晚期父亲骗出国,让其高空跳伞,88天后结局怎样

北大才子将癌症晚期父亲骗出国,让其高空跳伞,88天后结局怎样

云景侃记
2026-04-17 17:00:39
包工头与做饭大姐相好5年,工程完工想走,谁曾想大姐竟不好惹

包工头与做饭大姐相好5年,工程完工想走,谁曾想大姐竟不好惹

磊子讲史
2025-07-02 13:45:23
史上最贵航班直飞中国:黄仁勋背着双肩包,压哨蹭上万亿大佬专机

史上最贵航班直飞中国:黄仁勋背着双肩包,压哨蹭上万亿大佬专机

小影的娱乐
2026-05-14 05:43:26
宝玉和谁有过肌肤之亲?4个女人,2个千金小姐,2个漂亮丫头

宝玉和谁有过肌肤之亲?4个女人,2个千金小姐,2个漂亮丫头

掠影后有感
2026-05-13 11:17:09
2分!曼城喜获“半分”优势,阿森纳迎来两个冠军点

2分!曼城喜获“半分”优势,阿森纳迎来两个冠军点

嗨皮看球
2026-05-14 11:40:20
继父入赘我家40多年,母亲去世,大哥要赶继父离开,我:爹不能走

继父入赘我家40多年,母亲去世,大哥要赶继父离开,我:爹不能走

人间百态大全
2026-05-14 06:35:04
人伦之乱,正在悄悄毁掉无数家庭!看完一身冷汗

人伦之乱,正在悄悄毁掉无数家庭!看完一身冷汗

三农老历
2026-05-08 19:20:12
汪涵嚼槟榔十几年成习惯?网友偶遇十次有九次他手里都攥着槟榔

汪涵嚼槟榔十几年成习惯?网友偶遇十次有九次他手里都攥着槟榔

TVB的四小花
2026-05-14 12:44:47
哈登关键战爆发30+8+6,正名之战稳住东部第一

哈登关键战爆发30+8+6,正名之战稳住东部第一

奇史怪谈
2026-05-14 11:23:53
孙杨和张豆豆,可能是婚姻里走得最远的一对

孙杨和张豆豆,可能是婚姻里走得最远的一对

精读君
2026-05-14 09:00:26
Siegel:詹姆斯离开湖人加盟勇士的可能性很低 但勇士仍准备报价

Siegel:詹姆斯离开湖人加盟勇士的可能性很低 但勇士仍准备报价

砚底沉香
2026-05-14 12:48:05
为嫁50亿富豪抛弃同居5年的周一围,今成笑柄

为嫁50亿富豪抛弃同居5年的周一围,今成笑柄

青杉依旧啊啊
2026-04-27 14:03:21
同居12年嫌体力不支,与大49岁香港男友分手,如今她回老家当网红

同居12年嫌体力不支,与大49岁香港男友分手,如今她回老家当网红

白面书誏
2026-05-13 20:39:20
希金斯:只有奥沙利文能教我新的东西,所以我现在不需要任何教练

希金斯:只有奥沙利文能教我新的东西,所以我现在不需要任何教练

世界体坛观察家
2026-05-14 09:02:40
国际油价13日下跌

国际油价13日下跌

证券时报
2026-05-14 07:21:02
亚洲9队晋级!U17世界杯48强已定38席,国足破魔咒,比赛时间如下

亚洲9队晋级!U17世界杯48强已定38席,国足破魔咒,比赛时间如下

侃球熊弟
2026-05-14 04:46:28
放眼看世界之空军一号:美国总统的“空中白宫”

放眼看世界之空军一号:美国总统的“空中白宫”

阿芒娱乐说
2026-05-13 08:09:31
林诗栋夺冠返乡,妈妈停业接机:别再说母爱普通,她从不缺席

林诗栋夺冠返乡,妈妈停业接机:别再说母爱普通,她从不缺席

乡野小珥
2026-05-14 10:32:44
2026-05-14 13:19:00
字节漫游指南
字节漫游指南
有态度网友ytd
3880文章数 41关注度
往期回顾 全部

科技要闻

马斯克:只有我和黄仁勋坐上了"空军一号"

头条要闻

兄妹救4名落水者后遭拉黑 被告知获救者身份不便公开

头条要闻

兄妹救4名落水者后遭拉黑 被告知获救者身份不便公开

体育要闻

登海报!哈登30+8+6创多项纪录 第8次赢天王山

娱乐要闻

肖战提名金海燕奖,这一步走得太稳

财经要闻

片仔癀依旧困在“片仔癀”

汽车要闻

C级纯电轿跑 吉利银河"TT"申报图来了

态度原创

艺术
家居
数码
时尚
本地

艺术要闻

充满光感的花卉油画 | 亚历山大·沙巴德伊

家居要闻

精神奢享 对话塔尖需求

数码要闻

泡泡玛特高管否认进军传统家电 专注IP衍生小家电品类

T恤+低腰阔腿裤、衬衫+低腰半裙,今年夏天最时髦的搭配,谁穿谁好看!

本地新闻

用苏绣的方式,打开江西婺源

无障碍浏览 进入关怀版