/// <summary> /// Runs the blur procedure /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> /// <param name="source">The source.</param> /// <param name="depth">The depth.</param> /// <param name="sourceViewport"></param> /// <param name="modelStruct"></param> public virtual void Run(RenderContext context, DeviceContextProxy deviceContext, ShaderResourceViewProxy source, ref ViewportF sourceViewport, BlurDepth depth, ref BorderEffectStruct modelStruct) { deviceContext.SetSampler(PixelShader.Type, samplerSlot, sampler); if ((depth & BlurDepth.One) != 0) { using (var target1 = context.GetOffScreenRT(OffScreenTextureSize.Half, global::SharpDX.DXGI.Format.R8G8B8A8_UNorm, out var width, out var height)) { modelStruct.ViewportScale = (int)OffScreenTextureSize.Half; modelCB.Upload(deviceContext, ref modelStruct); //Full -> Half Vertical deviceContext.SetRenderTarget(target1); deviceContext.SetViewport(0, 0, width, height); deviceContext.SetScissorRectangle(0, 0, width, height); screenBlurPassVertical.BindShader(deviceContext); screenBlurPassVertical.BindStates(deviceContext, StateType.All); screenBlurPassVertical.PixelShader.BindTexture(deviceContext, textureSlot, source); deviceContext.Draw(4, 0); if ((depth & BlurDepth.Two) != 0) { using (var target2 = context.GetOffScreenRT(OffScreenTextureSize.Quarter, global::SharpDX.DXGI.Format.R8G8B8A8_UNorm, out var width2, out var height2)) { // Half to Quater Vertical modelStruct.ViewportScale = (int)OffScreenTextureSize.Quarter; modelCB.Upload(deviceContext, ref modelStruct); deviceContext.SetRenderTarget(target2); deviceContext.SetViewport(0, 0, width2, height2); deviceContext.SetScissorRectangle(0, 0, width2, height2); screenBlurPassVertical.BindShader(deviceContext); screenBlurPassVertical.PixelShader.BindTexture(deviceContext, textureSlot, target1); deviceContext.Draw(4, 0); // Quater to Half Horizontal modelStruct.ViewportScale = (int)OffScreenTextureSize.Half; modelCB.Upload(deviceContext, ref modelStruct); deviceContext.SetRenderTarget(target1); deviceContext.SetViewport(0, 0, width, height); deviceContext.SetScissorRectangle(0, 0, width, height); screenBlurPassHorizontal.BindShader(deviceContext); screenBlurPassHorizontal.PixelShader.BindTexture(deviceContext, textureSlot, target2); deviceContext.Draw(4, 0); } } // Half to Full Horizontal modelStruct.ViewportScale = (int)OffScreenTextureSize.Full; modelCB.Upload(deviceContext, ref modelStruct); deviceContext.SetRenderTarget(source); deviceContext.SetViewport(ref sourceViewport); deviceContext.SetScissorRectangle(ref sourceViewport); screenBlurPassHorizontal.BindShader(deviceContext); screenBlurPassHorizontal.PixelShader.BindTexture(deviceContext, textureSlot, target1); deviceContext.Draw(4, 0); } } }
private void DrawOutline(RenderContext context, DeviceContextProxy deviceContext, ShaderResourceViewProxy depthStencilBuffer, ShaderResourceViewProxy source) { var buffer = context.RenderHost.RenderBuffer; var sourceViewport = new ViewportF(0, 0, buffer.FullResPPBuffer.Width, buffer.FullResPPBuffer.Height); deviceContext.SetViewport(ref sourceViewport); deviceContext.SetScissorRectangle(ref sourceViewport); #region Do Blur Pass if (useBlurCore) { for (var i = 0; i < numberOfBlurPass; ++i) { blurCore.Run(context, deviceContext, source, ref sourceViewport, PostEffectBlurCore.BlurDepth.One, ref modelStruct); } } else { blurPassHorizontal.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); for (var i = 0; i < numberOfBlurPass; ++i) { deviceContext.SetRenderTarget(context.RenderHost.RenderBuffer.FullResPPBuffer.NextRTV); blurPassHorizontal.PixelShader.BindTexture(deviceContext, textureSlot, source); blurPassHorizontal.BindShader(deviceContext); blurPassHorizontal.BindStates(deviceContext, StateType.All); deviceContext.Draw(4, 0); deviceContext.SetRenderTarget(source); blurPassVertical.PixelShader.BindTexture(deviceContext, textureSlot, context.RenderHost.RenderBuffer.FullResPPBuffer.NextRTV); blurPassVertical.BindShader(deviceContext); blurPassVertical.BindStates(deviceContext, StateType.All); deviceContext.Draw(4, 0); } } #region Draw back with stencil test deviceContext.SetRenderTarget(depthStencilBuffer, context.RenderHost.RenderBuffer.FullResPPBuffer.NextRTV, true, global::SharpDX.Color.Transparent, false); screenQuadPass.PixelShader.BindTexture(deviceContext, textureSlot, source); screenQuadPass.BindShader(deviceContext); screenQuadPass.BindStates(deviceContext, StateType.All); deviceContext.Draw(4, 0); #endregion #region Draw outline onto original target deviceContext.SetRenderTarget(buffer.FullResPPBuffer.CurrentRTV); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, context.RenderHost.RenderBuffer.FullResPPBuffer.NextRTV); screenOutlinePass.BindShader(deviceContext); screenOutlinePass.BindStates(deviceContext, StateType.All); deviceContext.Draw(4, 0); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, null); #endregion #endregion }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; #region Do Bloom Pass modelCB.Upload(deviceContext, ref modelStruct); //Extract bloom samples deviceContext.SetRenderTarget(buffer.FullResPPBuffer.NextRTV, buffer.TargetWidth, buffer.TargetHeight); screenQuadPass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.CurrentSRV); screenQuadPass.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); screenQuadPass.BindShader(deviceContext); screenQuadPass.BindStates(deviceContext, StateType.All); deviceContext.Draw(4, 0); // Down sampling for (int i = 0; i < numberOfBlurPass; ++i) { blurCore.Run(context, deviceContext, buffer.FullResPPBuffer.NextRTV, buffer.TargetWidth, buffer.TargetHeight, PostEffectBlurCore.BlurDepth.Two, ref modelStruct); } #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.All); deviceContext.Draw(4, 0); screenOutlinePass.PixelShader.BindTexture(deviceContext, textureSlot, null); #endregion }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; deviceContext.SetRenderTarget(buffer.FullResPPBuffer.NextRTV); var viewport = context.Viewport; deviceContext.SetViewport(ref viewport); deviceContext.SetScissorRectangle(ref viewport); OnUpdatePerModelStruct(context); modelCB.Upload(deviceContext, ref modelStruct); LUMAPass.BindShader(deviceContext); LUMAPass.BindStates(deviceContext, StateType.All); LUMAPass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.CurrentSRV); LUMAPass.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); deviceContext.Draw(4, 0); deviceContext.SetRenderTarget(buffer.FullResPPBuffer.CurrentRTV); FXAAPass.BindShader(deviceContext); FXAAPass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.NextSRV); deviceContext.Draw(4, 0); FXAAPass.PixelShader.BindTexture(deviceContext, textureSlot, null); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { if (CreateRenderTargets((int)context.ActualWidth, (int)context.ActualHeight)) { RaiseInvalidateRender(); return; } var buffer = context.RenderHost.RenderBuffer; var hasMSAA = buffer.ColorBufferSampleDesc.Count > 1; var nonMSAADepthBuffer = hasMSAA ? context.RenderHost.RenderBuffer.DepthStencilBufferNoMSAA : null; var depthStencilView = hasMSAA ? nonMSAADepthBuffer : ExternRenderParameter.DepthStencilView; RenderCount = 0; InitializeMinMaxRenderTarget(deviceContext); context.OITRenderStage = OITRenderStage.DepthPeelingInitMinMaxZ; deviceContext.SetRenderTarget(depthStencilView, minMaxZTargets[0]); DrawMesh(context, deviceContext); context.OITRenderStage = OITRenderStage.DepthPeeling; var currId = 0; for (var layer = 1; layer < PeelingIteration; ++layer) { currId = layer % 2; var prevId = 1 - currId; var color = new Color4(-1, -1, 0, 0); deviceContext.ClearRenderTargetView(minMaxZTargets[currId], color); targets[0] = minMaxZTargets[currId]; targets[1] = frontBlendingTarget; targets[2] = backBlendingTarget; deviceContext.SetRenderTargets(depthStencilView, targets); deviceContext.SetShaderResource(new PixelShaderType(), 100, minMaxZTargets[prevId]); DrawMesh(context, deviceContext); deviceContext.SetShaderResource(new PixelShaderType(), 100, null); } context.OITRenderStage = OITRenderStage.None; finalSRVs[0] = minMaxZTargets[currId]; finalSRVs[1] = frontBlendingTarget; finalSRVs[2] = backBlendingTarget; finalPass.BindShader(deviceContext); finalPass.BindStates(deviceContext, StateType.All); deviceContext.SetRenderTargets(null, ExternRenderParameter.RenderTargetView); deviceContext.SetShaderResources(new PixelShaderType(), 100, finalSRVs); deviceContext.Draw(4, 0); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; deviceContext.SetRenderTarget(buffer.FullResPPBuffer.NextRTV, buffer.TargetWidth, buffer.TargetHeight); OnUpdatePerModelStruct(context); modelCB.Upload(deviceContext, ref modelStruct); LUMAPass.BindShader(deviceContext); LUMAPass.BindStates(deviceContext, StateType.All); LUMAPass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.CurrentSRV); LUMAPass.PixelShader.BindSampler(deviceContext, samplerSlot, sampler); deviceContext.Draw(4, 0); deviceContext.SetRenderTargetOnly(buffer.FullResPPBuffer.CurrentRTV); FXAAPass.BindShader(deviceContext); FXAAPass.PixelShader.BindTexture(deviceContext, textureSlot, buffer.FullResPPBuffer.NextSRV); deviceContext.Draw(4, 0); FXAAPass.PixelShader.BindTexture(deviceContext, textureSlot, null); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { EnsureTextureResources((int)context.ActualWidth, (int)context.ActualHeight, deviceContext); int texScale = (int)offScreenTextureSize; var viewport = context.Viewport; using (var ds = context.GetOffScreenDS(offScreenTextureSize, DEPTHFORMAT)) { using (var rt0 = context.GetOffScreenRT(offScreenTextureSize, RENDERTARGETFORMAT)) { using (var rt1 = context.GetOffScreenRT(offScreenTextureSize, SSAOTARGETFORMAT)) { var w = (int)(context.ActualWidth / texScale);// Make sure to set correct viewport width/height by quality var h = (int)(context.ActualHeight / texScale); deviceContext.SetRenderTarget(ds, rt0, true, new Color4(0, 0, 0, 1), true, DepthStencilClearFlags.Depth); deviceContext.SetViewport(0, 0, w, h); deviceContext.SetScissorRectangle(0, 0, w, h); IRenderTechnique currTechnique = null; var ssaoPass1 = ShaderPass.NullPass; var frustum = context.BoundingFrustum; for (var i = 0; i < context.RenderHost.PerFrameOpaqueNodesInFrustum.Count; ++i) { var node = context.RenderHost.PerFrameOpaqueNodesInFrustum[i]; if (currTechnique != node.EffectTechnique) { currTechnique = node.EffectTechnique; ssaoPass1 = currTechnique[DefaultPassNames.MeshSSAOPass]; } if (ssaoPass1.IsNULL) { continue; } node.RenderDepth(context, deviceContext, ssaoPass1); } var invProjection = context.ProjectionMatrix.Inverted(); ssaoParam.InvProjection = invProjection; ssaoParam.NoiseScale = new Vector2(w / 4f, h / 4f); ssaoParam.Radius = radius; ssaoParam.TextureScale = texScale; ssaoCB.ModelConstBuffer.UploadDataToBuffer(deviceContext, (dataBox) => { Debug.Assert(UnsafeHelper.SizeOf(kernels) + UnsafeHelper.SizeOf(ref ssaoParam) <= ssaoCB.ModelConstBuffer.bufferDesc.SizeInBytes); var nextPtr = UnsafeHelper.Write(dataBox.DataPointer, kernels, 0, kernels.Length); UnsafeHelper.Write(nextPtr, ref ssaoParam); }); deviceContext.SetRenderTarget(rt1); ssaoPass.BindShader(deviceContext); ssaoPass.BindStates(deviceContext, StateType.All); ssaoPass.PixelShader.BindTexture(deviceContext, ssaoTexSlot, rt0); ssaoPass.PixelShader.BindTexture(deviceContext, noiseTexSlot, ssaoNoiseView); ssaoPass.PixelShader.BindTexture(deviceContext, depthSlot, ds); ssaoPass.PixelShader.BindSampler(deviceContext, surfaceSampleSlot, surfaceSampler); ssaoPass.PixelShader.BindSampler(deviceContext, noiseSamplerSlot, noiseSampler); deviceContext.Draw(4, 0); ssaoPass.PixelShader.BindTexture(deviceContext, depthSlot, null); deviceContext.SetRenderTarget(ssaoView); deviceContext.SetViewport(ref viewport); deviceContext.SetScissorRectangle(ref viewport); ssaoBlur.BindShader(deviceContext); ssaoBlur.BindStates(deviceContext, StateType.All); ssaoBlur.PixelShader.BindTexture(deviceContext, ssaoTexSlot, rt1); ssaoBlur.PixelShader.BindSampler(deviceContext, surfaceSampleSlot, blurSampler); deviceContext.Draw(4, 0); context.SharedResource.SSAOMap = ssaoView; context.RenderHost.SetDefaultRenderTargets(false); deviceContext.SetShaderResource(PixelShader.Type, ssaoTexSlot, ssaoView); } } } }
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; var dPass = EnableDoublePass; var depthStencilBuffer = buffer.DepthStencilBufferNoMSAA; deviceContext.SetRenderTarget(depthStencilBuffer, buffer.FullResPPBuffer.CurrentRTV); var viewport = context.Viewport; deviceContext.SetViewport(ref viewport); deviceContext.SetScissorRectangle(ref viewport); deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 1, 0); if (dPass) { for (var i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out var effect)) { currentCores.Add(new KeyValuePair <SceneNode, IEffectAttributes>(mesh, effect)); context.CustomPassName = DefaultPassNames.EffectMeshXRayP1; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP1]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } } modelCB.Upload(deviceContext, ref modelStruct); for (var i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i]; var effect = mesh.Value; var color = Color; if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out var attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; modelCB.Upload(deviceContext, ref modelStruct); } context.CustomPassName = DefaultPassNames.EffectMeshXRayP2; var pass = mesh.Key.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.Key.RenderCustom(context, deviceContext); } currentCores.Clear(); } else { modelCB.Upload(deviceContext, ref modelStruct); for (var i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out var effect)) { var color = Color; if (effect.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out var attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; modelCB.Upload(deviceContext, ref modelStruct); } context.CustomPassName = DefaultPassNames.EffectMeshXRayP2; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState); deviceContext.SetDepthStencilState(pass.DepthStencilState, 0); mesh.RenderCustom(context, deviceContext); } } } }
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; var hasMSAA = buffer.ColorBufferSampleDesc.Count > 1; var depthStencilBuffer = hasMSAA ? context.GetOffScreenDS(OffScreenTextureSize.Full, Format.D32_Float_S8X24_UInt) : buffer.DepthStencilBuffer; deviceContext.SetRenderTarget(depthStencilBuffer, buffer.FullResPPBuffer.CurrentRTV); var viewport = context.Viewport; deviceContext.SetViewport(ref viewport); deviceContext.SetScissorRectangle(ref viewport); if (hasMSAA) { //Needs to do a depth pass for existing meshes.Because the msaa depth buffer is not resolvable. deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Depth, 1, 0); depthPrepassCore.Render(context, deviceContext); } //First pass, draw onto stencil buffer for (var i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out var effect)) { currentCores.Add(new KeyValuePair <SceneNode, IEffectAttributes>(mesh, effect)); context.CustomPassName = DefaultPassNames.EffectMeshXRayGridP1; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayGridP1]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } } //Second pass, remove not covered part from stencil buffer for (var i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i].Key; context.CustomPassName = DefaultPassNames.EffectMeshXRayGridP2; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayGridP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } OnUpdatePerModelStruct(context); modelCB.Upload(deviceContext, ref modelStruct); //Thrid pass, draw mesh with grid overlay for (var i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i].Key; var color = Color; if (currentCores[i].Value.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out var attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; modelCB.Upload(deviceContext, ref modelStruct); } context.CustomPassName = XRayDrawingPassName; var pass = mesh.EffectTechnique[XRayDrawingPassName]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); if (mesh.RenderCore is IMaterialRenderParams material) { material.MaterialVariables.BindMaterialResources(context, deviceContext, pass); } mesh.RenderCustom(context, deviceContext); } if (hasMSAA) { deviceContext.ClearRenderTagetBindings(); depthStencilBuffer.Dispose(); } currentCores.Clear(); }
public override void Render(RenderContext context, DeviceContextProxy deviceContext) { int width = 0; int height = 0; using (var depthStencilBuffer = context.GetOffScreenDS(TextureSize, global::SharpDX.DXGI.Format.D32_Float_S8X24_UInt, out width, out height)) { using (var renderTargetBuffer = context.GetOffScreenRT(TextureSize, global::SharpDX.DXGI.Format.R8G8B8A8_UNorm)) { OnUpdatePerModelStruct(context); 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]; deviceContext.SetRenderTarget(depthStencilBuffer, renderTargetBuffer, width, height, true, global::SharpDX.Color.Transparent, true, DepthStencilClearFlags.Stencil, 0, 0); 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, renderTargetBuffer, width, height); } #endregion } } else { deviceContext.SetRenderTarget(depthStencilBuffer, renderTargetBuffer, width, height, true, Transparent, true, DepthStencilClearFlags.Stencil, 0, 0); #region Render objects onto offscreen texture bool hasMesh = false; for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; 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, renderTargetBuffer, width, height); } } } } }
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; bool hasMSAA = buffer.ColorBufferSampleDesc.Count > 1; var dPass = EnableDoublePass; var depthStencilBuffer = hasMSAA ? context.GetOffScreenDS(OffScreenTextureSize.Full, Format.D32_Float_S8X24_UInt) : buffer.DepthStencilBuffer; deviceContext.SetRenderTarget(depthStencilBuffer, buffer.FullResPPBuffer.CurrentRTV, buffer.TargetWidth, buffer.TargetHeight); if (hasMSAA) { //Needs to do a depth pass for existing meshes.Because the msaa depth buffer is not resolvable. deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Depth, 1, 0); depthPrepassCore.Render(context, deviceContext); } deviceContext.ClearDepthStencilView(depthStencilBuffer, DepthStencilClearFlags.Stencil, 1, 0); if (dPass) { for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out IEffectAttributes effect)) { currentCores.Add(new KeyValuePair <SceneNode, IEffectAttributes>(mesh, effect)); context.CustomPassName = DefaultPassNames.EffectMeshXRayP1; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP1]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } } modelCB.Upload(deviceContext, ref modelStruct); for (int i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i]; IEffectAttributes effect = mesh.Value; 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.EffectMeshXRayP2; var pass = mesh.Key.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.Key.RenderCustom(context, deviceContext); } currentCores.Clear(); } else { modelCB.Upload(deviceContext, ref modelStruct); for (int i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; 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.EffectMeshXRayP2; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState); deviceContext.SetDepthStencilState(pass.DepthStencilState, 0); mesh.RenderCustom(context, deviceContext); } } } if (hasMSAA) { deviceContext.ClearRenderTagetBindings(); depthStencilBuffer.Dispose(); } }
/// <summary> /// Called when [render]. /// </summary> /// <param name="context">The context.</param> /// <param name="deviceContext">The device context.</param> public override void Render(RenderContext context, DeviceContextProxy deviceContext) { var buffer = context.RenderHost.RenderBuffer; var depthStencilBuffer = buffer.DepthStencilBufferNoMSAA; deviceContext.SetRenderTarget(depthStencilBuffer, buffer.FullResPPBuffer.CurrentRTV); var viewport = context.Viewport; deviceContext.SetViewport(ref viewport); deviceContext.SetScissorRectangle(ref viewport); //First pass, draw onto stencil buffer for (var i = 0; i < context.RenderHost.PerFrameNodesWithPostEffect.Count; ++i) { var mesh = context.RenderHost.PerFrameNodesWithPostEffect[i]; if (mesh.TryGetPostEffect(EffectName, out var effect)) { currentCores.Add(new KeyValuePair <SceneNode, IEffectAttributes>(mesh, effect)); context.CustomPassName = DefaultPassNames.EffectMeshXRayGridP1; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayGridP1]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } } //Second pass, remove not covered part from stencil buffer for (var i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i].Key; context.CustomPassName = DefaultPassNames.EffectMeshXRayGridP2; var pass = mesh.EffectTechnique[DefaultPassNames.EffectMeshXRayGridP2]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); mesh.RenderCustom(context, deviceContext); } OnUpdatePerModelStruct(context); modelCB.Upload(deviceContext, ref modelStruct); //Thrid pass, draw mesh with grid overlay for (var i = 0; i < currentCores.Count; ++i) { var mesh = currentCores[i].Key; var color = Color; if (currentCores[i].Value.TryGetAttribute(EffectAttributeNames.ColorAttributeName, out var attribute) && attribute is string colorStr) { color = colorStr.ToColor4(); } if (modelStruct.Color != color) { modelStruct.Color = color; modelCB.Upload(deviceContext, ref modelStruct); } context.CustomPassName = XRayDrawingPassName; var pass = mesh.EffectTechnique[XRayDrawingPassName]; if (pass.IsNULL) { continue; } pass.BindShader(deviceContext); pass.BindStates(deviceContext, StateType.BlendState | StateType.DepthStencilState); if (mesh.RenderCore is IMaterialRenderParams material) { material.MaterialVariables.BindMaterialResources(context, deviceContext, pass); } mesh.RenderCustom(context, deviceContext); } currentCores.Clear(); }