2011-07-31 11 views
5

Estoy usando SlimDX, apuntando a DirectX 11 con shader modelo 4. Tengo un sombreador de píxeles "preProc" que procesa mis vértices y guarda tres texturas de datos. Una para las normales por píxel, una para los datos de posición por píxel y otra para el color y la profundidad (el color ocupa rgb y la profundidad toma el canal alfa).Multiple Render Targets no guarda datos

Más tarde uso estas texturas en un sombreador de posprocesamiento para implementar la oclusión ambiental del espacio de pantalla, sin embargo, parece que ninguno de los datos se guarda en el primer sombreador.

Aquí es mi pixel shader:

PS_OUT PS(PS_IN input) 
{ 
    PS_OUT output; 
    output.col = float4(0,0,0,0); 
    output.norm = float4(input.norm,1); 
    output.pos = input.pos; 
    return output; 
} 

que emite la siguiente estructura:

struct PS_OUT 
{ 
    float4 col : SV_TARGET0; 
    float4 norm : SV_TARGET1; 
    float4 pos : SV_TARGET2; 
}; 

y tiene la siguiente estructura para la entrada:

struct PS_IN 
{ 
    float4 pos : SV_POSITION; 
    float2 tex : TEXCOORD0; 
    float3 norm : TEXCOORD1; 
}; 

Sin embargo en mi shader de post-procesamiento:

Texture2D renderTex : register(t1); 
Texture2D normalTex : register(t2); 
Texture2D positionTex : register(t3); 
Texture2D randomTex : register(t4); 
SamplerState samLinear : register(s0); 

float4 PS(PS_IN input) : SV_Target 
{ 
    return float4(getCol(input.tex)); 
} 

Simplemente genera una pantalla azul claro (el color al que reinicié mis objetivos de renderizado al comienzo de cada fotograma). Se ha probado que getCol funciona y devuelve un color del material de renderTex cuando solo se trata de un objetivo de renderizado. Si cambio el pixelshader para que muestre en su lugar la textura de randomTex (que mi código cargó previamente desde un archivo y no es un objetivo de renderizado), todo se procesa correctamente, así que estoy seguro de que no es mi shader posterior al procesamiento.

En caso de que sea mi código SlimDX que está fallando aquí es lo que hago:

Creación de mis texturas, shaderresourvecviews y rendertargetviews:

Texture2DDescription textureDescription = new Texture2DDescription() 
       { 
        Width=texWidth, 
        Height=texHeight, 
        MipLevels=1, 
        ArraySize=3, 
        Format=SlimDX.DXGI.Format.R32G32B32A32_Float, 
        SampleDescription = new SlimDX.DXGI.SampleDescription(1,0), 
        BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource, 
        CpuAccessFlags= CpuAccessFlags.None, 
        OptionFlags = ResourceOptionFlags.None, 
        Usage= ResourceUsage.Default, 
       }; 
      texture = new Texture2D(device, textureDescription); 

      renderTargetView = new RenderTargetView[3]; 
      shaderResourceView = new ShaderResourceView[3]; 

      for (int i = 0; i < 3; i++) 
      { 
       RenderTargetViewDescription renderTargetViewDescription = new RenderTargetViewDescription() 
        { 
         Format = textureDescription.Format, 
         Dimension = RenderTargetViewDimension.Texture2D, 
         MipSlice = 0, 
        }; 

       renderTargetView[i] = new RenderTargetView(device, texture, renderTargetViewDescription); 

       ShaderResourceViewDescription shaderResourceViewDescription = new ShaderResourceViewDescription() 
        { 
         Format = textureDescription.Format, 
         Dimension = ShaderResourceViewDimension.Texture2D, 
         MostDetailedMip = 0, 
         MipLevels = 1 
        }; 

       shaderResourceView[i] = new ShaderResourceView(device, texture, shaderResourceViewDescription); 
      } 

representación a mis múltiples objetivos render:

private void renderToTexture(Shader shader) 
    { 
     //set the vertex and pixel shaders 
     context.VertexShader.Set(shader.VertexShader); 
     context.PixelShader.Set(shader.PixelShader); 

     //send texture data and a linear sampler to the shader 
     context.PixelShader.SetShaderResource(texture, 0); 
     context.PixelShader.SetSampler(samplerState, 0); 

     //set the input assembler 
     SetInputAssembler(shader); 

     //reset the camera's constant buffer 
     camera.ResetConstantBuffer(); 

     //set the render targets to the textures we will render to 
     context.OutputMerger.SetTargets(depthStencilView, renderTargetViews); 
     //clear the render targets and depth stencil 
     foreach (RenderTargetView view in renderTargetViews) 
     { 
      context.ClearRenderTargetView(view, color); 
     } 
     context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0); 
      //draw the scene 
      DrawScene(); 

     } 

y luego la función cuando renderizo mi shader postProcessing a la pantalla:

