Example #1
0
 public void Generate()
 {
     SetupTerainData();
     noisehelper = new NoiseHelper(xOffset, yOffset);
     GenerateBiomes();
     noisehelper.SetBiomes(biomes);
     noisehelper.SetBounds(new Rect(yOffset, yOffset + 1, xOffset, xOffset + 1));
     GenerateHeightmap(biomes);
     GenerateAlphamap(biomes);
 }
Example #2
0
 public override ModuleBase Generate(NoiseHelper noisehelper)
 {
     return noisehelper.GetBorealForestNoise();
 }
        public override void Update(GameTime gameTime)
        {
            Random random = new Random(1234567);

            // The debug renderer stores all draw commands. In this sample we recreate
            // the draw jobs each frame. --> Clear draw jobs of last frame.
            _debugRenderer.Clear();

            // The DebugRenderer can draw stuff "in" the scene (enabled z test) or "over"
            // the scene (disabled z test).

            // Draw some points and line "in" and "over" the scene.
            for (int i = 0; i < 10; i++)
            {
                var position = new Vector3F(-6, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                _debugRenderer.DrawPoint(position, Color.Green, false);
            }

            for (int i = 0; i < 10; i++)
            {
                var position = new Vector3F(-4, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                _debugRenderer.DrawPoint(position, Color.Yellow, true);
            }

            for (int i = 0; i < 10; i++)
            {
                var start = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                var end   = new Vector3F(-2, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                _debugRenderer.DrawLine(start, end, Color.Green, false);
            }

            for (int i = 0; i < 10; i++)
            {
                var start = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                var end   = new Vector3F(0, 0, -3) + random.NextVector3F(-0.5f, 0.5f);
                _debugRenderer.DrawLine(start, end, Color.Yellow, true);
            }

            // Text without a specified position is drawn at a default position.
            _debugRenderer.DefaultTextPosition = new Vector2F(10, 100);
            _debugRenderer.DrawText("White objects are positioned in screen space.");
            _debugRenderer.DrawText("Yellow objects are positioned in world space. Depth test disabled.");
            _debugRenderer.DrawText("Other objects are positioned in world space. Depth test enabled.");

            // Text can also be drawn in world space coordinates or in screen space coordinates.
            _debugRenderer.DrawText("WorldSpacePosition (0, 0, 0)", new Vector3F(0, 0, 0), Color.Green, false);
            _debugRenderer.DrawText("WorldSpacePosition (0, 0, -1)", new Vector3F(0, 0, -1), Color.Yellow, true);
            _debugRenderer.DrawText("ScreenPosition (600, 40)", new Vector2F(600, 40), Color.White);
            _debugRenderer.DrawText("ScreenPosition (640, 360)", new Vector2F(640, 360), Color.White);

            // It is often useful to copy textures to the screen for debugging.
            _debugRenderer.DrawTexture(NoiseHelper.GetGrainTexture(GraphicsService, 128), new Rectangle(1000, 10, 128, 128));

            // Axes can be drawn to display poses (positions and orientations).
            _debugRenderer.DrawAxes(new Pose(new Vector3F(0, 0, 0)), 1, true);

            // Axis-aligned bounding boxes (AABB)
            _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(2, 0, -3)), Color.Green, false);
            _debugRenderer.DrawAabb(new Aabb(new Vector3F(-0.5f), new Vector3F(0.5f)), new Pose(new Vector3F(4, 0, -3)), Color.Yellow, true);

            // Box shapes
            var orientation = random.NextQuaternionF();

            _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), new Color(255, 0, 0, 100), false, false);
            _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-6, 0, -5), orientation), Color.Green, true, false);
            _debugRenderer.DrawBox(1, 1, 1, new Pose(new Vector3F(-4, 0, -5), orientation), Color.Yellow, true, true);

            // View volumes (frustums)
            var viewVolume = new PerspectiveViewVolume(1, 2, 0.1f, 1f);

            _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), new Color(0, 255, 0, 100), false, false);
            _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(-2, 0, -5), orientation), Color.Green, true, false);
            _debugRenderer.DrawViewVolume(viewVolume, new Pose(new Vector3F(0, 0, -5), orientation), Color.Yellow, true, true);

            // Spheres
            _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), new Color(0, 0, 255, 100), false, false);
            _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(2, 0, -5), orientation), Color.Green, true, false);
            _debugRenderer.DrawSphere(0.5f, new Pose(new Vector3F(4, 0, -5), orientation), Color.Yellow, true, true);

            // Capsules
            _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), new Color(255, 255, 0, 100), false, false);
            _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-6, 0, -7), orientation), Color.Green, true, false);
            _debugRenderer.DrawCapsule(0.3f, 1, new Pose(new Vector3F(-4, 0, -7), orientation), Color.Yellow, true, true);

            // Cylinders
            _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), new Color(255, 0, 255, 100), false, false);
            _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(-2, 0, -7), orientation), Color.Green, true, false);
            _debugRenderer.DrawCylinder(0.3f, 1, new Pose(new Vector3F(0, 0, -7), orientation), Color.Yellow, true, true);

            // Cones
            _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), new Color(0, 255, 255, 100), false, false);
            _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(2, 0, -7), orientation), Color.Green, true, false);
            _debugRenderer.DrawCone(0.3f, 1, new Pose(new Vector3F(4, 0, -7), orientation), Color.Yellow, true, true);

            // The debug renderer can draw any IGeometricObjects, like SceneNodes, RigidBodies, etc.
            _debugRenderer.DrawObject(_geometricObject, Color.Brown, false, false);
            _debugRenderer.DrawObject(_geometricObject, Color.Yellow, true, true);

            // The debug renderer can also an XNA model (without materials).
            _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), new Color(128, 255, 64, 100), false, false);
            _debugRenderer.DrawModel(_xnaModel, new Pose(new Vector3F(0, 2, -2), orientation), new Vector3F(1, 2, 1), Color.LightCyan, true, false);

            // Draw a DigitalRune model.
            _debugRenderer.DrawModel(_modelNode, Color.Peru, true, false);

            // Draw the bounding shapes of the meshes in this model.
            foreach (var node in _modelNode.GetSubtree())
            {
                _debugRenderer.DrawObject(node, Color.PeachPuff, true, false);
            }
        }
        public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            int numberOfNodes = nodes.Count;

            if (numberOfNodes == 0)
            {
                return;
            }

            context.Validate(_effect);
            context.ThrowIfCameraMissing();

            var graphicsDevice   = _effect.GraphicsDevice;
            var savedRenderState = new RenderStateSnapshot(graphicsDevice);

            graphicsDevice.DepthStencilState = DepthStencilState.None;
            graphicsDevice.RasterizerState   = RasterizerState.CullNone;

            var cameraNode = context.CameraNode;

            _parameterViewInverse.SetValue(cameraNode.PoseWorld);
            _parameterGBuffer0.SetValue(context.GBuffer0);

            Viewport viewport = context.Viewport;

            _parameterParameters0.SetValue(new Vector2(viewport.Width, viewport.Height));

            if (_jitterMap == null)
            {
                _jitterMap = NoiseHelper.GetGrainTexture(context.GraphicsService, NoiseHelper.DefaultJitterMapWidth);
            }

            _parameterJitterMap.SetValue(_jitterMap);

            for (int i = 0; i < numberOfNodes; i++)
            {
                var lightNode = nodes[i] as LightNode;
                if (lightNode == null)
                {
                    continue;
                }

                var shadow = lightNode.Shadow as StandardShadow;
                if (shadow == null)
                {
                    continue;
                }

                if (shadow.ShadowMap == null || shadow.ShadowMask == null)
                {
                    continue;
                }

                // The effect must only render in a specific channel.
                // Do not change blend state if the correct write channels is already set, e.g. if this
                // shadow is part of a CompositeShadow, the correct blend state is already set.
                if ((int)graphicsDevice.BlendState.ColorWriteChannels != (1 << shadow.ShadowMaskChannel))
                {
                    graphicsDevice.BlendState = GraphicsHelper.BlendStateWriteSingleChannel[shadow.ShadowMaskChannel];
                }

                _parameterParameters1.SetValue(new Vector4(
                                                   shadow.Near,
                                                   shadow.Far,
                                                   shadow.EffectiveDepthBias,
                                                   shadow.EffectiveNormalOffset));

                // If we use a subset of the Poisson kernel, we have to normalize the scale.
                int   numberOfSamples = Math.Min(shadow.NumberOfSamples, PoissonKernel.Length);
                float filterRadius    = shadow.FilterRadius;
                if (numberOfSamples > 0)
                {
                    filterRadius /= PoissonKernel[numberOfSamples - 1].Length();
                }

                _parameterParameters2.SetValue(new Vector3(
                                                   shadow.ShadowMap.Width,
                                                   filterRadius,
                                                   // The StandardShadow.JitterResolution is the number of texels per world unit.
                                                   // In the shader the parameter JitterResolution contains the division by the jitter map size.
                                                   shadow.JitterResolution / _jitterMap.Width));

                _parameterLightPosition.SetValue((Vector3)cameraNode.PoseWorld.ToLocalPosition(lightNode.PoseWorld.Position));

                Matrix cameraViewToShadowView = cameraNode.PoseWorld * shadow.View;
                _parameterShadowView.SetValue(cameraViewToShadowView);
                _parameterShadowMatrix.SetValue(cameraViewToShadowView * shadow.Projection);
                _parameterShadowMap.SetValue(shadow.ShadowMap);

                var      rectangle           = GraphicsHelper.GetViewportRectangle(cameraNode, viewport, lightNode);
                Vector2F texCoordTopLeft     = new Vector2F(rectangle.Left / (float)viewport.Width, rectangle.Top / (float)viewport.Height);
                Vector2F texCoordBottomRight = new Vector2F(rectangle.Right / (float)viewport.Width, rectangle.Bottom / (float)viewport.Height);
                GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, texCoordTopLeft, texCoordBottomRight, _frustumFarCorners);
                _parameterFrustumCorners.SetValue(_frustumFarCorners);

                var pass = GetPass(numberOfSamples);

                if (numberOfSamples > 0)
                {
                    if (_lastNumberOfSamples != numberOfSamples)
                    {
                        // Create an array with the first n samples and the rest set to 0.
                        _lastNumberOfSamples = numberOfSamples;
                        for (int j = 0; j < numberOfSamples; j++)
                        {
                            _samples[j].X = PoissonKernel[j].X;
                            _samples[j].Y = PoissonKernel[j].Y;
                            _samples[j].Z = 1.0f / numberOfSamples;

                            // Note [HelmutG]: I have tried weights decreasing with distance but that did not
                            // look better.
                        }

                        // Set the rest to zero.
                        for (int j = numberOfSamples; j < _samples.Length; j++)
                        {
                            _samples[j] = Vector3.Zero;
                        }

                        _parameterSamples.SetValue(_samples);
                    }
                    else if (i == 0)
                    {
                        // Apply offsets in the first loop.
                        _parameterSamples.SetValue(_samples);
                    }
                }

                pass.Apply();

                graphicsDevice.DrawQuad(rectangle);
            }

            _parameterGBuffer0.SetValue((Texture2D)null);
            _parameterJitterMap.SetValue((Texture2D)null);
            _parameterShadowMap.SetValue((Texture2D)null);
            savedRenderState.Restore();
        }
