ガウシアン ブラー。
Inheritance: IDisposable
Example #1
0
        void HandleInput(GameTime gameTime)
        {
            float time = (float) gameTime.ElapsedGameTime.TotalMilliseconds;

            lastKeyboardState = currentKeyboardState;
            lastGamePadState = currentGamePadState;

            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);

            rotateDude += currentGamePadState.Triggers.Right * time * 0.2f;
            rotateDude -= currentGamePadState.Triggers.Left * time * 0.2f;

            if (currentKeyboardState.IsKeyDown(Keys.Q))
                rotateDude -= time * 0.2f;
            if (currentKeyboardState.IsKeyDown(Keys.E))
                rotateDude += time * 0.2f;

            if (currentKeyboardState.IsKeyUp(Keys.B) && lastKeyboardState.IsKeyDown(Keys.B) ||
                currentGamePadState.IsButtonUp(Buttons.B) && lastGamePadState.IsButtonDown(Buttons.B))
            {
                currentLightCameraType++;

                if (LightCameraType.Basic < currentLightCameraType)
                    currentLightCameraType = LightCameraType.LiSPSM;
            }

            if (currentKeyboardState.IsKeyUp(Keys.Y) && lastKeyboardState.IsKeyDown(Keys.Y) ||
                currentGamePadState.IsButtonUp(Buttons.Y) && lastGamePadState.IsButtonDown(Buttons.Y))
            {
                useCameraFrustumSceneBox = !useCameraFrustumSceneBox;
            }

            if (currentKeyboardState.IsKeyUp(Keys.X) && lastKeyboardState.IsKeyDown(Keys.X) ||
                currentGamePadState.IsButtonUp(Buttons.X) && lastGamePadState.IsButtonDown(Buttons.X))
            {
                if (shadowMapForm == ShadowMapForm.Basic)
                {
                    shadowMapForm = ShadowMapForm.Variance;
                }
                else
                {
                    shadowMapForm = ShadowMapForm.Basic;
                }
            }

            if (currentKeyboardState.IsKeyUp(Keys.K) && lastKeyboardState.IsKeyDown(Keys.K) ||
                currentGamePadState.IsButtonUp(Buttons.RightShoulder) && lastGamePadState.IsButtonDown(Buttons.RightShoulder))
            {
                splitCount++;
                if (MaxSplitCount < splitCount)
                    splitCount = 1;
            }

            if (currentKeyboardState.IsKeyUp(Keys.L) && lastKeyboardState.IsKeyDown(Keys.L) ||
                currentGamePadState.IsButtonUp(Buttons.LeftShoulder) && lastGamePadState.IsButtonDown(Buttons.LeftShoulder))
            {
                currentShadowMapSizeIndex++;
                if (ShadowMapSizes.Length <= currentShadowMapSizeIndex)
                    currentShadowMapSizeIndex = 0;

                if (gaussianBlur != null)
                {
                    gaussianBlur.Dispose();
                    gaussianBlur = null;
                }
            }

            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
                currentGamePadState.Buttons.Back == ButtonState.Pressed)
            {
                Exit();
            }
        }
Example #2
0
        void CreateShadowMap()
        {
            // デュード モデルのワールド行列。
            world = Matrix.CreateRotationY(MathHelper.ToRadians(rotateDude));

            dudeBoxLocal.GetCorners(corners);
            dudeBoxWorld = BoundingBoxHelper.Empty;
            foreach (var corner in corners)
            {
                Vector3 cornerLocal = corner;
                Vector3 cornerWorld;
                Vector3.Transform(ref cornerLocal, ref world, out cornerWorld);

                BoundingBoxHelper.Merge(ref dudeBoxWorld, ref cornerWorld);
            }

            // ライト カメラへ指定するシーン領域。
            BoundingBox actualSceneBox;
            if (useCameraFrustumSceneBox)
            {
                // 視錐台全体とする場合。
                cameraFrustum.Matrix = camera.View * camera.Projection;
                cameraFrustum.GetCorners(corners);
                actualSceneBox = BoundingBox.CreateFromPoints(corners);

            }
            else
            {
                // 明示する場合。
                actualSceneBox = sceneBox;
                BoundingBoxHelper.Merge(ref actualSceneBox, camera.Position);
            }

            // 表示カメラの分割。
            // デフォルトのラムダ値 0.5f ではカメラ手前が少し狭すぎるか?
            // ここは表示カメラの far の値に応じて調整する。
            pssm.Count = splitCount;
            pssm.Lambda = 0.4f;
            pssm.View = camera.View;
            pssm.SceneBox = actualSceneBox;
            pssm.Split(splitDistances, splitProjections);

            // 使用するライト カメラ ビルダの選択。
            LightCameraBuilder currentLightCameraBuilder;
            switch (currentLightCameraType)
            {
                case LightCameraType.LiSPSM:
                    currentLightCameraBuilder = liSPSMLightCameraBuilder;
                    break;
                case LightCameraType.Uniform:
                    currentLightCameraBuilder = uniformLightCameraBuilder;
                    break;
                default:
                    currentLightCameraBuilder = basicLightCameraBuilder;
                    break;
            }

            // 各分割で共通のビルダ プロパティを設定。
            currentLightCameraBuilder.EyeView = camera.View;
            currentLightCameraBuilder.LightDirection = lightDirection;
            currentLightCameraBuilder.SceneBox = sceneBox;

            for (int i = 0; i < splitCount; i++)
            {
                // 射影行列は分割毎に異なる。
                currentLightCameraBuilder.EyeProjection = splitProjections[i];

                // ライトのビューおよび射影行列の算出。
                Matrix lightView;
                Matrix lightProjection;
                currentLightCameraBuilder.Build(out lightView, out lightProjection);

                // 後のモデル描画用にライト空間行列を算出。
                Matrix.Multiply(ref lightView, ref lightProjection, out lightViewProjections[i]);

                // シャドウ マップを描画。
                shadowMaps[i].Form = shadowMapForm;
                shadowMaps[i].Size = ShadowMapSizes[currentShadowMapSizeIndex];
                shadowMaps[i].Draw(camera.View, splitProjections[i], lightView, lightProjection, DrawShadowCasters);

                // VSM の場合は生成したシャドウ マップへブラーを適用。
                if (shadowMapForm == ShadowMapForm.Variance)
                {
                    if (gaussianBlur == null)
                    {
                        var shadowMapSize = ShadowMapSizes[currentShadowMapSizeIndex];
                        gaussianBlur = new GaussianBlur(
                            GraphicsDevice, shadowMapSize, shadowMapSize, SurfaceFormat.Vector2, gaussianBlurEffect);
                        gaussianBlur.Radius = 7;
                        gaussianBlur.Amount = 7;
                    }

                    gaussianBlur.Filter(shadowMaps[i].RenderTarget, shadowMaps[i].RenderTarget);
                }
            }
        }