如何在WGSL中使用随机数实现片段着色器黑白噪点渲染
WGSL 片段着色器生成随机数实现白噪的方案
WGSL 规范确实没有内置随机数生成接口,目前有两种通用实现方案:
- 方案1:使用基于片段坐标的伪随机哈希函数
这是最轻量化的方案,不需要额外资源依赖,通过数学哈希函数把当前片段的屏幕坐标转换成近似均匀分布的0~1随机值,效果足以满足绝大多数白噪渲染需求。
首先实现通用随机函数:
// 输入二维种子(一般为当前片段的屏幕坐标),输出0~1区间的均匀随机值 fn random(seed: vec2<f32>) -> f32 { return fract(sin(dot(seed, vec2<f32>(12.9898, 78.233))) * 43758.5453123); }
在片段着色器中调用方式如下:
[[stage(fragment)]] fn main(@builtin(position) frag_coord: vec4<f32>) -> [[location(0)]] vec4<f32> { let color: f32 = random(frag_coord.xy); // 如果需要动态变化的白噪,可以额外传入uniform时间变量,调整函数入参支持三维种子即可 return vec4<f32>(color, color, color, 1.0); }
上述代码使用的魔数是图形领域经过验证的经典参数,生成的白噪分布足够均匀,如果需要更高质量的随机分布,也可以自行更换更高阶的哈希函数实现。
- 方案2:预生成噪声纹理采样
如果对随机性要求更高,或者需要固定随机序列避免伪哈希函数的周期性问题,可以提前在CPU侧生成一张单通道的噪声纹理,每个像素存储0~1的随机值,在着色器中直接对这张纹理进行采样即可。
这种方案性能开销更低,只需要绑定一张小分辨率的噪声纹理(通常256x256即可),采样时纹理 wrap 模式设置为 repeat 就可以适配任意尺寸的渲染目标。
内容的提问来源于stack exchange,提问作者Michael Hilus
相关产品推荐
相关产品推荐

