Low Resolution Rendering

This post concerns low resolution rendering – rendering to lower resolution and then upsampling to full resolution in order to reduce fragment workload

Low resolution rendering is used to reduce fragment workload by rendering to lower resolution render targets and then upsampling to full resolution. The technique is interesting when there is either many fragments that need to be processed, for instance particle rendering with a lot of potential overdraw, or if the fragment workload is very large as in the case of view space ray marching. By lowering the total amount of fragments needed for the effect, we can gain a lot of performance so long as the downsampling and upsampling overhead is small enough. The devil is in the details, avoiding artifacts introduced by the lower resolution rendering.

Rendering in half resolution means that one texel (blue) in the low resolution corresponds to four texels (red) in the full resolution image. Nearest Neighbor Upsampling fetches the corresponding low resolution texel for each of the full resolution texels. Bilinear Upsampling weights the four closest low resolution texels in a 2x2 bilinear footprint. Bilateral  Upsampling uses the same footprint and weights but adds additional weights as a function of the depth discontinuity – weighting by the difference of the low resolution depth and the high resolution depth.

downsample2

upsample_bilinear

 

NVIDIA introduced another alternative where instead of always considering all four texels in the bilinear footprint, the one with the depth closest to the high resolution depth is chosen instead. The depth buffer is downsampled and then each of the low resolution depths in the bilinear footprint is compared to the full resolution depth when upsampling. Finally, the coarse shading texture is point sampled at the texel corresponding to the minimum depth difference. To avoid blocky artifacts, an edge detection algorithm is used to branch and use bilinear filtering as a fallback for non-edge pixels. Another approach is to interpolate between the two cases as a function of the depth discontinuity.

There are several ways to downsample the depth buffer, the simplest way being with point sampling. A better way is to use a min or max filter when considering the four possible high resolution depths for a downsampled texel. Anglelo Pesce proposes a third way is good specifically for Nearest Depth Upsampling, namely alternating a min and max filter in a 2x2 checkered pattern. Since we want to maximise the probability of finding a good depth in the low resolution depth buffer, doing this ensures that a bilinear footprint will have at least two depth downsampled with a min filter and a max filter. An additional idea is to, when used in conjunction with temporal anti aliasing, also shift the checkered pattern each frame.