Ejemplo n.º 1
0
    public void RenderAllPases(DeviceContext context, Action <RenderingPass> render)
    {
        context.Rasterizer.SetViewport(viewport);

        //One-sided Opaque pass
        standardTarget.SetAsTarget(context);
        oneSidedOpaquePassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.OneSidedOpaque, OutputMode.Standard));

        //One-sided Back-to-Front-Transparency Pass
        backToFrontTransparencyAllFacesPassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.OneSidedBackToFrontTransparent, OutputMode.Standard));

        //One-sided False-Depth Pass
        standardTarget.ClearDepth(context);
        standardTarget.SetAsDepthOnlyTarget(context);
        oneSidedOpaquePassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.OneSidedOpaque, OutputMode.FalseDepth));

        //Two-sided Opaque Pass
        standardTarget.SetAsTarget(context);
        twoSidedOpaquePassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.TwoSidedOpaque, OutputMode.Standard));

        //Two-sided Back-to-Front-Transparency Pass
        backToFrontTransparencyBackFacesPassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.TwoSidedBackToFrontTransparent, OutputMode.Standard));
        backToFrontTransparencyFrontFacesPassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.TwoSidedBackToFrontTransparent, OutputMode.Standard));

        //Switch to oit-blend target
        oitBlendTarget.CopyStandardDepthToBlendDepth(context, standardTarget.DepthResourceView);
        oitBlendTarget.SetAsTarget(context);

        //Unordered Transparency Blend Pass
        unorderedTransparencyPassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.UnorderedTransparent, OutputMode.WeightedBlendedOrderIndependent));

        //Resolve and composite
        standardTarget.SetResolveAsTarget(context);
        oitBlendTarget.Composite(context, standardTarget.RenderSourceView, standardTarget.DepthResourceView);

        postProcessor.PostProcess(context, standardTarget.ResolveSourceView);

        //Render UI
        backToFrontTransparencyAllFacesPassStates.Apply(context);
        render(new RenderingPass(RenderingLayer.UiElements, OutputMode.Standard));
    }
 public void Composite(DeviceContext context, ShaderResourceView multisampleColorSourceView, ShaderResourceView multisampleDepthSourceView)
 {
     compositingStates.Apply(context);
     context.PixelShader.Set(compositingShader);
     context.PixelShader.SetShaderResources(0, AccumResourceView, RevealageSourceView, DepthSourceView, multisampleColorSourceView, multisampleDepthSourceView);
     DrawFullscreenQuad(context);
 }
 public void CopyStandardDepthToBlendDepth(DeviceContext context, ShaderResourceView standardDepth)
 {
     depthCopyingStates.Apply(context);
     context.OutputMerger.SetRenderTargets(DepthTargetView);
     context.PixelShader.Set(depthCopyingShader);
     context.PixelShader.SetShaderResource(0, standardDepth);
     DrawFullscreenQuad(context);
 }
 public void PostProcess(DeviceContext context, ShaderResourceView source)
 {
     postProcessingStates.Apply(context);
     context.OutputMerger.SetTargets(ResultTargetView);
     context.PixelShader.Set(postProcessingShader);
     context.PixelShader.SetShaderResource(0, source);
     context.PixelShader.SetConstantBuffer(0, constantsBuffer.Buffer);
     DrawFullscreenQuad(context);
 }
    private void ProcessTexturedSurface(int surfaceIdx, string uvSetName, FileInfo file, bool isLinear)
    {
        bool isOrderedTransparent = surfaceProperties.RenderOrder.Contains(surfaceIdx);
        bool isMaxing             = isOrderedTransparent;

        var context = device.ImmediateContext;

        var opacityTexture     = LoadOpacityTexture(file, isLinear);
        var opacityTextureView = new ShaderResourceView(device, opacityTexture);

        // Not sure by, possibly a nvidia bug, but the vertex buffer padding by an extra element is necessary.
        // Otherwise (0,0) gets passed to the vertex shader instead of the last vertex.
        var uvSet    = figure.UvSets[uvSetName];
        var vertices = uvSet.Uvs;
        var vertexBufferSizeInBytes = Vector2.SizeInBytes * (vertices.Length + 1);
        var vertexBuffer            = Buffer.Create(device, BindFlags.VertexBuffer, vertices, vertexBufferSizeInBytes);

        List <int> faceIdxMap      = new List <int>();
        List <int> triangleIndices = new List <int>();

        for (int faceIdx = 0; faceIdx < faceCount; ++faceIdx)
        {
            if (figure.Geometry.SurfaceMap[faceIdx] != surfaceIdx)
            {
                continue;
            }

            faceIdxMap.Add(faceIdx);

            Quad face = figure.DefaultUvSet.Faces[faceIdx];
            triangleIndices.Add(face.Index0);
            triangleIndices.Add(face.Index1);
            triangleIndices.Add(face.Index2);

            if (!face.IsDegeneratedIntoTriangle)
            {
                triangleIndices.Add(face.Index2);
                triangleIndices.Add(face.Index3);
                triangleIndices.Add(face.Index0);
            }
        }

        var indexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, triangleIndices.ToArray());

        var transparencyCounterBufferManager = new InOutStructuredBufferManager <TransparencyCounters>(device, faceIdxMap.Count);

        context.ClearState();

        states.Apply(context);

        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
        context.InputAssembler.InputLayout       = inputLayout;
        context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, Vector2.SizeInBytes, 0));
        context.InputAssembler.SetIndexBuffer(indexBuffer, Format.R32_UInt, 0);

        context.VertexShader.Set(vertexShader);

        context.Rasterizer.SetViewport(0, 0, opacityTexture.Description.Width, opacityTexture.Description.Height);

        context.PixelShader.Set(isMaxing ? maxingPixelShader : addingPixelShader);
        context.PixelShader.SetShaderResources(0, opacityTextureView);

        context.OutputMerger.SetUnorderedAccessView(0, transparencyCounterBufferManager.OutView);

        context.DrawIndexed(triangleIndices.Count, 0, 0);

        context.ClearState();

        var transparencyCounterStagingBufferManager = new StagingStructuredBufferManager <TransparencyCounters>(device, faceIdxMap.Count);

        transparencyCounterStagingBufferManager.CopyToStagingBuffer(context, transparencyCounterBufferManager.Buffer);
        var array = transparencyCounterStagingBufferManager.FillArrayFromStagingBuffer(context);

        for (int faceIdx = 0; faceIdx < faceIdxMap.Count; ++faceIdx)
        {
            TransparencyCounters transparencyCounter = array[faceIdx];

            if (transparencyCounter.pixelCount > (1 << 24))
            {
                throw new Exception("pixel count overflow");
            }

            float transparency;
            if (isMaxing)
            {
                transparency = (float)transparencyCounter.transparencyCount / 0xff;
            }
            else
            {
                transparency = transparencyCounter.transparencyCount == 0 ? 0 : (float)transparencyCounter.transparencyCount / transparencyCounter.pixelCount / 0xff;
            }
            faceTransparencies[faceIdxMap[faceIdx]] = transparency;
        }

        opacityTextureView.Dispose();
        opacityTexture.Dispose();
        indexBuffer.Dispose();
        vertexBuffer.Dispose();
        transparencyCounterBufferManager.Dispose();
        transparencyCounterStagingBufferManager.Dispose();
    }