/// <summary> /// /// </summary> /// <param name="context"></param> internal void RenderShadowMapCascade(ShadowContext shadowRenderCtxt, IEnumerable <MeshInstance> instances) { using (new PixEvent("ShadowMap")) { if (surfaceShader == null) { return; } var device = Game.GraphicsDevice; var cbData = new CBMeshInstanceData(); var viewPosition = Matrix.Invert(shadowRenderCtxt.ShadowView).TranslationVector; device.SetTargets(shadowRenderCtxt.DepthBuffer, shadowRenderCtxt.ColorBuffer); device.SetViewport(shadowRenderCtxt.ShadowViewport); device.PixelShaderConstants[0] = constBuffer; device.VertexShaderConstants[0] = constBuffer; device.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap; device.PixelShaderConstants[1] = constBufferSubset; cbData.Projection = shadowRenderCtxt.ShadowProjection; cbData.View = shadowRenderCtxt.ShadowView; cbData.ViewPos = new Vector4(viewPosition, 1); cbData.BiasSlopeFar = new Vector4(shadowRenderCtxt.DepthBias, shadowRenderCtxt.SlopeBias, shadowRenderCtxt.FarDistance, 0); //#warning INSTANSING! foreach (var instance in instances) { if (!instance.Visible) { continue; } device.PipelineState = factory[(int)ApplyFlags(instance, SurfaceFlags.SHADOW)]; cbData.World = instance.World; cbData.Color = instance.Color; constBuffer.SetData(cbData); if (instance.IsSkinned) { constBufferBones.SetData(instance.BoneTransforms); device.VertexShaderConstants[3] = constBufferBones; } device.SetupVertexInput(instance.vb, instance.ib); device.DrawIndexed(instance.indexCount, 0, 0); rs.Counters.ShadowDIPs++; } } }
/// <summary> /// /// </summary> /// <param name="?"></param> internal void RenderShadows(RenderWorld renderWorld, LightSet lightSet) { var device = Game.GraphicsDevice; var camera = renderWorld.Camera; var instances = renderWorld.Instances; if (SkipShadows) { return; } CheckShadowSize(); csmController.ComputeMatricies( camera.GetViewMatrix(StereoEye.Mono), lightSet.DirectLight.Direction, cascadedShadowMap.CascadeSize, this.SplitSize, this.SplitOffset, this.SplitFactor, this.CSMProjectionDepth); ICSMController csmCtrl = lightSet.DirectLight.CSMController ?? csmController; int activeCascadeCount = Math.Min(cascadedShadowMap.CascadeCount, csmCtrl.GetActiveCascadeCount()); using (new PixEvent("Cascaded Shadow Maps")) { Game.GraphicsDevice.ResetStates(); cascadedShadowMap.Clear(); for (int i = 0; i < activeCascadeCount; i++) { var context = new ShadowContext(); context.ShadowView = csmCtrl.GetShadowViewMatrix(i); context.ShadowProjection = csmCtrl.GetShadowProjectionMatrix(i); context.ShadowViewport = cascadedShadowMap.GetCascadeViewport(i); context.FarDistance = 1; context.SlopeBias = CSMSlopeBias; context.DepthBias = CSMDepthBias; context.ColorBuffer = cascadedShadowMap.ColorBuffer.Surface; context.DepthBuffer = cascadedShadowMap.DepthBuffer.Surface; Game.RenderSystem.SceneRenderer.RenderShadowMapCascade(context, instances); } } using (new PixEvent("Particle Shadows")) { for (int i = 0; i < activeCascadeCount; i++) { var viewport = cascadedShadowMap.GetCascadeViewport(i); var colorBuffer = cascadedShadowMap.ParticleShadow.Surface; var depthBuffer = cascadedShadowMap.DepthBuffer.Surface; var viewMatrix = csmController.GetShadowViewMatrix(i); var projMatrix = csmController.GetShadowProjectionMatrix(i); renderWorld.ParticleSystem.RenderShadow(new GameTime(), viewport, viewMatrix, projMatrix, colorBuffer, depthBuffer); } } using (new PixEvent("Spotlight Shadow Maps")) { device.Clear(spotDepth.Surface, 1, 0); device.Clear(spotColor.Surface, Color4.White); int index = 0; foreach (var spot in lightSet.SpotLights) { var smSize = SpotShadowSize; var context = new ShadowContext(); var dx = index % 4; var dy = index / 4; var far = spot.Projection.GetFarPlaneDistance(); index++; context.ShadowView = spot.SpotView; context.ShadowProjection = spot.Projection; context.ShadowViewport = new Viewport(smSize * dx, smSize * dy, smSize, smSize); context.FarDistance = far; context.SlopeBias = spot.SlopeBias; context.DepthBias = spot.DepthBias; context.ColorBuffer = spotColor.Surface; context.DepthBuffer = spotDepth.Surface; Game.RenderSystem.SceneRenderer.RenderShadowMapCascade(context, instances); } } }
/// <summary> /// /// </summary> /// <param name="context"></param> internal void RenderShadowMapCascade ( ShadowContext shadowRenderCtxt, IEnumerable<MeshInstance> instances ) { using ( new PixEvent("ShadowMap") ) { if (surfaceShader==null) { return; } var device = Game.GraphicsDevice; var cbData = new CBMeshInstanceData(); var viewPosition = Matrix.Invert( shadowRenderCtxt.ShadowView ).TranslationVector; device.SetTargets( shadowRenderCtxt.DepthBuffer, shadowRenderCtxt.ColorBuffer ); device.SetViewport( shadowRenderCtxt.ShadowViewport ); device.PixelShaderConstants[0] = constBuffer ; device.VertexShaderConstants[0] = constBuffer ; device.PixelShaderSamplers[0] = SamplerState.AnisotropicWrap ; cbData.Projection = shadowRenderCtxt.ShadowProjection; cbData.View = shadowRenderCtxt.ShadowView; cbData.ViewPos = new Vector4( viewPosition, 1 ); cbData.BiasSlopeFar = new Vector4( shadowRenderCtxt.DepthBias, shadowRenderCtxt.SlopeBias, shadowRenderCtxt.FarDistance, 0 ); //#warning INSTANSING! foreach ( var instance in instances ) { if (!instance.Visible) { continue; } device.PipelineState = factory[ (int)ApplyFlags( null, instance, SurfaceFlags.SHADOW ) ]; cbData.World = instance.World; constBuffer.SetData( cbData ); if (instance.IsSkinned) { constBufferBones.SetData( instance.BoneTransforms ); device.VertexShaderConstants[3] = constBufferBones ; } device.SetupVertexInput( instance.vb, instance.ib ); device.DrawIndexed( instance.indexCount, 0, 0 ); rs.Counters.ShadowDIPs++; } } }
/// <summary> /// /// </summary> /// <param name="?"></param> internal void RenderShadows ( RenderWorld renderWorld, LightSet lightSet ) { var device = Game.GraphicsDevice; var camera = renderWorld.Camera; var instances = renderWorld.Instances; if (SkipShadows) { return; } CheckShadowSize(); csmController.ComputeMatricies( camera.GetViewMatrix(StereoEye.Mono), lightSet.DirectLight.Direction, cascadedShadowMap.CascadeSize, this.SplitSize, this.SplitOffset, this.SplitFactor, this.CSMProjectionDepth ); ICSMController csmCtrl = lightSet.DirectLight.CSMController ?? csmController; int activeCascadeCount = Math.Min( cascadedShadowMap.CascadeCount, csmCtrl.GetActiveCascadeCount() ); using (new PixEvent("Cascaded Shadow Maps")) { Game.GraphicsDevice.ResetStates(); cascadedShadowMap.Clear(); for (int i=0; i<activeCascadeCount; i++) { var context = new ShadowContext(); context.ShadowView = csmCtrl.GetShadowViewMatrix( i ); context.ShadowProjection = csmCtrl.GetShadowProjectionMatrix( i ); context.ShadowViewport = cascadedShadowMap.GetSplitViewport( i ); context.FarDistance = 1; context.SlopeBias = CSMSlopeBias; context.DepthBias = CSMDepthBias; context.ColorBuffer = cascadedShadowMap.ColorBuffer.Surface; context.DepthBuffer = cascadedShadowMap.DepthBuffer.Surface; Game.RenderSystem.SceneRenderer.RenderShadowMapCascade( context, instances ); } } using (new PixEvent("Particle Shadows")) { for (int i=0; i<activeCascadeCount; i++) { var viewport = cascadedShadowMap.GetSplitViewport(i); var colorBuffer = cascadedShadowMap.ParticleShadow.Surface; var depthBuffer = cascadedShadowMap.DepthBuffer.Surface; var viewMatrix = csmController.GetShadowViewMatrix( i ); var projMatrix = csmController.GetShadowProjectionMatrix( i ); renderWorld.ParticleSystem.RenderShadow( new GameTime(), viewport, viewMatrix, projMatrix, colorBuffer, depthBuffer ); } } using (new PixEvent("Spotlight Shadow Maps")) { device.Clear( spotDepth.Surface, 1, 0 ); device.Clear( spotColor.Surface, Color4.White ); int index = 0; foreach ( var spot in lightSet.SpotLights ) { var smSize = SpotShadowSize; var context = new ShadowContext(); var dx = index % 4; var dy = index / 4; var far = spot.Projection.GetFarPlaneDistance(); index++; context.ShadowView = spot.SpotView; context.ShadowProjection = spot.Projection; context.ShadowViewport = new Viewport( smSize * dx, smSize * dy, smSize, smSize ); context.FarDistance = far; context.SlopeBias = SpotSlopeBias; context.DepthBias = SpotDepthBias; context.ColorBuffer = spotColor.Surface; context.DepthBuffer = spotDepth.Surface; Game.RenderSystem.SceneRenderer.RenderShadowMapCascade( context, instances ); } } }