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(); } }
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); } } }