• Advertisement
Sign in to follow this  

3D Texture Render Target?

This topic is 2507 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Using DirectX 11 (or earlier), is it possible to make bind a Texture3D as a render target? i.e. I'd like to have my pixel shader writing values into a 3D texture

Share this post


Link to post
Share on other sites
Advertisement
Would it be possible for you to give a quick explanation (and ideally code sample) on how to do achieve this scenario?

I am assuming it looks something like making a D3D11_TEXTURE3D_DESC and then creating a D3D11_RENDER_TARGET_VIEW_DESC for that texture but I am not clear on what it would be code-wise in the shader to set which u,v,w would be written by the pixel shader.

Big thanks!

Share this post


Link to post
Share on other sites
it is actually not that difficult. First you have to create the texture (i hope its pretty selfexplanatory)


ID3D10Device* pDevice = Renderer::getInstance()->getDevice();

ID3D10Texture3D* colorMap = 0;

D3D10_TEXTURE3D_DESC texDesc;
texDesc.Width = _width;
texDesc.Height = _height;
texDesc.Depth = _depth;
texDesc.MipLevels = 0;
texDesc.Format = _colorFormat;
texDesc.Usage = D3D10_USAGE_DEFAULT;
texDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS;

HR(pDevice->CreateTexture3D(&texDesc, 0, &colorMap));

HR(pDevice->CreateRenderTargetView(colorMap, 0, &m_colorMapRTV));
HR(pDevice->CreateShaderResourceView(colorMap, 0, &m_colorMapSRV));

ReleaseCOM(colorMap);
buildViewport(_width, _height);


when writing to the texture you have to choose the layer via a geometry shader - for example in c++ code you have something like that


for (unsigned int layer = 0; layer < RES_DEPTH; ++layer)
{
shader->setInt("g_layer", layer);
shader->activate("RenderSomethingTo3DTexture");
m_fullScreenQuad->render();
}



then the geometry shader chooses the specific layer


struct GS_OUT_LAYER
{
float4 posH : SV_POSITION;
float2 texC : TEXCOORD;
uint layer : SV_RenderTargetArrayIndex;
};

[maxvertexcount(3)]
void GS_SetLayer(triangle VS_OUT input[3],
inout TriangleStream<GS_OUT_LAYER> triOutputStream)
{
GS_OUT_LAYER output;

for(int i=0; i < 3; ++i)
{
output.posH = input.posH;
output.texC = input.texC;
output.layer = g_layer;

triOutputStream.Append(output);
}
}



Important is the system-value semantic SV_RenderTargetArrayIndex which chooses the slice/layer in depth to which the pixel shader writes.

hope this helps!

Share this post


Link to post
Share on other sites
Also if you'd rather render to 1 layer at a time without a geometry shader, you can create a render target view per layer by setting Texture3D.FirstWSlice to the slice you want, and Texture3D.WSize to 1.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement