Rendering su texture 1450 Visite) DirectX 11
Una delle possibilità che DirectX offre ormai da molte versioni è la possibilità di effettuare il rendering di una scena su di una texture che possiamo poi utilizzare per altri scopi (un esempio è la possibilità di visualizzare una scena che contiene un monitor con all'interno un'altra scena).
La tecnologia di rendering sulle texture è diventata a partire dalla versione DirectX9 qualcosa di fondamentale per la computer grafica. Tramite il rendering sulle texture sono possibili effetti come riflessione e rifrazione delle superfici, post processing (ad esempio la profondità di campo) e tutta una serie di tecniche che fanno la differenza. Ad oggi non esiste prodotto che non fa uso di questa tecnologia.
In Direct3D11 il render to texture è stato reso molto più semplice e potente. Potrete infatti utilizzare fino ad 8 render target contemporaneamente ed indirizzare grafica differente ad ognuno di essi. In questo tutorial vi illustrerò come implementare una scena con un render target.
Per prima cosa dovrete creare una texture da utilizzare come bersaglio della rendering.
Texture2D target = new Texture2D(Device, new Texture2DDescription()
{
Format = format,
Width = width,
Height = height,
ArraySize = 1,
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
MipLevels = 1,
OptionFlags = ResourceOptionFlags.None,
SampleDescription = new SampleDescription(1, 0),
Usage = ResourceUsage.Default,
});
Come potete vedere la risorsa creata ha come bindFlags Render_Target e Shader_Resource. Questo perchè vogliamo utilizzare la texture sia come bersaglio che come texture per un modello 3D. Ora dobbiamo creare il RenderTargetView
RenderTargetView _target = new RenderTargetView(Device, target);
Infine si crea uno ShaderResourceView che ci servirà per essere utilizzato dallo shader.
ShaderResourceView _resource = new ShaderResourceView(Device, target);
Avete già visto questo oggetto. Il device infatti vi ha richiesto di crearne uno e qui non abbiamo fatto altro che crearne uno simile ma collegato alla texture.
Avete ora creato le risorse che vi servono, il targetView da utilizzare per passarlo al device come destinazione di rendering e lo ShaderResourceView da passare allo shader come risorsa. Qui potrete anche distruggere la texture (la variabile target) in quanto non più necessaria.
Ora per utilizzare il nuovo target dovrete semplicemente passarle alla funzione SetTarget
DeviceContext.OutputMerger.SetTargets(_zbuffer, _target);
La variabile _zbuffer, eventualmente anche NULL, è una superficie DepthStencilView che va creata in modo identico a quanto fatto per il Device. L'unica differenza sarà la dimensione che dovrà essere uguale a quella utilizzata per il target (sempre come il Device). Al momento dell'inserimento dovrete modificare anche il viewport per porlo uguale a quello della texture.
Dal momento in cui avrete inserito i target ogni oggetto sarà renderizzato sulla texture anzichè sullo schermo. Al termine non dovrete far altro che rimettere come target il backbuffer e lo ZBuffer originari. Qui potrete utilizzare lo ShaderResourceView come texture per un modello 3D o uno sprite.
Vi rimando al tutorial numero 9 della serie (Github o in fondo dal primo tutorial)