Specifying the target layer of a 3D rendertarget in vertex shader? [HLSL]
Asked Answered
E

1

4

When working in HLSL/Directx11 I see there are two methods for binding a 3D rendertarget: either you bind the entire target or you bind it while specifying a layer.

If you bind the entire target how does one specify the layer in HLSL code to which the output color is applied?

I have a suspicion this requires a geometry shader ... is that correct?

Is there any other approach which would allow this to be done in the vertex shader or elsewhere?

Eada answered 24/9, 2013 at 22:5 Comment(0)
H
3

If you bind your whole volume texture (or TextureArray), you indeed need to use Geometry Shader to write to a specific slice.

your GS output structure will look like this:

struct GSOutput
{
    float4 pos : SV_Position;
    uint slice : SV_RenderTargetArrayIndex;
    //Add anything else you need for your triangle
};

Please not that slice is not interpolated, so if you need to emit to several slices you need to push one primitive per slice.

Second case where you do not want to use Geometry Shader.

Create a rendertargetview description with the same parameters as the previous one, but for each slice, change those parameters (This is for a Texture2DArray, but it's mostly the same if you use Texture3D) :

D3D11_RENDER_TARGET_VIEW_DESC rtvd;

rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rtvd.Texture2DArray.ArraySize = 1;
rtvd.Texture2DArray.FirstArraySlice = yourslice;

Now you have a render target for the slice only, so you can directly bind a single slice in the pipeline.

Please note that this only works if you know in advance (in CPU) to which slice your draw call will render. Also you can render to a single slice only for this draw call.

Hae answered 29/9, 2013 at 5:20 Comment(4)
So this is the only way? If you know in advance of the draw call that there is a quad you wish to go to layer 0 and another quad to layer 1. Can that be accomplished in a single draw call without the use of a geometry shader, via packing the correct information (somehow) in the vertex data (or some other stream) from the cpu-side?Eada
Updated answer with slice example.Hae
Just realized that it actual is possible... using multiple render targets. Bind each slice of the 3D texture to a separate render target slot. Then your vertex shader outputs n colors where n is number of slices, but only one of those (decided based on vertex shader logic or elsewhere) will be assigned the color your shader computed. Render with an additive blend mode, and voila, one shader that renders to the 3d slice of your choice, per pixel, with one draw call.Eada
Good point, in that case you get limited to 8 slices per call, but that can fit a use case indeed.Hae

© 2022 - 2024 — McMap. All rights reserved.