VDR Follow Up – Grain and Fine Details

The prior post in this series established a base technique for adding grain, and now this post is going to look at very subtle changes to improve quality using the same 3-bit/channel quantization case from the prior post. The first change is to apply a clamped amount of sharpening prior to adding the grain. Grain can have a tendency to disrupt and mask fine detail. The sharpening is designed to increase the minimum contrast on an edge to the point where it survives the addition of grain. The second change is to adjust the Probability Density Function of the grain. 

The image below to the left is a crop from the prior post: no sharpening and a Rectangular Probability Density Function (RPDF). To the left: sharpening and something similar to a Gaussian Probability Density Function (GPDF). The differences can be hard to spot, look in the upper right under the green leaves. The fine detail is better preserved for the vines.



The sharpening is a simple 3×3 filter kernel applied to the linear color. The sharpening is limited so that the maximum change is proportional to the amount of grain added to the image.

float3 sharpen; // added to color to sharpen the image
float1 limiter; // constant factor proportional to the amount of grain added 
float3 maxSharpen = max3(abs(sharpen.r), abs(sharpen.g), abs(sharpen.b));
sharpen *= min(limiter, maxSharpen) / maxSharpen;

Probability Density Function

The prior post established a sorting technique to force a texture into a uniform or Rectangular Probability Density Function. After building a RPDF texture, the PDF can be changed by taking the grain value which ranges from {-1.0 to 1.0}, and applying a function to that value. Below I used f(x) = x*abs(x) to shape into a Triangular Probability Density Function (TPDF). And then f(x) = (3.0*x*x - 2.0*x*x*abs(x)) * sign(x) (aka smoothstep() in HLSL and GLSL ) to shape into something similar to a Gaussian Probability Density Function. 

First the result for the TPDF,


The TPDF reduces the amount of visible grain by reducing the probability of getting a grain value close to {-1} or {1}. This has a positive visual side effect of increasing clarity for fine detail. However this appears to have a non-energy conserving side effect as well: the quantized value is more likely to stay close to a band. In the above image the lower right dark colors move closer to black (in an area which has no full black values). 

This is easier to see in the four cropped swatches below. From the left to right: {RPDF, GPDF proxy, TPDF, and original image}.


The GPDR proxy below, implemented via the smoothstep() function, provides a middle ground which does not exhibit as obvious tonal separation,


Practical Application

Regardless of application of grain/dithering in linear (this series) or after conversion to a non-linear output space (alternative method), the aim of these techniques is to remove banding regardless of bit-depth and maximize the visual quality of the pixel. These techniques applied temporally look substantially better. 

Mikkel Gjoel’s dithering section of Playdead’s Low Complexity, High Fidelity – INSIDE Rendering talk at GDC 2016 shows a great example of using grain mixed with temporal AA to remove banding while maintaining cache friendly and lower bandwidth 32-bit/pixel color formats. See the first few seconds of the Youtube Video.

Other posts in this series


The TressFX library is AMD’s hair/fur rendering and simulation technology. TressFX is designed to use the GPU to simulate and render high-quality, realistic hair and fur.


ShadowFX library provides a scalable GCN-optimized solution for deferred shadow filtering. It supports uniform and contact hardening shadow (CHS) kernels.


GeometryFX improves the rasterizer efficiency by culling triangles that do not contribute to the output in a pre-pass. This allows the full chip to be used to process geometry, and ensures that the rasterizer only processes triangles that are visible.


LiquidVR™ provides a Direct3D 11 based interface for applications to get access to the following GPU features regardless of whether a VR device is installed on a system.


Compressonator is a set of tools to allow artists and developers to more easily work with compressed assets and easily visualize the quality impact of various compression technologies.


GPUPerfAPI provides access to GPU Performance Counters. It analyzes performance and execution characteristics of applications using a Radeon™ GPU.

Radeon™ Rays

The lightweight accelerated ray intersection library for DirectX®12 and Vulkan®.

Radeon ProRender

Radeon™ ProRender

AMD Radeon™ ProRender is a powerful physically-based path traced rendering engine that enables creative professionals to produce stunningly photorealistic images.

TrueAudio Next

AMD TrueAudio Next is a software development kit for GPU accelerated and multi-core high-performance audio signal processing.

Other posts by Timothy Lottes

Timothy Lottes

Timothy Lottes

Timothy Lottes is a member of the Graphics Performance R&D team at AMD. Links to third party sites are provided for convenience and unless explicitly stated, AMD is not responsible for the contents of such linked sites and no endorsement is implied.

Enjoy this blog post? If you found it useful, why not share it with other game developers?

You may also like...

Getting started: our software

New or fairly new to AMD’s tools, libraries, and effects? This is the best place to get started on GPUOpen!

Getting started: development and performance

Looking for tips on getting started with developing and/or optimizing your game, whether on AMD hardware or generally? We’ve got you covered!

If slide decks are what you’re after, you’ll find 100+ of our finest presentations here. Plus there’s a handy list of our product manuals!

Developer guides

Browse our developer guides, and find valuable advice on developing with AMD hardware, ray tracing, Vulkan, DirectX, UE4, and lots more.

Words not enough? How about pictures? How about moving pictures? We have some amazing videos to share with you!

The home of great performance and optimization advice for AMD RDNA™ 2 GPUs, AMD Ryzen™ CPUs, and so much more.

Product Blogs

Our handy product blogs will help you make good use of our tools, SDKs, and effects, as well as sharing the latest features with new releases.


Discover our published publications.