Custom compute shaders can act as analysis effects, producing typed output fields that are read back to the CPU and can drive downstream effect properties via data bindings.
| Type | Pixels | Packing |
|---|---|---|
float |
1 | .x used |
float2 |
1 | .xy used |
float3 |
1 | .xyz used |
float4 |
1 | all 4 components |
floatarray |
ceil(N/4) | 4 floats packed per pixel |
float2array |
N | .xy per pixel |
float3array |
N | .xyz per pixel |
float4array |
N | all 4 per pixel |
D2D evaluates compute effects in tiles. Key conventions:
_TileOffset(int2): Auto-injected at cbuffer offset 0 inCalculateThreadgroups. Gives the tile's origin in the full image.Source.GetDimensions(): Returns the full source image size (not tile size).SampleLevel(): Must use normalized UVs viaSampleLevel().Load()is not available in D2D compute shaders.Output.GetDimensions(): Returns the tile size, not the full image.- Constant buffer upload: Done in
CalculateThreadgroups(notPrepareForRender) for correct per-tile values.
cbuffer Constants : register(b0) {
int2 _TileOffset; // Auto-injected per tile
// User parameters here...
};
Texture2D Source : register(t0);
RWTexture2D<float4> Output : register(u0);
SamplerState Sampler0 : register(s0);
[numthreads(8, 8, 1)]
void main(uint3 DTid : SV_DispatchThreadID) {
uint srcW, srcH;
Source.GetDimensions(srcW, srcH);
uint2 globalPos = DTid.xy + uint2(_TileOffset);
if (globalPos.x >= srcW || globalPos.y >= srcH) return;
float2 uv = (float2(globalPos) + 0.5) / float2(srcW, srcH);
float4 color = Source.SampleLevel(Sampler0, uv, 0);
Output[DTid.xy] = color;
}