/// <summary> /// /// </summary> /// <param name="view"></param> /// <param name="projection"></param> internal void RenderLighting(StereoEye stereoEye, Camera camera, HdrFrame hdrFrame, RenderWorld viewLayer, RenderTargetCube envLight) { using (new PixEvent("TiledLighting")) { var view = camera.GetViewMatrix(stereoEye); var projection = camera.GetProjectionMatrix(stereoEye); var device = Game.GraphicsDevice; device.ResetStates(); var width = hdrFrame.HdrBuffer.Width; var height = hdrFrame.HdrBuffer.Height; ICSMController csmCtrl = viewLayer.LightSet.DirectLight.CSMController ?? csmController; int activeCascadeCount = Math.Min(cascadedShadowMap.CascadeCount, csmCtrl.GetActiveCascadeCount()); // // Setup compute shader parameters and states : // try { var cbData = new LightingParams(); var invView = Matrix.Invert(view); var invVP = Matrix.Invert(view * projection); var viewPos = invView.TranslationVector; cbData.DirectLightDirection = new Vector4(viewLayer.LightSet.DirectLight.Direction, 0); cbData.DirectLightIntensity = viewLayer.LightSet.DirectLight.Intensity.ToVector4(); cbData.Projection = projection; cbData.CSMViewProjection0 = csmCtrl.GetShadowViewMatrix(0) * csmCtrl.GetShadowProjectionMatrix(0); cbData.CSMViewProjection1 = csmCtrl.GetShadowViewMatrix(1) * csmCtrl.GetShadowProjectionMatrix(1); cbData.CSMViewProjection2 = csmCtrl.GetShadowViewMatrix(2) * csmCtrl.GetShadowProjectionMatrix(2); cbData.CSMViewProjection3 = csmCtrl.GetShadowViewMatrix(3) * csmCtrl.GetShadowProjectionMatrix(3); cbData.View = view; cbData.ViewPosition = new Vector4(viewPos, 1); cbData.InverseViewProjection = invVP; cbData.CSMFilterRadius = new Vector4(CSMFilterSize); cbData.AmbientColor = viewLayer.LightSet.AmbientLevel; cbData.Viewport = new Vector4(0, 0, width, height); cbData.ShowCSLoadOmni = ShowOmniLightTileLoad ? 1 : 0; cbData.ShowCSLoadEnv = ShowEnvLightTileLoad ? 1 : 0; cbData.ShowCSLoadSpot = ShowSpotLightTileLoad ? 1 : 0; cbData.CascadeCount = activeCascadeCount; cbData.CascadeScale = 1.0f / (float)cascadedShadowMap.CascadeCount; cbData.FogDensity = viewLayer.FogSettings.Density; ComputeOmniLightsTiles(view, projection, viewLayer.LightSet); ComputeSpotLightsTiles(view, projection, viewLayer.LightSet); ComputeEnvLightsTiles(view, projection, viewLayer.LightSet); ComputeDecalTiles(view, projection, viewLayer.LightSet); // // set states : // device.SetTargets(null, hdrFrame.HdrBuffer.Surface); lightingCB.SetData(cbData); device.ComputeShaderSamplers[0] = SamplerState.PointClamp; device.ComputeShaderSamplers[1] = SamplerState.LinearClamp; device.ComputeShaderSamplers[2] = SamplerState.ShadowSampler; device.ComputeShaderSamplers[3] = SamplerState.LinearPointWrap; device.ComputeShaderResources[0] = hdrFrame.GBuffer0; device.ComputeShaderResources[1] = hdrFrame.GBuffer1; device.ComputeShaderResources[2] = rs.Sky.SkyCube; device.ComputeShaderResources[4] = hdrFrame.DepthBuffer; device.ComputeShaderResources[5] = cascadedShadowMap.ColorBuffer; device.ComputeShaderResources[6] = spotColor; device.ComputeShaderResources[7] = viewLayer.LightSet.SpotAtlas == null ? rs.WhiteTexture.Srv : viewLayer.LightSet.SpotAtlas.Texture.Srv; device.ComputeShaderResources[8] = omniLightBuffer; device.ComputeShaderResources[9] = spotLightBuffer; device.ComputeShaderResources[10] = envLightBuffer; device.ComputeShaderResources[11] = rs.SsaoFilter.OcclusionMap; device.ComputeShaderResources[12] = viewLayer.RadianceCache; device.ComputeShaderResources[13] = viewLayer.ParticleSystem.SimulatedParticles; device.ComputeShaderResources[14] = cascadedShadowMap.ParticleShadow; device.ComputeShaderResources[15] = envLut.Srv; device.ComputeShaderResources[16] = decalBuffer; device.ComputeShaderResources[17] = viewLayer.LightSet.DecalAtlas == null ? rs.WhiteTexture.Srv : viewLayer.LightSet.DecalAtlas.Texture.Srv; device.ComputeShaderConstants[0] = lightingCB; device.SetCSRWTexture(0, hdrFrame.LightAccumulator.Surface); device.SetCSRWBuffer(1, viewLayer.ParticleSystem.ParticleLighting); // // Dispatch solids : // using (new PixEvent("Solid Lighting")) { device.PipelineState = factory[(int)LightingFlags.SOLIDLIGHTING]; device.Dispatch(MathUtil.IntDivUp(width, BlockSizeX), MathUtil.IntDivUp(height, BlockSizeY), 1); } // // Dispatch particles : // using (new PixEvent("Particle Lighting")) { if (stereoEye != StereoEye.Right && !rs.SkipParticles) { int threadGroupCount = MathUtil.IntDivUp(ParticleSystem.MaxSimulatedParticles, ParticleSystem.BlockSize); device.PipelineState = factory[(int)LightingFlags.PARTICLES]; device.Dispatch(threadGroupCount, 1, 1); } } } catch (UbershaderException e) { Log.Warning("{0}", e.Message); } // // Add accumulated light : // rs.Filter.OverlayAdditive(hdrFrame.HdrBuffer.Surface, hdrFrame.LightAccumulator); // Uncomment to enable SSS : #if false rs.Filter.GaussBlur(hdrFrame.SSSAccumulator, hdrFrame.LightAccumulator, 5, 0); rs.Filter.OverlayAdditive(hdrFrame.HdrBuffer.Surface, hdrFrame.SSSAccumulator); #endif device.ResetStates(); if (rs.ShowLightCounters) { var ls = viewLayer.LightSet; Log.Message("lights: {0,5} omni {1,5} spot {2,5} env", ls.OmniLights.Count, ls.SpotLights.Count, ls.EnvLights.Count); } } }
/// <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); } } }