The Monte Carlo method is a numerical method of solving mathematical problems by random sampling (or by the simulation of random variables).
蒙特卡洛法是一类通过随机采样来求解问题的算法的统称,要求解的问题是某随机事件的概率或某随机变量的期望。通过随机抽样的方法,以随机事件出现的频率估计其概率,并将其作为问题的解。
shade(p, wo) //任意一个着色点p,出射方向是wo 按照pdf随机往半球各个方向wi生成N个向量 Lo=0 foreach wi ray r(p, wi) //从p点往wi发射方向连一条光线 if r 射中了光源 Lo += (1 / N) * L_i * f_r * cos / pdf(wi) //L_i是光源辐射出的radiance,f_r是BRDF return Lo
再考虑间接光,其实间接光就是其他物体反射光源的光,也是radiance
就好像我们在P点算Q点的直接光照
在伪代码里加上间接光
1 2 3 4 5 6 7 8 9 10
shade(p, wo) //任意一个着色点p,出射方向是wo 按照pdf随机往半球各个方向wi生成N个向量 Lo=0 foreach wi ray r(p, wi) //从p点往wi发射方向连一条光线 if r 射中了光源 Lo += (1 / N) * L_i * f_r * cos / pdf(wi) //L_i是光源辐射出的radiance,f_r是BRDF elseif r 在q点射中了物体 Lo += (1 / N) * shade(q, -wi) * f_r * cos / pdf(wi) //-wi的原因是,我们从p点往外选了一个方向,对于q点来说是负方向 return Lo
全局光照get✔
路径追踪算法
这个算法还有问题吗?
递归生成光线的数量会指数上升,1->100->10000->…基本不可能计算出来
我们可以只生成一条光线(233)
1 2 3 4 5 6 7 8 9
shade(p, wo) //任意一个着色点p,出射方向是wo 按照pdf随机往半球各个方向wi生成1个向量 Lo = 0 ray r(p, wi) //从p点往wi发射方向连一条光线 if r 射中了光源 Lo += L_i * f_r * cos / pdf(wi) //L_i是光源辐射出的radiance,f_r是BRDF elseif r 在q点射中了物体 Lo += shade(q, -wi) * f_r * cos / pdf(wi) //-wi的原因是,我们从p点往外选了一个方向,对于q点来说是负方向 return Lo
只生成一条光线,连结视点和光源的路径的算法,就叫做路径追踪
但是只生成一条光线,噪声很大,我们可以生成多条路径,再把结果叠加求平均
光线生成算法
我们要对所有像素都发射一条光线
1 2 3 4 5 6 7 8
ray_gen(camPos, pixel) 像素内均匀地在N个不同位置取样sample pixel_radiance = 0 foreachsamplein pixel ray r(camPos, cam_to_sample) //从摄像机位置连一条光线到取样地位置 if r在p点射中了物体 pixel_radiance += 1 / N * shade(p, sample_to_cam) //出射方向是采样点到摄像机 return pixel_radiance
按照pdf随机往半球各个方向wi生成1个向量 Lo = 0 ray r(p, wi) if r 射中了光源 Lo += L_i * f_r * cos / pdf(wi) / P_RR elseif r 在q点射中了物体 Lo += shade(q, -wi) * f_r * cos / pdf(wi) / P_RR return Lo