Example #1
0
        /// <summary>
        /// Called when [attach].
        /// </summary>
        /// <param name="technique">The technique.</param>
        /// <returns></returns>
        protected override bool OnAttach(IRenderTechnique technique)
        {
            if (base.OnAttach(technique))
            {
                VertexLayout = technique.Layout;
                updatePass   = technique[DefaultParticlePassNames.Update];
                insertPass   = technique[DefaultParticlePassNames.Insert];
                renderPass   = technique[DefaultParticlePassNames.Default];
                #region Get binding slots
                currentStateSlot = updatePass.GetShader(ShaderStage.Compute).UnorderedAccessViewMapping.TryGetBindSlot(CurrentSimStateUAVBufferName);
                newStateSlot     = updatePass.GetShader(ShaderStage.Compute).UnorderedAccessViewMapping.TryGetBindSlot(NewSimStateUAVBufferName);

                renderStateSlot = renderPass.GetShader(ShaderStage.Vertex).ShaderResourceViewMapping.TryGetBindSlot(SimStateBufferName);
                textureSlot     = renderPass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(ShaderTextureBufferName);
                samplerSlot     = renderPass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(ShaderTextureSamplerName);
                #endregion
                perFrameCB = technique.ConstantBufferPool.Register(DefaultBufferNames.ParticleFrameCB, ParticlePerFrame.SizeInBytes);
                insertCB   = technique.ConstantBufferPool.Register(DefaultBufferNames.ParticleCreateParameters, ParticleInsertParameters.SizeInBytes);
                if (isInitialParticleChanged)
                {
                    OnInitialParticleChanged(ParticleCount);
                }
                textureSampler = Collect(technique.EffectsManager.StateManager.Register(SamplerDescription));
                OnTextureChanged();
                OnBlendStateChanged();
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #2
0
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            RenderCount = 0;
            if (CreateTextureResources(context, deviceContext))
            {
                InvalidateRenderer();
                return; // Skip this frame if texture resized to reduce latency.
            }
            Bind(context, deviceContext);
            var frustum = context.BoundingFrustum;
            int count   = context.RenderHost.PerFrameTransparentNodes.Count;

            context.IsOITPass = true;
            for (int i = 0; i < count; ++i)
            {
                var renderable = context.RenderHost.PerFrameTransparentNodes[i];
                if (context.EnableBoundingFrustum && !renderable.TestViewFrustum(ref frustum))
                {
                    continue;
                }
                renderable.RenderCore.Render(context, deviceContext);
                ++RenderCount;
            }
            context.IsOITPass = false;
            UnBind(context, deviceContext);
            screenQuadPass.BindShader(deviceContext);
            screenQuadPass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState | StateType.RasterState);
            screenQuadPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, colorTexIndex, colorTargetNoMSAA);
            screenQuadPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, alphaTexIndex, alphaTargetNoMSAA);
            screenQuadPass.GetShader(ShaderStage.Pixel).BindSampler(deviceContext, samplerIndex, targetSampler);
            deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
            deviceContext.DeviceContext.Draw(4, 0);
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="deviceContext"></param>
        protected override void OnUpdate(RenderContext context, DeviceContextProxy deviceContext)
        {
            UpdateTime(context, ref totalElapsed);
            //Set correct instance count from instance buffer
            drawArgument.InstanceCount = InstanceBuffer == null || !InstanceBuffer.HasElements ? 1 : (uint)InstanceBuffer.Buffer.ElementCount;
            //Upload the draw argument
            particleCountGSIABuffer.UploadDataToBuffer(deviceContext, ref drawArgument);

            updatePass.BindShader(deviceContext);
            updatePass.GetShader(ShaderStage.Compute).BindUAV(deviceContext, currentStateSlot, BufferProxies[0].UAV);
            updatePass.GetShader(ShaderStage.Compute).BindUAV(deviceContext, newStateSlot, BufferProxies[1].UAV);

            if (isRestart)
            {
                FrameVariables.NumParticles = 0;
                perFrameCB.UploadDataToBuffer(deviceContext, ref FrameVariables);
                // Call ComputeShader to add initial particles
                deviceContext.DeviceContext.Dispatch(1, 1, 1);
                isRestart = false;
            }
            else
            {
                #region Get consume buffer count
                // Get consume buffer count.
                //Due to some intel integrated graphic card having issue copy structure count directly into constant buffer.
                //Has to use staging buffer to read and pass into constant buffer
                FrameVariables.NumParticles = (uint)ReadCount("", deviceContext, BufferProxies[0]);
                perFrameCB.UploadDataToBuffer(deviceContext, ref FrameVariables);
                #endregion

                deviceContext.DeviceContext.Dispatch(Math.Max(1, (int)Math.Ceiling((double)FrameVariables.NumParticles / 512)), 1, 1);
                // Get append buffer count
                BufferProxies[1].CopyCount(deviceContext, particleCountGSIABuffer.Buffer, 0);
            }

#if OUTPUTDEBUGGING
            ReadCount("UAV 0", deviceContext, BufferProxies[0].UAV);
#endif


            if (totalElapsed > InsertElapseThrottle)
            {
                insertCB.UploadDataToBuffer(deviceContext, ref InsertVariables);
                // Add more particles
                insertPass.BindShader(deviceContext);
                insertPass.GetShader(ShaderStage.Compute).BindUAV(deviceContext, newStateSlot, BufferProxies[1].UAV);
                deviceContext.DeviceContext.Dispatch(1, 1, 1);
                totalElapsed = 0;
#if OUTPUTDEBUGGING
                ReadCount("UAV 1", deviceContext, BufferProxies[1].UAV);
#endif
            }

            // Swap UAV buffers for next frame
            var bproxy = BufferProxies[0];
            BufferProxies[0] = BufferProxies[1];
            BufferProxies[1] = bproxy;
        }
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            var buffer = context.RenderHost.RenderBuffer;

            buffer.SetDefaultRenderTargets(deviceContext, false);
            FXAAPass.BindShader(deviceContext);
            FXAAPass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState | StateType.RasterState);
            FXAAPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, buffer.ColorBuffer);
            FXAAPass.GetShader(ShaderStage.Pixel).BindSampler(deviceContext, samplerSlot, sampler);
            deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
            deviceContext.DeviceContext.Draw(4, 0);
            FXAAPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, null);
        }
 protected override bool OnAttach(IRenderTechnique technique)
 {
     if (base.OnAttach(technique))
     {
         FXAAPass    = technique[DefaultPassNames.Default];
         textureSlot = FXAAPass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(DefaultBufferNames.DiffuseMapTB);
         samplerSlot = FXAAPass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(DefaultSamplerStateNames.DiffuseMapSampler);
         sampler     = Collect(technique.EffectsManager.StateManager.Register(DefaultSamplers.LinearSamplerClampAni1));
         return(true);
     }
     else
     {
         return(false);
     }
 }
 /// <summary>
 /// <see cref="IEffectMaterialVariables.BindMaterialTextures(DeviceContext, ShaderPass)"/>
 /// </summary>
 /// <param name="context"></param>
 /// <param name="shaderPass"></param>
 /// <returns></returns>
 public bool BindMaterialTextures(DeviceContext context, ShaderPass shaderPass)
 {
     if (material == null)
     {
         return(false);
     }
     UpdateMappings(shaderPass);
     if (HasTextures)
     {
         for (int i = 0; i < shaderPass.Shaders.Count; ++i)
         {
             var shader = shaderPass.Shaders[i];
             if (shader.IsNULL || !EnumHelper.HasFlag(Constants.CanBindTextureStages, shader.ShaderType))
             {
                 continue;
             }
             OnBindMaterialTextures(context, shader);
         }
     }
     if (RenderShadowMap)
     {
         shaderPass.GetShader(ShaderStage.Pixel).BindSampler(context, SamplerBindingMap[ShaderStage.Pixel.ToIndex()][NUMSAMPLERS - 1], SamplerResources[NUMSAMPLERS - 1]);
     }
     return(true);
 }
