Depth Buffer 4010 Visite) DirectX 12
Il Depth buffer é un particolare buffer di memoria utilizzato per lo Z-buffer, cioè il calcolo della profondità.
Ogni volta che DirectX sta per renderizzare un pixel verifica se questi si trova davanti o dietro il resto della scena. Per ogni pixel viene calcolata la distanza dalla telecamera con un valore da 0 ad 1 e confrontato con il valore presente sul Depth buffer: se minore disegna il pixel e sovrascrive il valore, altrimenti non esegue il pixel Shader.
Una tecnica per ottimizzare é quella di renderizzare gli oggetti dal più vicino al più lontano in modo che più pixel possibili vengano scartati dallo Z-buffer.
Creiamo un Depth buffer
DescriptorHeapDescription dsvHeapDesc = new DescriptorHeapDescription()
{
DescriptorCount = FrameCount,
Flags = DescriptorHeapFlags.None,
Type = DescriptorHeapType.DepthStencilView
};
depthStencilViewHeap = device.CreateDescriptorHeap(dsvHeapDesc);
CpuDescriptorHandle dsvHandle = depthStencilViewHeap.CPUDescriptorHandleForHeapStart;
ClearValue depthOptimizedClearValue = new ClearValue()
{
Format = Format.D32_Float,
DepthStencil = new DepthStencilValue() { Depth = 1.0F, Stencil = 0 },
};
Resource depthTarget = device.CreateCommittedResource(
new HeapProperties(HeapType.Default),
HeapFlags.None,
new ResourceDescription(ResourceDimension.Texture2D, 0, width, height, 1, 0, Format.D32_Float, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowDepthStencil),
ResourceStates.DepthWrite,
depthOptimizedClearValue);
Come vedete si tratta di creare un buffer come texture ma per cui sia possibile effettuare il Depth stencil.
var depthView = new DepthStencilViewDescription()
{
Format = Format.D32_Float,
Dimension = DepthStencilViewDimension.Texture2D,
Flags = DepthStencilViewFlags.None,
};
device.CreateDepthStencilView(depthTarget, null, DsvHandle);
Dove DsvHandle é il prossimo puntatore dell'Heap.
Anche qui la risorsa viene posizionata nell'heap, usate lo stesso del render target.
Ora, quando inserite il render target nella command list
commandList.SetRenderTargets(1, rtvHandle, false, dsvHandle);
Quindi pulite il buffer
commandList.ClearDepthStencilView(dsvHandle, ClearFlags.FlagsDepth, 1, 0);
Ora il depth buffer é pronto.
Per attivarlo é sufficiente impostare due proprietà della Graphics pipeline come segue
DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
DepthStencilState = DepthStencilStateDescription.Default(),
Ora il rendering di oggetti rispetterà le regole di profondità.
Nei successivi tutorial vedremo come personalizzare il comportamento di questo buffer e soprattutto su come utilizzare effetti basati sull'uso di questo buffer come lo Z-pass e le ombre tramite Shadow map.
Vi rimando alla demo HelloDepthBuffer sul mio repository github.