Beispiel #1
0
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            #region Initialize textures
            if (renderTargetFull == null ||
                renderTargetDesc.Width != (int)(context.ActualWidth) ||
                renderTargetDesc.Height != (int)(context.ActualHeight))
            {
                depthdesc.Width  = renderTargetDesc.Width = (int)(context.ActualWidth);
                depthdesc.Height = renderTargetDesc.Height = (int)(context.ActualHeight);

                RemoveAndDispose(ref renderTargetFull);
                RemoveAndDispose(ref depthStencilBuffer);

                renderTargetFull = Collect(new ShaderResourceViewProxy(deviceContext.DeviceContext.Device, renderTargetDesc));
                renderTargetFull.CreateView(renderTargetViewDesc);
                renderTargetFull.CreateView(targetResourceViewDesc);
                depthStencilBuffer = Collect(new ShaderResourceViewProxy(deviceContext.DeviceContext.Device, depthdesc));
                depthStencilBuffer.CreateView(depthStencilViewDesc);

                blurCore.Resize(deviceContext.DeviceContext.Device,
                                renderTargetDesc.Width / downSamplingScale,
                                renderTargetDesc.Height / downSamplingScale);
                //Skip this frame to avoid performance hit due to texture creation
                InvalidateRenderer();
                return;
            }
            #endregion

            #region Render objects onto offscreen texture
            deviceContext.DeviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 0, 0);
            BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, renderTargetDesc.Width, renderTargetDesc.Height);

            context.IsCustomPass = true;
            bool hasMesh = false;
            for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i)
            {
                IEffectAttributes effect;
                var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i];
                if (mesh.TryGetPostEffect(EffectName, out effect))
                {
                    object attribute;
                    var    color = Color;
                    if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out attribute) && attribute is string colorStr)
                    {
                        color = colorStr.ToColor4();
                    }
                    if (modelStruct.Color != color)
                    {
                        modelStruct.Color = color;
                        OnUploadPerModelConstantBuffers(deviceContext);
                    }
                    context.CustomPassName = DefaultPassNames.EffectOutlineP1;
                    var pass = mesh.EffectTechnique[DefaultPassNames.EffectOutlineP1];
                    if (pass.IsNULL)
                    {
                        continue;
                    }
                    pass.BindShader(deviceContext);
                    pass.BindStates(deviceContext, StateType.BlendState);
                    deviceContext.SetDepthStencilState(pass.DepthStencilState, 1);
                    mesh.Render(context, deviceContext);
                    hasMesh = true;
                }
            }
            context.IsCustomPass = false;
            #endregion
            if (hasMesh)
            {
                deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
                deviceContext.DeviceContext.PixelShader.SetSampler(samplerSlot, sampler);
                #region Do Blur Pass
                BindTarget(null, blurCore.CurrentRTV, deviceContext, blurCore.Width, blurCore.Height, true);
                blurPassVertical.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, renderTargetFull);
                blurPassVertical.BindShader(deviceContext);
                blurPassVertical.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                deviceContext.DeviceContext.Draw(4, 0);

                blurCore.Run(deviceContext, NumberOfBlurPass, 1, 0);//Already blur once on vertical, pass 1 as initial index.
                #endregion

                #region Draw back with stencil test
                BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, renderTargetDesc.Width, renderTargetDesc.Height);
                screenQuadPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, blurCore.CurrentSRV);
                screenQuadPass.BindShader(deviceContext);
                deviceContext.SetDepthStencilState(screenQuadPass.DepthStencilState, 0);
                screenQuadPass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState);
                deviceContext.DeviceContext.Draw(4, 0);
                #endregion

                #region Draw outline onto original target
                context.RenderHost.SetDefaultRenderTargets(false);
                screenOutlinePass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, renderTargetFull);
                screenOutlinePass.BindShader(deviceContext);
                screenOutlinePass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                deviceContext.DeviceContext.Draw(4, 0);
                screenOutlinePass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, null);
                #endregion
            }
            else
            {
                context.RenderHost.SetDefaultRenderTargets(false);
            }
        }
