码迷,mamicode.com
首页 > 编程语言 > 详细

C++随机数导致的bug

时间:2020-03-08 17:36:40      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:gre   光照   时间差   rac   怎么   bug   a*   amp   点光源   

这周我在写path tracing的时候遇到了一个很奇怪的bug:光线追踪深度设为1的时候结果看起来是正常的,但是深度高于1的时候就会出现很奇怪的渲染结果,如下图所示(为了便于调试,我用了一个cornell-box的场景,mesh的颜色是统一的,并且设置的只是点光源):
技术图片
我仔细排查了逻辑上的代码,并没有发现几何计算、光照计算等模块有明显的问题(如果有问题,应该在depth为1的时候就测试出来了)。这时我观察到,这个颜色呈现出“一块一块”的表现,我猜测可能是由于在光线做完第一次碰撞后,利用随机数产生出射光线进行第二次碰撞,但是随机数分布并不均匀导致的。
于是我试着把代码中所有的srand全部去掉,果然结果就正常了。也就是说,是srand导致了产生的随机数分布不均匀
那么我的srand是怎么用的呢?

Pixel PathTracingRenderer::sample_pixel(Camera* camera, int x, int y, int width, int height)
{
    srand(time(0));
    float sample_x = 0.0f;
    float sample_y = 0.0f;
    Spectrum r;
    Pixel p;
    for (int i = 0; i < sample_count; i++)
    {
            //compute sample result
    }
    return p;
}

我将srand写到了遍历每个像素的代码里,这明显是不对的。我们可以做个试验来验证一下:
下图是我不使用srand,完全随机生成的一堆二维点,可以看到基本上是随机分布的:
技术图片
假设我这样写:

for (int i = 0; i < 100; i++)
{
    srand(time(0));
    std::cout << rand() % 101 << "," << rand() % 101 << ";"<<std::endl;
}

生成的结果会是如下所示的(请原谅我看到结果时笑出了声):
技术图片
之后我又做了很多次试验,发现只有每次生成随机数间隔时间差不多1s,这样写才能生成比较随机的结果:
技术图片
所以导致这个bug的答案也就呼之欲出了:srand会重置随机生成的结果,输入同一个种子,那么第一次rand的结果是一样的。之所以会导致如图所示的问题,就是因为相邻像素之间重复调用srand,而相隔的时间又很短,不断重置随机数结果,始终生成了相同的随机数,那么自然就会出现上图这种“颜色聚集”的情况了。
于是我就把代码改成了每次只有在渲染前才会srand一次,这样一来结果就正常了(和PBRT相同的场景与光照比对基本一致):
技术图片

C++随机数导致的bug

标签:gre   光照   时间差   rac   怎么   bug   a*   amp   点光源   

原文地址:https://www.cnblogs.com/wickedpriest/p/12443131.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!