第 6 课:纹理采样与混合

返回教程目录 · 打开本课练习

图片如何变成片元颜色

纹理是 GPU 中可按坐标读取的二维数据。日常开发会用它贴照片、做 UI 遮罩、控制溶解顺序、驱动 UV 位移或存储法线。本课使用本地原创纹理,练习可从 doc/shader-tutorial/exercises/ 运行 http-server -p 1000,不需要 CDN 或额外下载。

main.js 通过 TextureLoader.loadAsync() 读取 PNG,设置 texture.wrapS/wrapT 和颜色空间,然后把对象放到 ShaderMaterial.uniforms。Three.js 把图片上传成 GPU texture,并把 sampler uniform 绑定到对应纹理单元。平面每顶点的 uv attribute 经顶点 Shader 送入 vUv,在三角形内部插值;片元 Shader 通过 texture2D(uTexA,vUv) 取出当前坐标附近的像素,再输出颜色。当前练习使用 ShaderMaterial 的 GLSL ES 1.00 风格写法,因此采样函数是 texture2D;第 12 课再比较 GLSL ES 3.00 的 texture 写法。

纹理坐标、平铺与采样

vUv 在本课正方形预览里从 0 到 1。把它乘以 2,就会访问 0–2:若纹理设置为 RepeatWrapping,超出 1 的部分会回到纹理开头,因此得到 2×2 四个图案。若是默认 ClampToEdgeWrapping,边缘颜色会被拉长,而不是重复。示例的暖色纹理按周期公式制作,两侧颜色相接,平移时才没有明显接缝;随便换一张照片,即使设为 RepeatWrapping,图片左右边缘也未必匹配。

双图渐变取 a=texture2D(uTexA,vUv).rgb 与 b=texture2D(uTexB,vUv).rgb,再 mix(a,b,vUv.x)。左边权重 0,右边权重 1。黑白遮罩把第三张纹理的 .r 当权重:黑处显示 A,白处显示 B,灰处线性混合。遮罩、噪声和位移图保存的是数据,不应把灰度值当 sRGB 照片处理。

颜色空间是数据含义的一部分

教程的 art-a.png、art-b.png 是供人看的颜色纹理,JS 将其标记为 THREE.SRGBColorSpace;WebGL 采样时会得到适合线性计算的颜色。遮罩、噪声和 RG 位移图保持默认无颜色空间,因为 0.5 等数据值必须按原值读取。若误把遮罩标记成 sRGB,灰色 0.5 在 Shader 中会被解码为更低的线性值,混合区域会偏向 A。

片元 Shader 在线性空间混合颜色,最后由 Three.js 的 colorspace_fragment 转换到画布输出。若颜色看起来过亮、过暗或偏色,先核对纹理的 colorSpace、Shader 是否重复手动做了 gamma 变换,再检查浏览器和显示设置。纹理题使用两个原创抽象图案来减少许可证与素材路径问题;替换为项目图片时要确认来源与使用许可。

遮罩、溶解、位移和多次采样

溶解题将噪声值 n 与进度 uProgress 比较:n < progress 的片元透明,n >= progress 的片元保留。阈值附近再用 smoothstep 形成暖色亮边。这里选择透明度以便看见场景背景;也可以用 discard,但它会改变深度、混合及某些 GPU 的性能特征。进度题使用滑块,便于停在边界处观察。

位移图的红绿通道分别表示 X/Y 偏移。图片的 RG 原始范围是 0–1,所以要先减去 0.5 变成正负方向,再乘强度并加到 vUv 上。强度过大时,采样会跑到原图外;当前练习启用了 RepeatWrapping,因此会从对侧重复。若做单张照片的折射,更常用 clamp(sampleUv,0.0,1.0) 或边界淡出。

双图切换由按钮更新 JS 中的目标值,渲染循环按 dt 推进 uProgress;Shader 只做 mix。RGB 故障题对同一纹理采样三次,分别拿 R/G/B,制造通道错位;这比一次采样成本更高,应在目标设备测量。万花筒题用 atan、length 转成极坐标,按扇区取模并镜像折叠,再回到 UV 采样。正方形预览避免扇区在屏幕上被拉成椭圆。

资源与性能实践

排查顺序

黑屏先看 Network:PNG 和两个 Shader 文件是否为 200;再看 Shader 编译日志和 sampler uniform 名称。四格重复没出现时检查 RepeatWrapping 与 vUv*2.0;滚动有接缝时检查图片边缘内容,而不只是 wrapping 设置;遮罩反相时输出 vec3(mask) 看灰度;位移过强时先把 uStrength 设为 0 验证原图能显示。

练习

难度 题目 可见验收
⭐ 采样并显示本地纹理 暖色图案完整显示
⭐ UV 放大两倍重复四格 2×2 重复
⭐⭐ 两张纹理的水平渐变混合 左 A 右 B
⭐⭐ 黑白纹理遮罩混合 遮罩决定混合
⭐⭐ UV 滚动的无缝背景 连续循环滚动
⭐⭐⭐ 噪声纹理溶解与亮边 进度可调,有暖色边
⭐⭐⭐ 位移纹理扰动采样 UV 水面般扭曲
⭐⭐⭐ 点击切换双层纹理 A/B 平滑往返
⭐⭐⭐⭐ RGB 通道错位故障艺术 随机彩边横带
⭐⭐⭐⭐ 极坐标镜像万花筒 扇区数可调的镜像图案