Example #5
0
 public override ModuleBase Generate(NoiseHelper noisehelper)
 {
     return noisehelper.GetTaigaNoise();
 }
Example #6
0
 public abstract ModuleBase Generate(NoiseHelper noisehelper);
Example #7
0
 static NoiseLoader()
 {
     ComponentTypeRegistory = new ComponentTypeRegistory();
     NoiseHelper.SetTypeDefinitionNames(ComponentTypeRegistory);
 }
Example #8
0
 public override ModuleBase Generate(NoiseHelper noisehelper)
 {
     return noisehelper.GetArctic();
 }
        public TerrainTextureSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);

            var scene = _graphicsScreen.Scene;

            Services.Register(typeof(IScene), null, scene);

            // Add gravity and damping to the physics simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services, 60);

            cameraGameObject.ResetPose(new Vector3F(0, 1.8f, 0), 0, 0);
            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            for (int i = 0; i < 10; i++)
            {
                GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            }

            GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true));

            // Create a simple flat terrain.
            var terrain = new Terrain();

            _terrainTile = new TerrainTile(GraphicsService)
            {
                OriginX  = -100,
                OriginZ  = -100,
                CellSize = 1,
            };
            terrain.Tiles.Add(_terrainTile);

            // Create a flat dummy height texture.
            float[]   heights       = new float[200 * 200];
            Texture2D heightTexture = null;

            TerrainHelper.CreateHeightTexture(
                GraphicsService.GraphicsDevice,
                heights,
                200,
                200,
                false,
                ref heightTexture);
            _terrainTile.HeightTexture = heightTexture;

            var shadowMapEffect = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainShadowMap");
            var gBufferEffect   = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainGBuffer");
            var materialEffect  = ContentManager.Load <Effect>("DigitalRune/Terrain/TerrainMaterial");
            var material        = new Material
            {
                { "ShadowMap", new EffectBinding(GraphicsService, shadowMapEffect, null, EffectParameterHint.Material) },
                { "GBuffer", new EffectBinding(GraphicsService, gBufferEffect, null, EffectParameterHint.Material) },
                { "Material", new EffectBinding(GraphicsService, materialEffect, null, EffectParameterHint.Material) }
            };
            var terrainNode = new TerrainNode(terrain, material)
            {
                DetailClipmap =
                {
                    CellsPerLevel  = 1364,
                    NumberOfLevels =    9,
                    EnableMipMap   = true,
                },
            };

            scene.Children.Add(terrainNode);

            // Add 3 detail textures layers: gravel, rock, snow.
            float detailCellSize = terrainNode.DetailClipmap.CellSizes[0];
            var   materialGravel = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture  = ContentManager.Load <Texture2D>("Terrain/Gravel-Diffuse"),
                NormalTexture   = ContentManager.Load <Texture2D>("Terrain/Gravel-Normal"),
                SpecularTexture = ContentManager.Load <Texture2D>("Terrain/Gravel-Specular"),
                TileSize        = detailCellSize * 512,
                BlendRange      = 0.1f,
            };

            _terrainTile.Layers.Add(materialGravel);

            var noiseTexture = NoiseHelper.GetNoiseTexture(GraphicsService, 128, 60);

            var materialRock = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture          = ContentManager.Load <Texture2D>("Terrain/Rock-02-Diffuse"),
                NormalTexture           = ContentManager.Load <Texture2D>("Terrain/Rock-02-Normal"),
                SpecularTexture         = ContentManager.Load <Texture2D>("Terrain/Rock-02-Specular"),
                HeightTexture           = ContentManager.Load <Texture2D>("Terrain/Rock-02-Height"),
                TileSize                = detailCellSize * 1024,
                DiffuseColor            = new Vector3F(1 / 0.702f),
                BlendTexture            = noiseTexture,
                BlendTextureChannel     = 0,
                BlendRange              = 0.1f,
                TerrainHeightBlendRange = 0.1f,
            };

            _terrainTile.Layers.Add(materialRock);

            var materialSnow = new TerrainMaterialLayer(GraphicsService)
            {
                DiffuseTexture      = ContentManager.Load <Texture2D>("Terrain/Snow-Diffuse"),
                NormalTexture       = ContentManager.Load <Texture2D>("Terrain/Snow-Normal"),
                SpecularTexture     = ContentManager.Load <Texture2D>("Terrain/Snow-Specular"),
                TileSize            = detailCellSize * 512,
                BlendTexture        = noiseTexture,
                BlendTextureChannel = 1,
                BlendRange          = 0.1f,
            };

            _terrainTile.Layers.Add(materialSnow);

            // Create a flat plane for collision detection.
            var rigidBody = new RigidBody(new PlaneShape(), new MassFrame(), null)
            {
                MotionType = MotionType.Static,
            };

            Simulation.RigidBodies.Add(rigidBody);

            CreateGuiControls();
        }
