关于着色器噪声:使用特定伪随机函数生成随机值出现清晰边界的问题

现象原因
这个边界问题是当前sin-fract伪随机实现的浮点数精度丢失和参数适配不佳共同导致的,具体逻辑如下:
- 你所用的伪随机逻辑核心是将dot乘积的结果输入sin函数得到[-1,1]区间的值,放大后取小数部分得到随机值。当uv是逐像素离散递增值时,
dot(uv, vec2(18.13,98.16))的相邻像素增量会非常小,sin(x)的输出增量乘以19978.13之后,很容易小于32位浮点数的最小可表示步长,这时候sin(x)*19978.13的输出会出现阶梯式跳变,fract取小数后就会出现连续多像素值相同的情况,最终形成清晰的平直边界。 - 你选择的18.13、98.16、19978.13这组系数没有完全打散输入uv的线性关联,当uv沿某一方向变化时,dot结果的变化会和sin周期出现局部同步,进一步放大了边界的可见性。
优化方案
- 条件允许的话优先替换为32位整数哈希实现的伪随机函数,完全规避sin函数带来的精度问题,随机质量也更高。
- 如果要保留当前实现,可以把放大系数替换为业界常用的验证值
43758.5453123,能大幅降低精度不足导致的边界问题。 - 支持双精度的平台可以将这段计算切换为double类型执行,也能有效缓解精度丢失问题。
内容的提问来源于stack exchange,提问作者Forever Learner
相关产品推荐
相关产品推荐