Beispiel #2
0
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            #region Initialize textures
            var buffer = context.RenderHost.RenderBuffer;
            if (depthdesc.Width != buffer.TargetWidth ||
                depthdesc.Height != buffer.TargetHeight)
            {
                depthdesc.Width  = buffer.TargetWidth;
                depthdesc.Height = buffer.TargetHeight;

                blurCore.Resize(deviceContext,
                                depthdesc.Width / downSamplingScale,
                                depthdesc.Height / downSamplingScale);
                //Skip this frame to avoid performance hit due to texture creation
                InvalidateRenderer();
                return;
            }
            #endregion

            var depthStencilBuffer = buffer.FullResDepthStencilPool.Get(depthdesc.Format);

            #region Render objects onto offscreen texture
            var renderTargetFull = buffer.FullResPPBuffer.NextRTV;

            deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 0, 0);
            BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, buffer.TargetWidth, buffer.TargetHeight);
            var frustum = context.BoundingFrustum;
            context.IsCustomPass = true;
            bool hasMesh = false;
            for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i)
            {
                var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i];
                if (context.EnableBoundingFrustum && !mesh.TestViewFrustum(ref frustum))
                {
                    continue;
                }
                if (mesh.TryGetPostEffect(EffectName, out IEffectAttributes effect))
                {
                    object attribute;
                    var    color = Color;
                    if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out attribute) && attribute is string colorStr)
                    {
                        color = colorStr.ToColor4();
                    }
                    if (modelStruct.Color != color)
                    {
                        modelStruct.Color = color;
                        OnUploadPerModelConstantBuffers(deviceContext);
                    }
                    context.CustomPassName = DefaultPassNames.EffectOutlineP1;
                    var pass = mesh.EffectTechnique[DefaultPassNames.EffectOutlineP1];
                    if (pass.IsNULL)
                    {
                        continue;
                    }
                    pass.BindShader(deviceContext);
                    pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState);
                    mesh.Render(context, deviceContext);
                    hasMesh = true;
                }
            }
            context.IsCustomPass = false;
            #endregion
            if (hasMesh)
            {
                #region Do Blur Pass
                BindTarget(null, blurCore.CurrentRTV, deviceContext, blurCore.Width, blurCore.Height, true);
                blurPassVertical.PixelShader.BindSampler(deviceContext, samplerSlot, sampler);
                blurPassVertical.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.NextSRV);
                blurPassVertical.BindShader(deviceContext);
                blurPassVertical.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                deviceContext.Draw(4, 0);

                blurCore.Run(deviceContext, NumberOfBlurPass, 1, 0);//Already blur once on vertical, pass 1 as initial index.
                #endregion

                #region Draw back with stencil test
                BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, buffer.TargetWidth, buffer.TargetHeight);
                screenQuadPass.PixelShader.BindTexture(deviceContext, textureSlot, blurCore.CurrentSRV);
                screenQuadPass.BindShader(deviceContext);
                screenQuadPass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                deviceContext.Draw(4, 0);
                #endregion

                #region Draw outline onto original target
                BindTarget(null, buffer.FullResPPBuffer.CurrentRTV, deviceContext, buffer.TargetWidth, buffer.TargetHeight, false);
                screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.NextSRV);
                screenOutlinePass.BindShader(deviceContext);
                screenOutlinePass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                deviceContext.Draw(4, 0);
                screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, null);
                #endregion
            }
            buffer.FullResDepthStencilPool.Put(depthdesc.Format, depthStencilBuffer);
        }
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            #region Initialize textures
            var buffer = context.RenderHost.RenderBuffer;
            if (depthdesc.Width != buffer.TargetWidth ||
                depthdesc.Height != buffer.TargetHeight)
            {
                depthdesc.Width  = buffer.TargetWidth;
                depthdesc.Height = buffer.TargetHeight;

                blurCore.Resize(deviceContext,
                                depthdesc.Width / downSamplingScale,
                                depthdesc.Height / downSamplingScale);
                //Skip this frame to avoid performance hit due to texture creation
                InvalidateRenderer();
                return;
            }
            #endregion

            var depthStencilBuffer = buffer.FullResDepthStencilPool.Get(depthdesc.Format);
            var renderTargetFull   = buffer.FullResPPBuffer.NextRTV;

            var frustum = context.BoundingFrustum;
            if (drawMode == OutlineMode.Separated)
            {
                for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i)
                {
                    #region Render objects onto offscreen texture
                    var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i];
                    if (context.EnableBoundingFrustum && !mesh.TestViewFrustum(ref frustum))
                    {
                        continue;
                    }
                    BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, buffer.TargetWidth, buffer.TargetHeight);
                    deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 0, 0);
                    modelCB.Upload(deviceContext, ref modelStruct);
                    if (mesh.TryGetPostEffect(EffectName, out IEffectAttributes effect))
                    {
                        var color = Color;
                        if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out object attribute) && attribute is string colorStr)
                        {
                            color = colorStr.ToColor4();
                        }
                        if (modelStruct.Color != color)
                        {
                            modelStruct.Color = color;
                            modelCB.Upload(deviceContext, ref modelStruct);
                        }
                        context.CustomPassName = DefaultPassNames.EffectOutlineP1;
                        var pass = mesh.EffectTechnique[DefaultPassNames.EffectOutlineP1];
                        if (pass.IsNULL)
                        {
                            continue;
                        }
                        pass.BindShader(deviceContext);
                        pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState);
                        mesh.RenderCustom(context, deviceContext);
                        DrawOutline(context, deviceContext, depthStencilBuffer, renderTargetFull);
                    }
                    #endregion
                }
            }
            else
            {
                BindTarget(depthStencilBuffer, renderTargetFull, deviceContext, buffer.TargetWidth, buffer.TargetHeight);
                #region Render objects onto offscreen texture
                deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 0, 0);
                bool hasMesh = false;
                for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i)
                {
                    var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i];
                    if (context.EnableBoundingFrustum && !mesh.TestViewFrustum(ref frustum))
                    {
                        continue;
                    }
                    if (mesh.TryGetPostEffect(EffectName, out IEffectAttributes effect))
                    {
                        var color = Color;
                        if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out object attribute) && attribute is string colorStr)
                        {
                            color = colorStr.ToColor4();
                        }
                        if (modelStruct.Color != color)
                        {
                            modelStruct.Color = color;
                            modelCB.Upload(deviceContext, ref modelStruct);
                        }
                        context.CustomPassName = DefaultPassNames.EffectOutlineP1;
                        var pass = mesh.EffectTechnique[DefaultPassNames.EffectOutlineP1];
                        if (pass.IsNULL)
                        {
                            continue;
                        }
                        pass.BindShader(deviceContext);
                        pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState);
                        mesh.RenderCustom(context, deviceContext);
                        hasMesh = true;
                    }
                }
                #endregion
                if (hasMesh)
                {
                    DrawOutline(context, deviceContext, depthStencilBuffer, renderTargetFull);
                }
            }
            buffer.FullResDepthStencilPool.Put(depthdesc.Format, depthStencilBuffer);
        }