@vgpu/wgsl-std实战:noise、hash、color、sampling——你需要的WebGPU着色器标准库
【免费下载链接】vgpuModular cross-runtime WebGPU library for shaders, 3D scenes, GPU tensors, neural networks, and math viz项目地址: https://gitcode.com/gh_mirrors/vgpu/vgpu
如果你正在用WebGPU写着色器,一定被这些重复代码折磨过:手抄 Perlin 噪声公式、自己写 sRGB 转换、拼 Hammersley 采样序列。今天介绍的@vgpu/wgsl-std就是为此而生的WebGPU 着色器标准库——一组纯 WGSL 工具模块,把noise、hash、color、sampling这些高频功能打包成可直接import的标准子路径,开箱即用,零绑定、零隐藏状态。
为什么需要 @vgpu/wgsl-std?
写 GPU 程序时,"数学胶水代码"往往比核心逻辑还多。传统做法是把别人博客里的 snippet 直接粘进着色器,但这样做有两个隐患:
- 来源不明:公式对不对、边界情况(除零、溢出)有没有处理,全凭运气;
- 重复造轮子:每个项目都重写一遍 sRGB 解码和黄金角采样。
@vgpu/wgsl-std的设计哲学很克制:只发布纯声明式 WGSL 模块(函数、常量、结构体),不引入@group、@binding、override 或入口点。你import的每一个工具函数都经过审查与测试,例如 tests/perlin.test.ts 用 100 万随机采样验证了噪声的取值范围。
5分钟上手:如何安装和导入
@vgpu/wgsl-std是vgpu包的内置依赖,安装vgpu后无需单独安装,子路径即可直接导入:
import { perlin2d, fbmPerlin3d } from "@vgpu/wgsl-std/noise/perlin"; import { pcg3d, unitFloat } from "@vgpu/wgsl-std/hash"; import { srgbToLinear3, linearToSrgb3, tonemapAces } from "@vgpu/wgsl-std/color"; import { vogelDisk, hammersley2d } from "@vgpu/wgsl-std/sampling";所有子路径映射都写在 packages/wgsl-std/README.md 里,核心入口一览:
| 子路径 | 内容 |
|---|---|
@vgpu/wgsl-std/noise | Voronoi(细胞)噪声voronoi2d/3d |
@vgpu/wgsl-std/noise/perlin | Perlin 梯度噪声 + 归一化 fBM |
@vgpu/wgsl-std/noise/simplex | Simplex 噪声 + 归一化 fBM |
@vgpu/wgsl-std/hash | 确定性哈希与"随机数" |
@vgpu/wgsl-std/color | sRGB 转换、亮度、曝光、色调映射 |
@vgpu/wgsl-std/sampling | 低差异序列采样(Vogel 圆盘、Hammersley) |
@vgpu/wgsl-std/math/constants | 区间重映射、安全归一化、π 等常量 |
四大核心模块逐个看
1️⃣ noise:Perlin、Simplex 与 Voronoi 三件套
想要云、地形、雾、等离子体这类平滑场?选梯度噪声:
- @vgpu/wgsl-std/noise/perlin:
perlin2d/3d加fbmPerlin2d/3d,数学上保证输出恒在 (-1, 1),再也不用2.2 *这种玄学系数然后到处夹值; - @vgpu/wgsl-std/noise/simplex:更便宜、频率更高的"兄弟"实现,
fbmSimplex2d/3d同样幅值归一化; - @vgpu/wgsl-std/noise:Voronoi 细胞噪声,一次返回最近距离
f1、次近距离f2和格子cell,f2 - f1就是经典的细胞边缘图案。
一个小技巧:fBM 的octaves会被静默钳制在 [1, 16],gain钳制在 [0, 1]——即使 uniform 传进垃圾值也不会把 GPU 挂死,这对新手非常友好。
2️⃣ hash:着色器里的确定性"随机数"
GPU 上没有"掷骰子",只有确定性哈希。hash 模块 提供完整工具链:
hashU32:基于 Wellons lowbias32 的整数哈希;pcg2d/pcg3d:多输出 PCG 风格向量哈希,专给格子坐标用(2D/3D 各返回去相关的多个分量,省得再调用多次);unitFloat:把u32哈希位稳定映射到[0, 1),且永远不返回 1.0;hash1/2/3:浮点种子版,一个函数直接拿到单位区间内的小数。
典型用法——给每个格子一个稳定的随机值(注意用bitcast处理格子坐标):
import { pcg3d, unitFloat } from "@vgpu/wgsl-std/hash"; fn cellRandom(cell: vec3i) -> f32 { return unitFloat(pcg3d(bitcast<vec3u>(cell)).x); }官方文档还特别提醒:做格子噪声时优先用整数坐标哈希,别用sin/fract式的浮点哈希——精度陷阱少一个是一个。
3️⃣ color:sRGB、曝光与色调映射一步到位
色彩管线里最容易被写错的就是传递函数。color 模块 覆盖了非 PBR 场景的全部刚需:
| 函数 | 作用 |
|---|---|
srgbToLinear3/4、linearToSrgb3/4 | 标准 IEC/sRGB 分段转换(不自动夹值,安全可控) |
luminance | Rec.709 相对亮度(0.2126, 0.7152, 0.0722),记得传线性光颜色 |
applyExposure | 按"档/EV"曝光,1.0翻倍、-2.0变 1/4 |
tonemapAces/tonemapReinhard | 常用色调映射,ACES 用 Narkowicz 拟合 |
luminanceThreshold | 亮度阈值提取——做Bloom的高光通道就靠它 |
一条完整的调色链只有三行:
import { srgbToLinear3, applyExposure, tonemapAces, linearToSrgb3 } from "@vgpu/wgsl-std/color"; fn grade(srgb: vec3f, ev: f32) -> vec3f { return linearToSrgb3(tonemapAces(applyExposure(srgbToLinear3(srgb), ev))); }模块刻意不做 PBR 和默认显示管线——显示转换由你自己决定,这正是"标准库"该有的分寸感。
4️⃣ sampling:低差异序列,告别手写采样数学
蒙特卡洛积分、光斑光斑(Bokeh)、模糊核……都需要在圆盘或单位正方形里均匀撒点。sampling 模块 一次给齐:
goldenAngle:黄金角常量(f32 精度2.3999631);vogelDisk(index, count, phi):Vogel 螺旋圆盘采样点(向日葵螺旋那个模型),phi可整体旋转图案;radicalInverseVdc(bits):基数 2 Van der Corput 逆向位串,处理了 f32 舍入到 1.0 的边界;hammersley2d(index, count):经典Hammersley 点集,光照估计的老朋友。
过去你要手写一整段(还容易在count == 0时除零),现在一行导入搞定。文档中附了 before/after 对照,对比非常直观。
实战避坑:三条性能与正确性建议
- remap 而不是 saturate:Perlin/Simplex 的值域是 (-1, 1) 且标准差只有 0.26~0.53,直接
saturate会丢掉整整一半信号。正确姿势是用 math 模块 的remap把你关心的区间映射到 [0, 1]; - 固定核提前算:
vogelDisk每次调用含sqrt/cos/sin,若每个像素都要用同一组点,把它预计算到 buffer 里; - 未使用的导入会被裁掉:
resolveShader()会做声明级死代码消除,import多了也不会白白进 bundle,可以放心按模块整体引入。
场景速查:我该 import 哪个模块?
| 你想做的效果 | 推荐模块 | 关键函数 |
|---|---|---|
| 云、雾、烟雾 | noise/perlin 或 noise/simplex | fbmPerlin3d、fbmSimplex3d |
| 地形山脊 | noise/perlin | perlin3d+ 每八度(1-abs(n))² |
| 细胞/龟裂纹 | noise | voronoi2d,用f2 - f1取边缘 |
| 像素抖动、每格随机 | hash | hash2、pcg3d+unitFloat |
| HDR 调色、Bloom | color | tonemapAces、luminanceThreshold |
| 光照采样、模糊核 | sampling | hammersley2d、vogelDisk |
进一步阅读
- 总览与子路径表:packages/wgsl-std/README.md
- 各模块 API 文档(含公式、参数表、边界说明):src/color/index.docs.md、src/hash/index.docs.md、src/noise/perlin/index.docs.md、src/noise/simplex/index.docs.md、src/sampling/index.docs.md
- 数值验证测试:tests/ 目录下的
perlin.test.ts、sampling.test.ts、color.test.ts等
对新手来说,@vgpu/wgsl-std的价值不在"多高级",而在于:你第一次写着色器时,那些数学细节已经被验证过了。把省下的时间花在画面本身,才是学 WebGPU 的正解 🎨
【免费下载链接】vgpuModular cross-runtime WebGPU library for shaders, 3D scenes, GPU tensors, neural networks, and math viz项目地址: https://gitcode.com/gh_mirrors/vgpu/vgpu
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考