I am having my first encounter with the rendering of indirect reflections in the form of screen space reflections in a game engine, but i am struggling to get correct looking results.

taken at low resolution and ray count

(patterns arise from a bad way of generating noise for montecarlo integration)

(image taken at low ray count. otherwise the color values end up going to NaN)

From what i've gathered, a common formulation of the rendering equation is as follows:


which, dropping the $L_e(p,\omega_o)$ term, can be approximated using the following monte carlo estimator:


where $n$ is a unit vector perpendicular to the surface.

for actual computation of values, all of these terms must be specified.

$L_i(p,\omega_i)$ is found through raymarching in screen space

$fr(\omega_i,\omega_o)$ is the Cook-Torrance BRDF:$\frac{FGD}{4(n\cdot\omega_i)(n\cdot\omega_o)}$

if we name the angle between $n$ and $m$ $\theta$, we get that the GGX NDF is:$D=\frac{\alpha^2}{\pi(\cos^2(\theta)(\alpha^2-1)+1)^2}$

where $m$ is the microfacet normal $m=\frac{\omega_i+\omega_o}{|\omega_i+\omega_o|}$

$p(\omega_i)$ Is the PDF that can be derived from the GGX NDF $\frac{\alpha^2\cos(\theta)\sin(\theta)}{\pi(\cos^2(\theta)(\alpha^2-1)+1)^2}$

When put all together we get:

$$L_o(p,\omega_o)\approx\frac{1}{N}\sum_{i=1}^{N} \frac{L_i(p,\omega_i)\frac{FG}{4(n\cdot\omega_i)(n\cdot\omega_o)}\frac{\alpha^2}{\pi(\cos^2(\theta)(\alpha^2-1)+1)^2}(n\cdot\omega_i)}{\frac{\alpha^2\cos(\theta)\sin(\theta)}{\pi(\cos^2(\theta)(\alpha^2-1)+1)^2}}$$

After simplifying, we get:

$$L_o(p,\omega_o)\approx\frac{1}{N}\sum_{i=1}^{N} \frac{L_i(p,\omega_i)FG}{4(n\cdot\omega_o)\cos(\theta)\sin(\theta)}$$

This procedure seems correct to me but the images produced by my implementation have over exposed reflections at sharp incidence angles or at low roughness values. However, when i remove the $\sin(\theta)$ factor from the denominator it looks plausible (not sure about correctness though).

taken at low resolution with no denoise solution

Thanks in advance.


1 Answer 1


After some testing and some research I have found that both the $\sin(\theta)$ and the $\cos(\theta)$ should be removed from the denominator.

the reasoning is that, since we want a probability function of steradians instead of angles, the $\sin(\theta)$ factor (which is essentially used to convert from steradians on a unit sphere to radians on the two polar axis) should be dropped.

Also, $\cos(\theta)$ (as Nathan Reed explains in this blog post) is there to convert from microfacet area to macrosurface area. Since we are generating microsurface samples, this should be removed.

After these corrections we get the formula


which is free of the artifacts of the formula on the question.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.