Example #7
0
 /// <summary>
 /// Called when [attach].
 /// </summary>
 /// <param name="technique">The technique.</param>
 /// <returns></returns>
 protected override bool OnAttach(IRenderTechnique technique)
 {
     if (base.OnAttach(technique))
     {
         DefaultShaderPass = technique.EffectsManager[DefaultRenderTechniqueNames.ScreenDuplication][DefaultPassNames.Default];
         CursorShaderPass  = technique.EffectsManager[DefaultRenderTechniqueNames.ScreenDuplication][DefaultPassNames.ScreenQuad];
         textureBindSlot   = DefaultShaderPass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(DefaultBufferNames.DiffuseMapTB);
         samplerBindSlot   = DefaultShaderPass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(DefaultSamplerStateNames.DiffuseMapSampler);
         textureSampler    = Collect(technique.EffectsManager.StateManager.Register(DefaultSamplers.ScreenDupSampler));
         return(Initialize(technique.EffectsManager));
     }
     else
     {
         return(false);
     }
 }
        /// <summary>
        /// Runs the specified device context.
        /// </summary>
        /// <param name="deviceContext">The device context.</param>
        /// <param name="iteration">The iteration.</param>
        /// <param name="initVerticalIter">The initialize vertical iter.</param>
        /// <param name="initHorizontalIter">The initialize horizontal iter.</param>
        public virtual void Run(DeviceContextProxy deviceContext, int iteration, int initVerticalIter = 0, int initHorizontalIter = 0)
        {
            deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
            deviceContext.DeviceContext.PixelShader.SetSampler(samplerSlot, sampler);
            if (!screenBlurPassVertical.IsNULL)
            {
                screenBlurPassVertical.BindShader(deviceContext);
                screenBlurPassVertical.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                for (int i = initVerticalIter; i < iteration; ++i)
                {
                    SwapTargets();
                    BindTarget(null, renderTargetBlur[0], deviceContext, texture2DDesc.Width, texture2DDesc.Height);
                    screenBlurPassVertical.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, renderTargetBlur[1].TextureView);
                    deviceContext.DeviceContext.Draw(4, 0);
                }
            }

            if (!screenBlurPassHorizontal.IsNULL)
            {
                screenBlurPassHorizontal.BindShader(deviceContext);
                screenBlurPassHorizontal.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                for (int i = initHorizontalIter; i < iteration; ++i)
                {
                    SwapTargets();
                    BindTarget(null, renderTargetBlur[0], deviceContext, texture2DDesc.Width, texture2DDesc.Height);
                    screenBlurPassHorizontal.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, renderTargetBlur[1].TextureView);
                    deviceContext.DeviceContext.Draw(4, 0);
                }
            }
            deviceContext.DeviceContext.PixelShader.SetShaderResource(textureSlot, null);
        }