Example #10
0
 public override ModuleBase Generate(NoiseHelper noisehelper)
 {
     return noisehelper.GetTundraNoise();// noisehelper.GetHighFreqNoise(x, y) * 0.75f + noisehelper.GetMedFreqRidged(x, y) * 0.25f;
 }
Example #11
0
    private void RunGenerationForWeather(WeatherDefinition weatherDefinition, int seed, string presetName)
    {
        string currentSeasonType;

        if (!string.IsNullOrEmpty(presetName))
        {
            currentSeasonType = presetName;
        }
        else
        {
            currentSeasonType = this.seasonService.GetCurrentSeason().SeasonDefinition.SeasonType;
        }
        if (string.IsNullOrEmpty(currentSeasonType))
        {
            Diagnostics.LogError("currentSeasonType can't be null or empty");
            return;
        }
        WeatherDefinition.Preferences preferences = weatherDefinition.GameSettingsPreferences.First((WeatherDefinition.Preferences pref) => pref.SeasonType == currentSeasonType && pref.GameDifficulty == this.weatherDifficulty);
        if (preferences == null)
        {
            Diagnostics.LogWarning("No preferences were found corresponding to season type and game difficulty");
            return;
        }
        float num = preferences.Threshold;

        WeatherDefinition.Preferences.PreferencesOverride[] overrides = preferences.Overrides;
        if (overrides != null && overrides.Length > 0)
        {
            string seasonIntensityName = this.seasonService.GetSeasonIntensityName();
            if (!string.IsNullOrEmpty(seasonIntensityName))
            {
                num *= this.GetWeatherThresholdMultiplier(preferences, seasonIntensityName);
            }
        }
        if (num > 1f || preferences.Priority <= 0f)
        {
            return;
        }
        NoiseHelper.BufferGenerationData bufferGenerationData = preferences.BufferGenerationData;
        NoiseHelper.ApplyRandomOffsetToBufferGenerationData(seed, ref bufferGenerationData);
        Vector2 mapSize = new Vector2((float)this.weatherMap.Width, (float)this.weatherMap.Height);

        for (int i = 0; i < this.weatherMap.Height; i++)
        {
            for (int j = 0; j < this.weatherMap.Width; j++)
            {
                Vector2 uv   = new Vector2((float)j / mapSize.x, (float)i / mapSize.y);
                float   num2 = NoiseHelper.GetNoiseCyclicMap(uv, bufferGenerationData, mapSize);
                if (num2 >= num)
                {
                    num2 *= preferences.Priority;
                    if (weatherDefinition.AffectedByWind)
                    {
                        if (num2 > this.tempData.GetValue(i, j))
                        {
                            this.tempData.SetValue(i, j, num2);
                            this.weatherMap.SetValue(i, j, (byte)weatherDefinition.Value);
                        }
                    }
                    else if (num2 > this.staticTempData.GetValue(i, j))
                    {
                        this.staticTempData.SetValue(i, j, num2);
                        this.staticWeatherMap.SetValue(i, j, (byte)weatherDefinition.Value);
                    }
                }
            }
        }
    }
        public override void Render(IList <SceneNode> nodes, RenderContext context, RenderOrder order)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            int numberOfNodes = nodes.Count;

            if (numberOfNodes == 0)
            {
                return;
            }

            context.Validate(_effect);
            context.ThrowIfCameraMissing();

            var graphicsDevice   = _effect.GraphicsDevice;
            var savedRenderState = new RenderStateSnapshot(graphicsDevice);

            graphicsDevice.DepthStencilState = DepthStencilState.None;
            graphicsDevice.RasterizerState   = RasterizerState.CullNone;

            // Set camera properties.
            var    cameraNode  = context.CameraNode;
            var    cameraPose  = cameraNode.PoseWorld;
            Matrix viewInverse = cameraPose;

            _parameterViewInverse.SetValue(viewInverse);
            _parameterGBuffer0.SetValue(context.GBuffer0);

            Viewport viewport = context.Viewport;

            _parameterParameters0.SetValue(new Vector2(viewport.Width, viewport.Height));

            // Set jitter map.
            if (_jitterMap == null)
            {
                _jitterMap = NoiseHelper.GetGrainTexture(context.GraphicsService, NoiseHelper.DefaultJitterMapWidth);
            }

            _parameterJitterMap.SetValue(_jitterMap);

            float cameraFar = context.CameraNode.Camera.Projection.Far;

            for (int i = 0; i < numberOfNodes; i++)
            {
                var lightNode = nodes[i] as LightNode;
                if (lightNode == null)
                {
                    continue;
                }

                var shadow = lightNode.Shadow as CascadedShadow;
                if (shadow == null)
                {
                    continue;
                }

                if (shadow.ShadowMap == null || shadow.ShadowMask == null)
                {
                    continue;
                }

                // The effect must only render in a specific channel.
                // Do not change blend state if the correct write channels is already set, e.g. if this
                // shadow is part of a CompositeShadow, the correct blend state is already set.
                if ((int)graphicsDevice.BlendState.ColorWriteChannels != (1 << shadow.ShadowMaskChannel))
                {
                    graphicsDevice.BlendState = GraphicsHelper.BlendStateWriteSingleChannel[shadow.ShadowMaskChannel];
                }

                _parameterParameters1.SetValue(new Vector4(
                                                   shadow.FadeOutRange,
                                                   shadow.Distances[shadow.NumberOfCascades - 1],
                                                   shadow.VisualizeCascades ? 1 : 0,
                                                   shadow.ShadowFog));

                float filterRadius = shadow.FilterRadius;

                // If we use a subset of the Poisson kernel, we have to normalize the scale.
                int numberOfSamples = Math.Min(shadow.NumberOfSamples, StandardShadowMaskRenderer.PoissonKernel.Length);

                // Not all shader passes support cascade visualization. Use a similar pass instead.
                if (shadow.VisualizeCascades)
                {
                    if (numberOfSamples < 0)
                    {
                        numberOfSamples = 4;
                    }
                    else if (numberOfSamples == 0)
                    {
                        numberOfSamples = 1;
                        filterRadius    = 0;
                    }
                }

                // The best dithered CSM supports max 22 samples.
                if (shadow.CascadeSelection == ShadowCascadeSelection.BestDithered && numberOfSamples > 22)
                {
                    numberOfSamples = 22;
                }

                if (numberOfSamples > 0)
                {
                    filterRadius /= StandardShadowMaskRenderer.PoissonKernel[numberOfSamples - 1].Length();
                }

                _parameterParameters2.SetValue(new Vector4(
                                                   shadow.ShadowMap.Width,
                                                   shadow.ShadowMap.Height,
                                                   filterRadius,
                                                   // The StandardShadow.JitterResolution is the number of texels per world unit.
                                                   // In the shader the parameter JitterResolution contains the division by the jitter map size.
                                                   shadow.JitterResolution / _jitterMap.Width));

                // Split distances.
                if (_parameterDistances != null)
                {
                    // Set not used entries to large values.
                    Vector4 distances = shadow.Distances;
                    for (int j = shadow.NumberOfCascades; j < 4; j++)
                    {
                        distances[j] = 10 * cameraFar;
                    }

                    _parameterDistances.SetValue((Vector4)distances);
                }

                Debug.Assert(shadow.ViewProjections.Length == 4);
                for (int j = 0; j < _matrices.Length; j++)
                {
                    _matrices[j] = viewInverse * shadow.ViewProjections[j];
                }

                _parameterShadowMatrices.SetValue(_matrices);

                _parameterDepthBias.SetValue((Vector4)shadow.EffectiveDepthBias);
                _parameterNormalOffset.SetValue((Vector4)shadow.EffectiveNormalOffset);

                Vector3 lightBackwardWorld = lightNode.PoseWorld.Orientation.GetColumn(2);
                _parameterLightDirection.SetValue((Vector3)cameraPose.ToLocalDirection(lightBackwardWorld));
                _parameterNumberOfCascades.SetValue(shadow.NumberOfCascades);
                _parameterShadowMap.SetValue(shadow.ShadowMap);

                var      rectangle           = GraphicsHelper.GetViewportRectangle(cameraNode, viewport, lightNode);
                Vector2F texCoordTopLeft     = new Vector2F(rectangle.Left / (float)viewport.Width, rectangle.Top / (float)viewport.Height);
                Vector2F texCoordBottomRight = new Vector2F(rectangle.Right / (float)viewport.Width, rectangle.Bottom / (float)viewport.Height);
                GraphicsHelper.GetFrustumFarCorners(cameraNode.Camera.Projection, texCoordTopLeft, texCoordBottomRight, _frustumFarCorners);
                _parameterFrustumCorners.SetValue(_frustumFarCorners);

                var pass = GetPass(numberOfSamples, shadow.CascadeSelection, shadow.VisualizeCascades);

                if (numberOfSamples > 0)
                {
                    if (_lastNumberOfSamples != numberOfSamples)
                    {
                        // Create an array with the first n samples and the rest set to 0.
                        _lastNumberOfSamples = numberOfSamples;
                        for (int j = 0; j < numberOfSamples; j++)
                        {
                            _samples[j].Y = StandardShadowMaskRenderer.PoissonKernel[j].Y;
                            _samples[j].X = StandardShadowMaskRenderer.PoissonKernel[j].X;
                            _samples[j].Z = 1.0f / numberOfSamples;
                        }

                        // Set the rest to zero.
                        for (int j = numberOfSamples; j < _samples.Length; j++)
                        {
                            _samples[j] = Vector3.Zero;
                        }

                        _parameterSamples.SetValue(_samples);
                    }
                    else if (i == 0)
                    {
                        // Apply offsets in the first loop.
                        _parameterSamples.SetValue(_samples);
                    }
                }

                pass.Apply();

                graphicsDevice.DrawQuad(rectangle);
            }

            _parameterGBuffer0.SetValue((Texture2D)null);
            _parameterJitterMap.SetValue((Texture2D)null);
            _parameterShadowMap.SetValue((Texture2D)null);
            savedRenderState.Restore();
        }