如何在纹理中写入深度并在DirectX11中的着色器上的下一次传递中读取它?

时间:2013-11-19 15:21:30

标签: graphics directx shader directx-11 sharpdx

我在DirectX 11(SharpDX)中编写了两遍效果。它应该在第一遍中将纹理深度写入纹理,然后使用该纹理在像素着色器中的第二个上提取数据。

我得到的是一个白色的屏幕,只有界面,我不知道为什么没有打印。可能是什么问题呢?我会说我应该从深度纹理中获得至少一些东西。是否有更简单的方法来获得我的目标?

有关我正在做的事情的信息:

这就是我设置深度纹理值的方法:

this.depthBuffer = new Texture2D(device, new Texture2DDescription()
        {
            Format = Format.R32_Typeless,
            ArraySize = 1,
            MipLevels = 1,
            Width = (int)host.ActualWidth,
            Height = (int)host.ActualHeight,
            SampleDescription = new SampleDescription(1, 0),
            Usage = ResourceUsage.Default,
            BindFlags = BindFlags.DepthStencil | BindFlags.ShaderResource,
            CpuAccessFlags = CpuAccessFlags.None,
            OptionFlags = ResourceOptionFlags.None,
        });

this.depthBufferShaderResourceView = new ShaderResourceView(this.device, this.depthBuffer, new ShaderResourceViewDescription()
        {
            Format = Format.R32_Float,
            Dimension = ShaderResourceViewDimension.Texture2D,
            Texture2D = new ShaderResourceViewDescription.Texture2DResource()
            {
                MipLevels = 1,
                MostDetailedMip = 0,
            }
        });
var depthStencilDesc = new DepthStencilStateDescription()
        {
            DepthComparison = Comparison.LessEqual,
            DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
            IsDepthEnabled = true,
        };

以下是我在.fx文件中采样深度的方法:

int3 posTex = int3(input.p.xy, 0);
float depthPixel = DepthTexture.Load(posTex);
float4 color = float4(depthPixel, depthPixel , depthPixel, 1.0f );
return color;

这就是我现在将Depth Buffer模板视图设置为2次传递中的渲染目标的方式。在第一次尝试将depthstencilview设置为目标。在第二遍中,我试图将深度纹理设置为着色器资源以从中读取。

this.device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(this.vertexBuffer, LinesVertex.SizeInBytes, 0));

// PASS 0
this.device.ImmediateContext.OutputMerger.SetTargets(depthBufferStencilView);
this.device.ImmediateContext.ClearDepthStencilView(this.depthBufferStencilView,     DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
this.technique.GetPassByIndex(0).Apply(this.device.ImmediateContext);
this.device.ImmediateContext.DrawIndexed(this.geometry.Indices.Length, 0, 0);

// PASS 1
this.device.ImmediateContext.OutputMerger.ResetTargets(); // unbinding the depthStencilView

this.device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(this.vertexBuffer, LinesVertex.SizeInBytes, 0));
this.depthStencilShaderResourceVariable = effect.GetVariableByName("DepthTexture").AsShaderResource();
this.depthStencilShaderResourceVariable.SetResource(this.depthBufferShaderResourceView);
this.technique.GetPassByIndex(1).Apply(this.device.ImmediateContext);
this.device.ImmediateContext.DrawIndexed(this.geometry.Indices.Length, 0, 0);

最后,这就是我在.fx文件中设置两个传递的方式:

technique11 RenderMyTechnique
{
pass P0
{   

SetDepthStencilState( DSSDepthLessEqual, 0 );
SetVertexShader     ( CompileShader( vs_4_0, VShader() ) );
    SetHullShader       ( NULL );
    SetDomainShader     ( NULL );        
    SetGeometryShader   ( NULL  );
SetPixelShader      ( NULL );
}

pass P1
{
SetDepthStencilState( DSSDepthLessEqual, 0 );
SetVertexShader     ( CompileShader( vs_4_0, VShader() ) );
    SetHullShader       ( NULL );
    SetDomainShader     ( NULL );        
    SetGeometryShader   ( CompileShader( gs_4_0, GShader() ) );
SetPixelShader      ( CompileShader( ps_4_0, PShader() ) );
}
}

1 个答案:

答案 0 :(得分:1)

致电时:

this.device.ImmediateContext.OutputMerger.ResetTargets();

之后你直接执行你的绘制,你没有绑定任何渲染目标,所以你需要调用:

this.device.ImmediateContext.OutputMerger.SetTargets(renderView);

renderview是任何rendertarget视图(可以是你的交换链)。目前你做了一个平局,但没有“没有”。

第二个潜在的问题,你重绘相同的模型,但没有深度模板,因此结果可能会有所不同(特别是因为在一个版本中你使用的是几何着色器,而不是在另一个版本中)。因此,您之前传递的深度数据可能根本无效。