本文主要是介绍Better Sampling,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
A couple of days ago, I compared the images my ambient occlusion integrator produced with those of Modo using similar settings. I noticed immediately how much ‘cleaner’ the render from Modo was. Clearly there was an issue with the way I was picking my samples, so I set about improving things.
My approach for generating the ambient occlusion rays was to generate uniform random samples over the hemisphere about the normal. Based on two random numbers in the range [0,1), I calculate the normalized sample direction using the following function:
Vector3 Sample::UniformSampleHemisphere( float u1, float u2) { const float r = Sqrt(1.0f - u1 * u1); const float phi = 2 * kPi * u2; return Vector3(Cos(phi) * r, Sin(phi) * r, u1); } |
This generates points on a hemisphere from uniform variables u1 and u2, where each point has equal probability of being selected. The following image was generated with 256 random uniform samples:
It looks pretty noisy, that’s for sure. Part of the trouble comes from the fact that there’s no way to ensure that there’s an even distribution of the rays. A common way to alleviate this problem is to do stratified sampling instead of fully random sampling. The idea of stratified sampling is to split up the domain into evenly sized segments, and then to pick a random point from within each of those segments. You still get some randomness, but the points are more evenly distributed, which in turn reduces the variance. Less variance means less noise. Here’s the scene again, using 256 rays, but this time using stratified sampling:
As expected, it’s much less noisy, and for the same amount of computation!
Sampling for Diffuse Monte Carlo Estimator
The stratified sampler helps out with the indirect diffuse lighting calculation too, but one other thing you can do to reduce noise for the Monte Carlo estimator is to choose random values that have a similar ‘shape’ to the integral you are estimating. Looking at the integral for diffuse reflections, you will see the familiar cosine term inside the integral:
Where c is the diffuse material color, Li is the incoming radiance, and pi is the energy conservation constant.
Rather than wasting samples on areas of the integral where they will get mulitiplied out by the cosine term, why not just choose proportionally fewer samples in those areas?
Recall that the Monte Carlo estimator for an the integral of the function f(x), with probability density function p(x) is:
The probability density function is just a function that returns the probability that a particular value will be chosen. For the uniform hemisphere sampling function above, the pdf is just a constant, (1 / (2 * pi)). This makes the Monte Carlo estimator for the diffuse integral:
Rather than mutliply by the cosine term above, we just want to generate proportionally fewer rays at the bottom of the hemisphere. The integral of the pdf over the hemisphere must equal one, so by switching to a cosine-weighted sample distribution, the pdf becomes (cos(theta) / pi).
This makes the estimator:
Which cleans up rather nicely to:
Normally I would post a couple of images up for comparison’s sake, but in this case, the difference is pretty difficult to perceive without being able to compare one on top of the other. The difference is small, but it is definitely worth it!
The common way to generate a cosine weighted hemisphere sampler is to generate uniform points on a disk, and then project them up to the hemisphere. Here’s some code:
Vector3 Sample::CosineSampleHemisphere( float u1, float u2) { const float r = Sqrt(u1); const float theta = 2 * kPi * u2; const float x = r * Cos(theta); const float y = r * Sin(theta); return Vector3(x, y, Sqrt(Max(0.0f, 1 - u1))); } |
Just by doing these two small steps, I’ve been able to clean up my images significantly. Here’s the scene from above again, this time with single bounce final gather with 256 rays, stratified cosine-sampled:
Next on my list is to take a look at path tracing, followed by irradiance caching (wasn’t that the point of all this?). This should allow me to get fairly cheap multi-bounce diffuse lighting.
http://www.rorydriscoll.com/2009/01/07/better-sampling/
这篇关于Better Sampling的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!