On XR platforms that use variable rate rasterization (VRR), the pixels Unity renders no longer form a regular grid. Custom shaders that perform screen-space calculations can therefore produce incorrect results. To make such a shader work on every platform, add the foveated rendering shader library and remap coordinates between the linear and non-uniform raster spaces.
Shaders that don’t sample in screen space need no changes. Neither do the shaders that Unity and the Universal Render Pipeline (URP) provide, because they already use the foveated rendering macros. For an explanation of the two raster spaces and which coordinates each texture takes, refer to Introduction to foveated rendering.
Before you begin, make sure that:
When your project meets these conditions, add the shader library to your shader, then convert the coordinates that its screen-space calculations use. To adapt an effect that you built in Shader Graph instead, refer to Update shader graph effects for foveated rendering.
The shader library files contain keywords and macros for foveated rendering, and functions that map screen-space coordinates from non-uniform to linear and the reverse.
To make your URP screen-space shaders produce correct results under foveated rendering, add the following include files from the Core RP Library package to your shader:
#include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
After you add these includes, the foveated rendering shader functions are available in your shader.
Each of the following conversions returns the coordinates unchanged when foveated rendering isn’t active, or when the platform doesn’t use a non-uniform raster. The shader therefore produces correct results in all cases.
To convert a UV coordinate in linear screen space to non-uniform raster screen space:
uvNonUniform = FoveatedRemapLinearToNonUniform(uvLinear);
To convert a UV coordinate in non-uniform raster screen space to linear screen space:
uvLinear = FoveatedRemapNonUniformToLinear(uvNonUniform);
To update effects, such as Gaussian blur, that rely on fixed texel offsets, scale the offsets according to the local pixel density. At the center of the field of view, the density ratio is 1.0, so you don’t need to scale the offsets. At the periphery, the same number of texels cover more screen area, so divide the offsets by the density to compensate:
float2 density = FoveatedRemapDensity(uvLinear);
Note: Metal doesn’t implement the density functions, so this technique doesn’t scale offsets on visionOS. The coordinate remapping functions work on all platforms that use non-uniform rasterization.
For the full set of remapping functions and what each one returns, refer to Foveated rendering shader functions reference.