High variance in path tracing specular objects I'm testing my path tracer for specular surfaces. Images rendered with my own code have very noisy appearance, and I think they look like variance.

I use point light and the bunny is of mirror material, walls are matte. If it is the problem with sampling, how should I modify the program. To my understanding, point lights are specially handled and thus the sampling results should be a constant value. So I don't think the noise is caused by light sampling. So could there be any bugs?

When only matte material exists in the scene, there are also variance, but not that bad, and global illumination effects are visible. So what could the problem?


  specular bunny:





  matte bunny:




For the specular bunny image, spp is 4. Since it is a point light, wi is directly set to the vector between point light and intersection point when calculating direct illumination, so there is actually no "sampling". When computing scattering directions, BRDF is matte when intersecting the wall, and BRDF is specular reflection when the ray hit the bunny.

Matte BRDF is cosine weighted sampled, while specular reflection just use the perfect reflection direction.
If your bunny is purely specular, then sampling the light directly at the shade point would give no contribution since the specular BSDF is a delta BSDF. It generally evaluates to zero for any direction other than the mirror direction. If it was a glossy BSDF, then it might be possible that the pdf value could be very small so that the monte-carlo estimator $\frac{f(X)}{P(X)}$ just explodes (which is generally the source of fireflies i.e having a very small pdf and the function is large).

If it was a mirror direction, then you should just see a black bunny for direct illumination and just the reflection of the surrounding scene for multiple bounces. Multiple bounces from the specular bunny should not be cause fireflies, because if you're sampling based on cosine term at the matte surface, the estimator becomes $\frac{L_i(X)f_r(X)\cos(\theta_i)}{\text{pdf}(\theta_i)}$, where $\theta_i$ is the sampled direction using BSDF sampling at the matte surface. The pdf and the $\cos(\theta_i)$ should cancel out each other perfectly. However since you're using a point light, you can never sample from the BSDF since the light is a delta light and needs an explicit connection. Hence the pdf for the estimator would be 1 all the time. The only way for large values to creep up are in the numerator. So I would suggest you to check the values by increasing bounce one by one to see when the problems start creeping in.