Home Page Twitter Facebook Feed RSS
NotJustCode
Apri

Render Target 9797 Visite) DirectX 12

I render target sono oggetti diventati standard nella realizzazione di effetti grafici. Un render target é una risorsa che può essere usata in lettura come una texture ed in scrittura come i  target che si usano per mandare a video le immagini.

Questo permette di realizzare tutti gli effetti che si vedono nei videogiochi moderni dai riflessi alle ombre, dai vari filtri SSAO al deferred rendering.

FClearValue renderTargetOptimizedClearValue = new ClearValue()

{

Format = Format.R8G8B8A8_UNorm, Color = new Vector4(0, 0.2F, 0.4f, 1)

};

postProcessingRenderTarget = device.CreateCommittedResource(

new HeapProperties(HeapType.Default),

HeapFlags.None, 

new ResourceDescription(ResourceDimension.Texture2D, 0, TargetSize, TargetSize, 1, 0, Format.R8G8B8A8_UNorm, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowRenderTarget),

ResourceStates.RenderTarget,

renderTargetOptimizedClearValue

);

Quindi si passa a creare una vista sul Render Target

CpuDescriptorHandle rtvHandle = renderTargetViewHeap.CPUDescriptorHandleForHeapStart + device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView) * renderTargetPosition;

device.CreateRenderTargetView(postProcessingRenderTarget, null, rtvHandle);

Come vedete nulla di diverso dai normali target. Si passa quindi a creare una vista sulla risorsa

 

int D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING = 5768;

ShaderResourceViewDescription desc = new ShaderResourceViewDescription

{

Dimension = ShaderResourceViewDimension.Texture2D,

Format = postProcessingRenderTarget.Description.Format,

Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,

};

desc.Texture2D.MipLevels = 1;

desc.Texture2D.MostDetailedMip = 0;

desc.Texture2D.ResourceMinLODClamp = 0;

device.CreateShaderResourceView(postProcessingRenderTarget, desc, resourceViewHeap.CPUDescriptorHandleForHeapStart + device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView) * renderTargetViewPosition);

In pratica abbiamo creato una risorsa come Render Target e contemporamente abbiamo creato una vista partendo da questa. Ora dovrete procedere in 2 o più step:

  1. Impostare come render target le risorse create
  2. Renderizzare la scena
  3. Impostare i target primari
  4. Renderizzare un altra scena utilizzando i target precedenti come texture.

Il comando SetRenderTargets sarà utilizzato anche per impostare i Render Target. Di fatto non c'è differenza per DirectX, in quanto lui renderizza su un target, poi se è associato ad una texture o al video poco cambia. Come utilizzare i target dipenderà dalla vostra capacità e fantasia. Potete ad esempio renderizzare una scena e poi usare la texture per simulare un monitor che riprende una scena oppure fare effetti di postprocessing. Ad esempio potete renderizzare su un target la scena, quindi utilizzare come texture di un rettangolo a pieno schermo per modificare tonalità di colore, deformare la scena, sfocarla, etc. Ormai è normale fare anche 10-20 step creando moltissimi render target per creare una scena.

Ricordate che un Render Target andrà pulito con un clear e che dovrete creare anche più depth buffer se necessario.

Vi lascio all'esempio Hello Render target nel mio repository