Example #9
0
 protected override bool OnAttach(IRenderTechnique technique)
 {
     if (base.OnAttach(technique))
     {
         screenQuadPass = technique[DefaultPassNames.Default];
         colorTexIndex  = screenQuadPass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(DefaultBufferNames.OITColorTB);
         alphaTexIndex  = screenQuadPass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(DefaultBufferNames.OITAlphaTB);
         samplerIndex   = screenQuadPass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(DefaultSamplerStateNames.DiffuseMapSampler);
         targetSampler  = Collect(technique.EffectsManager.StateManager.Register(DefaultSamplers.LinearSamplerWrapAni2));
         RenderCount    = 0;
         return(true);
     }
     else
     {
         return(false);
     }
 }
 protected override bool OnAttach(IRenderTechnique technique)
 {
     if (base.OnAttach(technique))
     {
         screenQuadPass     = technique.GetPass(DefaultPassNames.ScreenQuad);
         screenQuadCopy     = technique.GetPass(DefaultPassNames.ScreenQuadCopy);
         blurPassVertical   = technique.GetPass(DefaultPassNames.EffectBlurVertical);
         blurPassHorizontal = technique.GetPass(DefaultPassNames.EffectBlurHorizontal);
         screenOutlinePass  = technique.GetPass(DefaultPassNames.MeshOutline);
         textureSlot        = screenOutlinePass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(DefaultBufferNames.DiffuseMapTB);
         samplerSlot        = screenOutlinePass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(DefaultSamplerStateNames.DiffuseMapSampler);
         sampler            = Collect(technique.EffectsManager.StateManager.Register(DefaultSamplers.LinearSamplerClampAni4));
         return(true);
     }
     else
     {
         return(false);
     }
 }
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            ShaderPass pass = DefaultShaderPass;

            if (RenderType == RenderType.Transparent && context.IsOITPass)
            {
                pass = TransparentPass;
            }
            pass.BindShader(deviceContext);
            pass.BindStates(deviceContext, DefaultStateBinding);
            BindBillboardTexture(deviceContext, pass.GetShader(ShaderStage.Pixel));
            OnDraw(deviceContext, InstanceBuffer);
        }
