public void RenderShadowMap(
            Scene3D scene,
            GraphicsDevice graphicsDevice,
            ref ShadowConstantsPS constants,
            Action <Framebuffer, BoundingFrustum> drawSceneCallback)
        {
            // TODO: Use terrain light for terrain self-shadowing?
            var light = scene.Lighting.CurrentLightingConfiguration.ObjectLightsPS.Light0;

            // Calculate size of shadow map.
            var shadowMapSize = scene.Shadows.ShadowMapSize;
            var numCascades   = (uint)scene.Shadows.ShadowMapCascades;

            if (_shadowData != null && _shadowData.ShadowMap != null &&
                (_shadowData.ShadowMap.Width != shadowMapSize ||
                 _shadowData.ShadowMap.Height != shadowMapSize ||
                 _shadowData.NearPlaneDistance != scene.Camera.NearPlaneDistance ||
                 _shadowData.FarPlaneDistance != scene.Camera.FarPlaneDistance ||
                 _shadowData.NumSplits != numCascades))
            {
                RemoveAndDispose(ref _shadowData);
            }

            if (_shadowData == null)
            {
                _shadowData = AddDisposable(new ShadowData(
                                                numCascades,
                                                scene.Camera.NearPlaneDistance,
                                                scene.Camera.FarPlaneDistance,
                                                shadowMapSize,
                                                graphicsDevice));
            }

            if (scene.Shadows.ShadowsType == ShadowsType.None)
            {
                constants.ShadowsType = ShadowsType.None;
                return;
            }

            _shadowFrustumCalculator.CalculateShadowData(
                light,
                scene.Camera,
                _shadowData,
                scene.Shadows);

            constants.Set(numCascades, scene.Shadows, _shadowData);

            // Render scene geometry to each split of the cascade.
            for (var splitIndex = 0; splitIndex < _shadowData.NumSplits; splitIndex++)
            {
                _lightFrustum.Matrix = _shadowData.ShadowCameraViewProjections[splitIndex];

                drawSceneCallback(
                    _shadowData.ShadowMapFramebuffers[splitIndex],
                    _lightFrustum);
            }
        }
Example #2
0
        public void RenderShadowMap(
            Scene3D scene,
            GraphicsDevice graphicsDevice,
            CommandList commandList,
            Action <Framebuffer, BoundingFrustum> drawSceneCallback)
        {
            // TODO: Use terrain light for terrain self-shadowing?
            var light = scene.Lighting.CurrentLightingConfiguration.ObjectLightsPS.Light0;

            // Calculate size of shadow map.
            var shadowMapSize = scene.Shadows.ShadowMapSize;
            var numCascades   = (uint)scene.Shadows.ShadowMapCascades;

            if (_shadowData != null && _shadowData.ShadowMap != null &&
                (_shadowData.ShadowMap.Width != shadowMapSize ||
                 _shadowData.ShadowMap.Height != shadowMapSize ||
                 _shadowData.NearPlaneDistance != scene.Camera.NearPlaneDistance ||
                 _shadowData.FarPlaneDistance != scene.Camera.FarPlaneDistance ||
                 _shadowData.NumSplits != numCascades))
            {
                RemoveAndDispose(ref _shadowData);
                RemoveAndDispose(ref _resourceSet);
            }

            if (_shadowData == null)
            {
                _shadowData = AddDisposable(new ShadowData(
                                                numCascades,
                                                scene.Camera.NearPlaneDistance,
                                                scene.Camera.FarPlaneDistance,
                                                shadowMapSize,
                                                graphicsDevice));

                _resourceSet = AddDisposable(graphicsDevice.ResourceFactory.CreateResourceSet(
                                                 new ResourceSetDescription(
                                                     _globalShaderResources.GlobalShadowResourceLayout,
                                                     _shadowConstantsPSBuffer.Buffer,
                                                     _shadowData.ShadowMap,
                                                     _globalShaderResources.ShadowSampler)));
            }

            if (scene.Shadows.ShadowsType != ShadowsType.None)
            {
                _shadowFrustumCalculator.CalculateShadowData(
                    light,
                    scene.Camera,
                    _shadowData,
                    scene.Shadows);

                _shadowConstants.Set(numCascades, scene.Shadows, _shadowData);

                // Render scene geometry to each split of the cascade.
                for (var splitIndex = 0; splitIndex < _shadowData.NumSplits; splitIndex++)
                {
                    _lightFrustum.Matrix = _shadowData.ShadowCameraViewProjections[splitIndex];

                    drawSceneCallback(
                        _shadowData.ShadowMapFramebuffers[splitIndex],
                        _lightFrustum);
                }
            }
            else
            {
                _shadowConstants.ShadowsType = ShadowsType.None;
            }

            _shadowConstantsPSBuffer.Value = _shadowConstants;
            _shadowConstantsPSBuffer.Update(commandList);
        }