What Is SV_Target in DirectX Pixel Shaders?
In DirectX High-Level Shader Language (HLSL), SV_Target
is a system-value semantic used to route pixel shader output data
directly into render targets. This article explains the fundamental
purpose of SV_Target, how it directs color values to the
graphics pipeline's Output Merger stage, its role in Multiple Render
Target (MRT) setups, and why it is essential for rendering 3D graphics
on modern GPUs.
The Purpose of System-Value Semantics
In HLSL, semantics are string tags attached to shader inputs and
outputs that communicate intent to the HLSL compiler and the graphics
pipeline. Prefixed with SV_, system-value semantics
indicate that the attached variable has a hardware-defined role rather
than user-defined data.
When a pixel shader completes its calculations, the GPU must
determine where the resulting data should be written. The
SV_Target semantic specifies that the returned value is a
color intended for an active render target view (RTV) bound to the
pipeline.
Directing Data to the Output Merger
The pixel shader is one of the final programmable stages in the
graphics pipeline, sitting just before the fixed-function Output Merger
(OM) stage. Without a semantic like SV_Target, the compiler
cannot determine which buffer should receive the computed pixel
color.
When the pixel shader outputs a value marked with
SV_Target, the Output Merger stage:
- Receives the raw color output (typically a vector such as
float4). - Applies any active pipeline configurations, such as depth-stencil tests, blend modes, and write masks.
- Commits the final computed color into the bound render target memory (such as a back buffer or an off-screen texture).
By default, annotating an output with simply SV_Target
maps to index 0, which corresponds to the first render target bound to
the device context (SV_Target0).
Multiple Render Targets (MRT)
Modern rendering engines frequently write to more than one render target in a single draw call. This technique, known as Multiple Render Targets (MRT), forms the foundation of deferred rendering and post-processing pipelines.
HLSL allows numerical indexing appended to SV_Target,
ranging from SV_Target0 through SV_Target7
(supporting up to eight simultaneous render targets in DirectX 11 and
12).
Instead of returning a single float4, a pixel shader can
return a structure containing multiple fields:
struct PixelOutput
{
float4 Color : SV_Target0;
float4 Normal : SV_Target1;
float4 Material : SV_Target2;
};
In this setup:
SV_Target0writes the diffuse/albedo color to the first bound render target.SV_Target1writes world-space or view-space normals to a second buffer.SV_Target2writes material properties (such as roughness, metallic, or ambient occlusion) to a third buffer.
This allows a single geometry pass to generate a complete G-Buffer without running vertex and pixel processing multiple times.
Data Types and Component Matching
While SV_Target commonly annotates standard
float4 color vectors, it supports various data types
matching the underlying resource format bound to the render target:
- Floating-point targets: Standard textures
(
R8G8B8A8_UNORM,R16G16B16A16_FLOAT) utilizefloat,float2, orfloat4. - Integer targets: Formats such as
R32_UINTorR16G16_SINTacceptuintorintvectors.
If the shader outputs fewer components than the target format possesses, default values apply (typically zero for green and blue, and one for alpha). If the shader outputs more components than the target format supports, the excess components are discarded during the Output Merger stage.