Example #12
0
        /// <summary>
        /// Called when [render].
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="deviceContext">The device context.</param>
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            perFrameCB.UploadDataToBuffer(deviceContext, ref FrameVariables);
            // Clear binding
            updatePass.GetShader(ShaderStage.Compute).BindUAV(deviceContext, currentStateSlot, null);
            updatePass.GetShader(ShaderStage.Compute).BindUAV(deviceContext, newStateSlot, null);

            // Render existing particles
            renderPass.BindShader(deviceContext);
            renderPass.BindStates(deviceContext, StateType.RasterState | StateType.DepthStencilState);

            renderPass.GetShader(ShaderStage.Vertex).BindTexture(deviceContext, renderStateSlot, BufferProxies[0].SRV);
            renderPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, textureView);
            renderPass.GetShader(ShaderStage.Pixel).BindSampler(deviceContext, samplerSlot, textureSampler);
            deviceContext.DeviceContext.InputAssembler.InputLayout       = VertexLayout;
            deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.PointList;
            int firstSlot = 0;

            InstanceBuffer?.AttachBuffer(deviceContext, ref firstSlot);
            deviceContext.DeviceContext.OutputMerger.SetBlendState(blendState, null, 0xFFFFFFFF);
            deviceContext.DeviceContext.DrawInstancedIndirect(particleCountGSIABuffer.Buffer, 0);
            InvalidateRenderer();//Since particle is running all the time. Invalidate once finished rendering
        }
Example #13
0
            /// <summary>
            /// Called when [attach].
            /// </summary>
            /// <param name="technique">The technique.</param>
            /// <returns></returns>
            protected override bool OnAttach(IRenderTechnique technique)
            {
                VertexLayout = technique.Layout;
                updatePass   = technique[DefaultParticlePassNames.Update];
                insertPass   = technique[DefaultParticlePassNames.Insert];
                renderPass   = technique[DefaultParticlePassNames.Default];
                #region Get binding slots
                currentStateSlot = updatePass.GetShader(ShaderStage.Compute).UnorderedAccessViewMapping.TryGetBindSlot(CurrentSimStateUAVBufferName);
                newStateSlot     = updatePass.GetShader(ShaderStage.Compute).UnorderedAccessViewMapping.TryGetBindSlot(NewSimStateUAVBufferName);

                renderStateSlot = renderPass.GetShader(ShaderStage.Vertex).ShaderResourceViewMapping.TryGetBindSlot(SimStateBufferName);
                textureSlot     = renderPass.PixelShader.ShaderResourceViewMapping.TryGetBindSlot(ShaderTextureBufferName);
                samplerSlot     = renderPass.PixelShader.SamplerMapping.TryGetBindSlot(ShaderTextureSamplerName);
                #endregion
                if (isInitialParticleChanged)
                {
                    OnInitialParticleChanged(ParticleCount);
                }
                textureSampler = technique.EffectsManager.StateManager.Register(SamplerDescription);
                OnTextureChanged();
                OnBlendStateChanged();
                return(true);
            }
Example #14
0
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            ShaderPass pass = DefaultShaderPass;

            if (RenderType == RenderType.Transparent && context.IsOITPass)
            {
                pass = TransparentPass;
            }
            pass.BindShader(deviceContext);
            pass.BindStates(deviceContext, DefaultStateBinding);
            if (!BindMaterialTextures(deviceContext, pass))
            {
                return;
            }
            if (context.RenderHost.IsShadowMapEnabled)
            {
                pass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, shadowMapSlot, context.SharedResource.ShadowView);
            }
            DynamicReflector?.BindCubeMap(deviceContext);
            OnDraw(deviceContext, InstanceBuffer);
            DynamicReflector?.UnBindCubeMap(deviceContext);
            if (RenderWireframe && WireframePass != ShaderPass.NullPass)
            {
                if (RenderType == RenderType.Transparent && context.IsOITPass)
                {
                    pass = WireframeOITPass;
                }
                else
                {
                    pass = WireframePass;
                }
                pass.BindShader(deviceContext, false);
                pass.BindStates(deviceContext, DefaultStateBinding);
                deviceContext.SetRasterState(RasterStateWireframe);
                OnDraw(deviceContext, InstanceBuffer);
            }
        }
Example #15
0
 protected override void OnDefaultPassChanged(ShaderPass pass)
 {
     base.OnDefaultPassChanged(pass);
     ColorTextureSlot        = pass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(CustomShaderNames.TexData);
     ColorTextureSamplerSlot = pass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(CustomShaderNames.TexDataSampler);
 }
