2011-07-31 18 views
5

Tôi đang sử dụng SlimDX, nhắm mục tiêu DirectX 11 bằng mô hình đổ bóng 4. Tôi có trình tạo pixel "preProc" xử lý các đỉnh của mình và lưu ba kết cấu dữ liệu. Một cho các tiêu chuẩn cho mỗi pixel, một cho dữ liệu vị trí trên mỗi pixel và một cho màu sắc và chiều sâu (màu chiếm rgb và chiều sâu lấy kênh alpha).Nhiều mục tiêu Render không lưu dữ liệu

Sau đó tôi sử dụng các họa tiết này trong trình đổ bóng hậu xử lý để triển khai Oc Space Ambient Occlusion, tuy nhiên dường như không có dữ liệu nào được lưu trong trình đổ bóng đầu tiên.

Dưới đây là pixel shader của tôi:

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; 
} 

mà kết quả đầu ra các cấu trúc sau:

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

và lấy struct sau cho đầu vào:

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

Tuy nhiên trong shader xử lý sau của tôi:

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)); 
} 

Nó chỉ đơn giản là kết quả đầu ra một màn hình màu xanh nhạt (màu tôi đặt lại mục tiêu hiển thị của tôi ở đầu mỗi khung hình). getCol đã được thử nghiệm để làm việc và trả về một màu từ tài liệu renderTex khi chỉ xử lý một mục tiêu render. Nếu tôi thay đổi pixelshader để thay vào đó lấy mẫu kết quả randomTex (mã của tôi trước đó được nạp từ một tệp và không phải là mục tiêu hiển thị), mọi thứ sẽ được hiển thị tốt, vì vậy tôi tin tưởng nó không phải là trình xử lý bài đăng của tôi.

Trong trường hợp nó là mã SlimDX của tôi đó là thất bại ở đây là những gì tôi làm:

Tạo kết cấu của tôi, shaderresourvecviews và 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); 
      } 

Rendering đến nhiều mục tiêu làm cho tôi:

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(); 

     } 

và sau đó là chức năng khi tôi hiển thị trình đổ bóng sau khi xử lý lên màn hình:

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: Tôi đã thêm PIX lượng chức năng cuộc gọi cho một khung duy nhất của chạy hiện tại:

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: Tôi đã làm một số việc đọc và có lẽ tôi cần phải deallocate các kết cấu như render mục tiêu sau khi vượt qua preProc trước khi tôi vượt qua chúng trong như ShaderResourceViews để postProcess shader của tôi. Tôi giả định gọi context.OutputMerger.SetTargets() sẽ deallocate tất cả các mục tiêu render hiện đang được gán và sau đó chỉ gán các đích render được chỉ định trong các tham số của hàm. Nếu đây không phải là trường hợp (tôi chưa thể chắc chắn nếu nó là hay không), sau đó làm thế nào tôi sẽ đi về unassigning các mục tiêu render trong SlimDX?

EDIT3: Ah, theo điều này MSDN Page, gọi OutputMerger.SetRenderTargets() "ghi đè tất cả các mục tiêu kết xuất được giới hạn và mục tiêu stencil sâu bất kể số mục tiêu hiển thị trong ppRenderTargetViews." vì vậy tất cả các mục tiêu hiển thị của tôi sẽ tự động được deallocated khi tôi yêu cầu OutputMerger hiển thị trên màn hình. Điều này khiến tôi trở lại hình vuông.

Trả lời

1

Khắc phục sự cố bằng cách khám phá ra tôi thật ngốc nghếch.

Khi tôi tạo mục tiêu hiển thị của mình, tôi tạo Texture2DArray nhưng tôi xử lý nó như một mảng đối tượng Texture2D, thay vì một đối tượng. Tôi đã thay đổi mã của mình để sử dụng một mảng các đối tượng Texture2D và nó hoạt động rất tốt.

Các vấn đề liên quan