小课 · 交互文章
从像素网格到字符与材质
把后处理当成一张可编程的二维画布:先进入每个像素单元塑造图案,再让同一组坐标长成 ASCII、LED、编织、凸点与磨砂玻璃。
- GoodVibe 中文改编
- Canvas 2D + Shader
- 更新于 2026 年 8 月
本课目录+
拆开刚才的画面
后处理是一张可编程的二维画布
一幅 Three.js 场景完成渲染后,会先得到一张平面的输入纹理。后处理 Shader 读取这张二维结果,再决定屏幕上的每个像素最终显示什么。它当然可以调色或加模糊,也可以把整幅画面重新组织成收据条纹、半调圆点、ASCII 字符、LED 面板,甚至编织和磨砂玻璃。
这些效果看上去互不相干,实际反复使用的是同一组动作:改变从哪里取样、把画面切成网格、进入每个格子内部画形状,再让明度、时间或指针决定形状怎样变化。本课沿着这条路径逐步拆解。你不需要先会写复杂 Shader,只需要跟住“坐标 → 数值 → 形状”这条线。
第一部分 · 像素图案
先让一组像素去同一个位置取色
正常情况下,UV 坐标从 0 到 1 连续变化,每个屏幕像素都从输入纹理的不同位置取色。像素化会先把坐标吸附到固定网格:落在同一个格子里的像素,共用同一个采样位置,于是它们显示相同颜色,方块才出现。
假设画布是 800 × 600,期望方块宽度是 8px。先用 8 / resolution 把屏幕像素换成 UV 尺寸,再用 floor 把连续坐标向下取整。这样即使画布尺寸改变,网格仍然按照屏幕像素计算,不会无缘无故被拉长。
把连续取样位置吸附到像素网格
vec2 normalizedPixelSize = pixelSize / resolution;
vec2 uvPixel = normalizedPixelSize * floor(uv / normalizedPixelSize);vec4 color = texture2D(inputBuffer, uvPixel);pixelSize / resolution 把屏幕像素换成 0–1 的 UV 尺寸。floor 让一个格子里的坐标落到同一个起点。uvPixel 读取输入纹理,得到稳定的色块。走进每个格子
uvPixel 决定格子读什么,cellUV 决定格子里面画什么
像素化只会得到整齐的色块。想让色块变成线、圆点或字符,还需要知道当前像素位于格子内部的哪里。fract 会丢掉整数部分,只保留小数,因此每个格子的左下角都会重新从 0 开始,右上角接近 1。
可以把 uvPixel 理解为“这个格子去原图哪里取色”,把 cellUV 理解为“画笔现在位于这张小画布的哪里”。前者重排整张画面,后者塑造每一个格子。后面的效果几乎都在重复组合这两层坐标。
免费部分到这里
继续完成字符、材质与动态后处理
解锁 cellUV 与明度的完整实现、真实案例和交互实验,并继续进入 ASCII 字符图集、LED 与编织材质、动态去像素化和 Remix。
解锁后从这里继续,前面的公开内容始终可以回来阅读。
学习进度
正在读取你的学习记录…