Example #16
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);
            }
        }
        protected override void OnRender(RenderContext context, DeviceContextProxy deviceContext)
        {
            #region Initialize textures
            if (offScreenRenderTargets.Count == 0 ||
                width != (int)(context.ActualWidth) ||
                height != (int)(context.ActualHeight))
            {
                width  = (int)(context.ActualWidth);
                height = (int)(context.ActualHeight);
                for (int i = 0; i < offScreenRenderTargets.Count; ++i)
                {
                    var target = offScreenRenderTargets[i];
                    RemoveAndDispose(ref target);
                }
                offScreenRenderTargets.Clear();

                int w     = width;
                int h     = height;
                int count = 0;
                while (w > 1 && h > 1 && count < Math.Max(0, MaximumDownSamplingStep) + 1)
                {
                    var target = Collect(new PostEffectBlurCore(global::SharpDX.DXGI.Format.B8G8R8A8_UNorm, blurPassVertical, blurPassHorizontal, textureSlot, samplerSlot,
                                                                DefaultSamplers.LinearSamplerClampAni1, EffectTechnique.EffectsManager));
                    target.Resize(Device, w, h);
                    offScreenRenderTargets.Add(target);
                    w >>= 2;
                    h >>= 2;
                    ++count;
                }
                //Skip this frame to avoid performance hit due to texture creation
                InvalidateRenderer();
                return;
            }
            #endregion

            #region Render objects onto offscreen texture
            var renderTargets = deviceContext.DeviceContext.OutputMerger.GetRenderTargets(1);
            using (var resource1 = renderTargets[0].Resource)
            {
                using (var resource2 = offScreenRenderTargets[0].CurrentRTV.Resource)
                {
                    if (context.RenderHost.RenderBuffer.ColorBufferSampleDesc.Count > 1)
                    {
                        deviceContext.DeviceContext.ResolveSubresource(resource1, 0, resource2, 0, global::SharpDX.DXGI.Format.B8G8R8A8_UNorm);
                    }
                    else
                    {
                        deviceContext.DeviceContext.CopyResource(resource1, resource2);
                    }
                }
            }
            //Decrement ref count. See OutputMerger.GetRenderTargets remarks
            foreach (var t in renderTargets)
            {
                t.Dispose();
            }
            #endregion

            deviceContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
            #region Do Bloom Pass
            deviceContext.DeviceContext.PixelShader.SetSampler(samplerSlot, sampler);

            //Extract bloom samples
            BindTarget(null, offScreenRenderTargets[0].NextRTV, deviceContext, offScreenRenderTargets[0].Width, offScreenRenderTargets[0].Height, false);
            screenQuadPass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, offScreenRenderTargets[0].CurrentSRV);
            screenQuadPass.BindShader(deviceContext);
            screenQuadPass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
            deviceContext.DeviceContext.Draw(4, 0);
            offScreenRenderTargets[0].SwapTargets();

            // Down sampling
            screenQuadCopy.BindShader(deviceContext);
            screenQuadCopy.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
            for (int i = 1; i < offScreenRenderTargets.Count; ++i)
            {
                BindTarget(null, offScreenRenderTargets[i].CurrentRTV, deviceContext, offScreenRenderTargets[i].Width, offScreenRenderTargets[i].Height, false);
                screenQuadCopy.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, offScreenRenderTargets[i - 1].CurrentSRV);
                deviceContext.DeviceContext.Draw(4, 0);
            }

            for (int i = offScreenRenderTargets.Count - 1; i >= 1; --i)
            {
                //Run blur pass
                offScreenRenderTargets[i].Run(deviceContext, NumberOfBlurPass);

                //Up sampling
                screenOutlinePass.BindShader(deviceContext);
                screenOutlinePass.BindStates(deviceContext, StateType.BlendState | StateType.RasterState | StateType.DepthStencilState);
                BindTarget(null, offScreenRenderTargets[i - 1].CurrentRTV, deviceContext, offScreenRenderTargets[i - 1].Width, offScreenRenderTargets[i - 1].Height, false);
                screenOutlinePass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, offScreenRenderTargets[i].CurrentSRV);
                deviceContext.DeviceContext.Draw(4, 0);
            }
            offScreenRenderTargets[0].Run(deviceContext, NumberOfBlurPass);
            #endregion

            #region Draw outline onto original target
            context.RenderHost.SetDefaultRenderTargets(false);
            screenOutlinePass.GetShader(ShaderStage.Pixel).BindTexture(deviceContext, textureSlot, offScreenRenderTargets[0].CurrentSRV);
            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
        }
Example #18
0
 protected override void OnDefaultPassChanged(ShaderPass pass)
 {
     base.OnDefaultPassChanged(pass);
     shadowMapSlot = pass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(ShaderShadowMapTextureName);
 }
 /// <summary>
 /// Called when [default pass changed].
 /// </summary>
 /// <param name="pass">The pass.</param>
 protected override void OnDefaultPassChanged(ShaderPass pass)
 {
     cubeTextureSlot    = pass.GetShader(ShaderStage.Pixel).ShaderResourceViewMapping.TryGetBindSlot(ShaderCubeTextureName);
     textureSamplerSlot = pass.GetShader(ShaderStage.Pixel).SamplerMapping.TryGetBindSlot(ShaderCubeTextureSamplerName);
 }