Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
0
        /// <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);
                }
            }
        }