interleavedGradientNoise
interleavedGradientNoise
基于 Jimenez 2014 的“交错梯度噪声”(IGN)。输入二维坐标返回 [0,1) 的低差异随机值,像素稳定,适合抖动和采样扰动。
核心优势
计算极廉价(点积和 fract),分布均匀且无明显条纹,相比白噪声更适合用于去条带与屏幕空间抖动;对同一位置输出稳定,便于可复现结果。
常见用途
对颜色渐变做屏幕空间抖动以消除 8‑bit 条带
透明度抖动/随机覆盖率以软化 alpha test 边缘
为 TAA/多重采样生成像素级低差异抖动序列
在 SSAO/SSR/体积效果中随机化采样旋转或偏移
打散屏幕空间模糊、Bloom 等效果中的规则图案
如何调整
1) 坐标选择:为获得分辨率无关且像素稳定的图样,推荐传入整数像素坐标,如 floor(viewportCoordinate)。若使用归一化 UV(如 viewportCoordinate.div(viewportSize)),图样会随分辨率变化。2) 抖动强度:通过缩放使用该噪声的幅度来控制效果强弱,例如 dither = (IGN - 0.5) * (1/255)。3) 时间变化:用 frameId 或 time 作为附加种子改变逐帧图样,例如 interleavedGradientNoise( floor(viewportCoordinate) + float(frameId) )。4) 空间域:屏幕空间抖动优先用 viewportCoordinate;若需物体空间随机性,可改用 positionWorld.xz 或模型 UV。
代码示例
1// 用例A:8-bit 渐变抖动,减少条带
2const pixel = floor( viewportCoordinate ); // 整数像素坐标
3const ign = interleavedGradientNoise( pixel ); // [0,1)
4const dither = ign.sub( 0.5 ).mul( 1.0 / 255.0 ); // 约一个量化台阶
5
6const uvScreen = viewportCoordinate.div( viewportSize );
7const gradient = uvScreen.y; // 垂直渐变 0..1
8output.color = vec3( gradient.add( dither ) ).saturate();
9
10// 用例B:随机覆盖率透明,软化 alphaTest 边缘
11const baseAlpha = texture( map, uv() ).a.saturate();
12const n = interleavedGradientNoise( floor( viewportCoordinate ) );
13if ( n.greaterThan( baseAlpha ) ) { discard(); }
14
15// 可选:逐帧更换图样(例如在 TAA 中)
16const nTemporal = interleavedGradientNoise( floor( viewportCoordinate ).add( float( frameId ) ) );