private void renderTexture(Shader shader) 
     { 
      //get a single quad to be the screen we render 
      Mesh mesh = CreateScreenFace(); 
      //set vertex and pixel shaders 
      context.VertexShader.Set(shader.VertexShader); 
      context.PixelShader.Set(shader.PixelShader); 
      //set the input assembler 
      SetInputAssembler(shader); 
      //point the render target to the screen 
      context.OutputMerger.SetTargets(depthStencil, renderTarget); 
      //send the rendered textures and a linear sampler to the shader 
       context.PixelShader.SetShaderResource(renderTargetViews[0], 1); 
      context.PixelShader.SetShaderResource(renderTargetViews[1], 2); 
      context.PixelShader.SetShaderResource(renderTargetViews[2], 3); 
      context.PixelShader.SetShaderResource(random, 4); 
      context.PixelShader.SetSampler(samplerState, 0); 
      //clear the render targets and depth stencils 
      context.ClearRenderTargetView(renderTarget, new Color4(0.52734375f, 0.8046875f, 0.9765625f)); 
      context.ClearDepthStencilView(depthStencil, DepthStencilClearFlags.Depth, 1, 0); 
      //set the vertex and index buffers from the quad 
      context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(mesh.VertexBuffer, Marshal.SizeOf(typeof(Vertex)), 0)); 
      context.InputAssembler.SetIndexBuffer(mesh.IndexBuffer, Format.R16_UInt, 0); 
      //draw the quad 
      context.DrawIndexed(mesh.indices, 0, 0); 
      //dispose of the buffers 
      mesh.VertexBuffer.Dispose(); 
      mesh.IndexBuffer.Dispose(); 
     } 

EDIT: He añadido la salida de llamada a la función PIX para un solo marco de la ejecución actual:

Frame 40 
//setup 
<0x06BDA1D8> ID3D11DeviceContext::ClearRenderTargetView(0x06B66190, 0x0028F068) 
<0x06BDA1D8> ID3D11DeviceContext::ClearDepthStencilView(0x06B66138, 1, 1.000f, 0) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0028F010, 0x0028EFF8, 0x0028F00C --> 0x06BF8EE0) 
CreateObject(D3D11 Buffer, 0x06BF8EE0) 
<0x06BDA1D8> ID3D11DeviceContext::PSSetConstantBuffers(0, 1, 0x0028F084 --> { 0x06BF8EE0 }) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0F8DEB58, 0x0F8DEB40, 0x0F8DEB54 --> 0x06BF8F68) 
CreateObject(D3D11 Buffer, 0x06BF8F68) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0F70EAD8, 0x0F70EAC0, 0x0F70EAD4 --> 0x06BF8FF0) 
CreateObject(D3D11 Buffer, 0x06BF8FF0) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FAAE9A8, 0x0FAAE990, 0x0FAAE9A4 --> 0x06BF9078) 
CreateObject(D3D11 Buffer, 0x06BF9078) 
<0x0059FF78> ID3D11Device::GetImmediateContext(0x06BDA1D8 --> 0x5BA8A8D8) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0F8DEB58, 0x0F8DEB40, 0x0F8DEB54 --> 0x06BF9100) 
CreateObject(D3D11 Buffer, 0x06BF9100) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0F70EAD8, 0x0F70EAC0, 0x0F70EAD4 --> 0x06BF9188) 
CreateObject(D3D11 Buffer, 0x06BF9188) 
<0x06BDA1D8> ID3D11DeviceContext::Release() 
<0x06BDA1D8> ID3D11DeviceContext::UpdateSubresource(0x06B59270, 0, NULL, 0x06287FA0, 0, 0) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FAAE9A8, 0x0FAAE990, 0x0FAAE9A4 --> 0x06BF9210) 
CreateObject(D3D11 Buffer, 0x06BF9210) 
<0x06BDA1D8> ID3D11DeviceContext::VSSetShader(0x06B66298, NULL, 0) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FC0E978, 0x0FC0E960, 0x0FC0E974 --> 0x06BF9298) 
CreateObject(D3D11 Buffer, 0x06BF9298) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FE8EDE8, 0x0FE8EDD0, 0x0FE8EDE4 --> 0x06BF9320) 
CreateObject(D3D11 Buffer, 0x06BF9320) 
<0x06BDA1D8> ID3D11DeviceContext::PSSetShader(0x06B666F8, NULL, 0) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FC0E978, 0x0FC0E960, 0x0FC0E974 --> 0x06BF93A8) 
CreateObject(D3D11 Buffer, 0x06BF93A8) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0FE8EDE8, 0x0FE8EDD0, 0x0FE8EDE4 --> 0x06BF9430) 
CreateObject(D3D11 Buffer, 0x06BF9430) 
<0x0059FF78> ID3D11Device::CreateInputLayout(0x0028EBE0, 3, 0x06286CB8, 152, 0x0028EBD8 --> 0x06BF9D68) 
CreateObject(D3D11 Input Layout, 0x06BF9D68) 
<0x06BDA1D8> ID3D11DeviceContext::IASetInputLayout(0x06BF9D68) 
<0x06BDA1D8> ID3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) 
<0x0059FF78> ID3D11Device::GetImmediateContext(0x06BDA1D8 --> 0x5BA8A8D8) 
<0x06BDA1D8> ID3D11DeviceContext::Release() 
<0x06BDA1D8> ID3D11DeviceContext::VSSetConstantBuffers(0, 1, 0x0028F024 --> { 0x06B59270 }) 
<0x06BDA1D8> ID3D11DeviceContext::OMSetRenderTargets(3, 0x0028F004 --> { 0x06B65708, 0x06B657B8, 0x06B582E0 }, 0x06B66138) 
<0x06BDA1D8> ID3D11DeviceContext::ClearRenderTargetView(0x06B65708, 0x0028EFEC) 
<0x06BDA1D8> ID3D11DeviceContext::ClearRenderTargetView(0x06B657B8, 0x0028EFEC) 
<0x06BDA1D8> ID3D11DeviceContext::ClearRenderTargetView(0x06B582E0, 0x0028EFEC) 
<0x06BDA1D8> ID3D11DeviceContext::ClearDepthStencilView(0x06B66138, 1, 1.000f, 0) 
//draw scene for preproc shader (this should output the three render targets) 
//DRAW CALLS HIDDEN 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0028EE04, 0x0028EDEC, 0x0028EE00 --> 0x06BF94B8) 
CreateObject(D3D11 Buffer, 0x06BF94B8) 
<0x0059FF78> ID3D11Device::CreateBuffer(0x0028EE04, 0x0028EDEC, 0x0028EE00 --> 0x06BF9540) 
CreateObject(D3D11 Buffer, 0x06BF9540) 
<0x06BDA1D8> ID3D11DeviceContext::VSSetShader(0x06B66BB8, NULL, 0) 
<0x06BDA1D8> ID3D11DeviceContext::PSSetShader(0x06B66E50, NULL, 0) 
<0x0059FF78> ID3D11Device::CreateInputLayout(0x0028EB64, 3, 0x05E988E0, 120, 0x0028EB5C --> 0x06BF9E28) 
CreateObject(D3D11 Input Layout, 0x06BF9E28) 
<0x06BDA1D8> ID3D11DeviceContext::IASetInputLayout(0x06BF9E28) 
<0x06BDA1D8> ID3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) 
<0x06BDA1D8> ID3D11DeviceContext::OMSetRenderTargets(1, 0x0028EFC0 --> { 0x06B66190 }, 0x06B66138) 
<0x06BDA1D8> ID3D11DeviceContext::PSSetShaderResources(1, 3, 0x0028EF3C --> { 0x06B65760, 0x06B58288, 0x06B58338 }) 
<0x06BDA1D8> ID3D11DeviceContext::PSSetShaderResources(4, 1, 0x0028EFC0 --> { 0x06B66FA0 }) 
<0x06BDA1D8> ID3D11DeviceContext::ClearRenderTargetView(0x06B66190, 0x0028EFA4) 
<0x06BDA1D8> ID3D11DeviceContext::ClearDepthStencilView(0x06B66138, 1, 1.000f, 0) 
<0x06BDA1D8> ID3D11DeviceContext::IASetVertexBuffers(0, 1, 0x0028EFAC --> { 0x06BF94B8 }, 0x0028EFB0, 0x0028EFB4) 
<0x06BDA1D8> ID3D11DeviceContext::IASetIndexBuffer(0x06BF9540, DXGI_FORMAT_R16_UINT, 0) 
//draw quad for post proc shader. This shader takes the three textures in, as well as a random texture, which is added in the second PSSetShaderResources call. The random texture outputs fine. 
<0x06BDA1D8> ID3D11DeviceContext::DrawIndexed(6, 0, 0) 
<0x06BF94B8> ID3D11Buffer::Release() 
<0x06BF9540> ID3D11Buffer::Release() 
<0x06B65B00> IDXGISwapChain::Present(0, 0) 

Edit2: He estado leyendo y tal vez Necesito desasignar las texturas como objetivos de renderización después del pase preProc antes de pasarlas como ShaderResourceViews a mi shader postProcess. Supuse que llamar al contexto. OutputMerger.SetTargets() desasignaría todos los objetivos de render asignados actualmente y luego asignaría solo los objetivos de renderización especificados en los parámetros de la función. Si este no es el caso (todavía no estoy seguro de si es o no), ¿cómo voy a desasignar los objetivos de renderizado en SlimDX?

Edit3: Ah, de acuerdo con esta MSDN Page, llamando OutputMerger.SetRenderTargets() "anula toda acotada hacer que los objetivos y el objetivo de profundidad de la plantilla, independientemente del número de objetivos de renderización en ppRenderTargetViews." por lo que todos mis objetivos de renderización se desasignan automáticamente cuando digo al OutputMerger que se muestre en la pantalla. Esto me devuelve a la casilla uno.

Respuesta

1

Se solucionó al descubrir lo tonto que soy.

Cuando creo mi rendertarget creo un Texture2DArray pero lo estoy tratando como una matriz de objetos Texture2D, en lugar de un objeto. Desde entonces he alterado mi código para usar una matriz de objetos Texture2D y funciona muy bien.

Cuestiones relacionadas