void Filter(IPostProcessorContext context) { Instrument.Begin(InstrumentFilter); if (blur != null) { blur.Filter(shadowSceneMap); } //---------------------------------------------------------------- // エフェクト shadowColorParameter.SetValue(shadowColor); shadowSceneMapParameter.SetValue(shadowSceneMap); //---------------------------------------------------------------- // 描画 GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, sssmEffect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
/// <summary> /// アクティブ化の完了を検査します。 /// </summary> void CheckActivations() { Instrument.Begin(InstrumentCheckActivations); Partition partition; while (activatedPartitions.TryDequeue(out partition)) { Partition removedPartition; if (!activatingParitions.TryRemove(partition.Position, out removedPartition)) { continue; } // アクティブ リストへ追加。 clusterManager.AddPartition(partition); partitions.Enqueue(partition); // 完了を通知。 partition.OnActivated(); // 隣接パーティションへ通知。 NotifyNeighborActivated(partition); // サブクラスへも通知。 OnActivated(partition); } Instrument.End(); }
void Filter(IPostProcessorContext context) { Instrument.Begin(InstrumentFilter); //---------------------------------------------------------------- // エフェクト edgeEffect.EdgeWidth = EdgeWidth; edgeEffect.EdgeIntensity = EdgeIntensity; edgeEffect.NormalThreshold = NormalThreshold; edgeEffect.DepthThreshold = DepthThreshold; edgeEffect.NormalSensitivity = NormalSensitivity; edgeEffect.DepthSensitivity = DepthSensitivity; edgeEffect.EdgeColor = EdgeColor; edgeEffect.NormalDepthMap = normalDepthMap; //---------------------------------------------------------------- // 描画 GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, edgeEffect.Effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
/// <summary> /// パーティションの非アクティブ化を試行します。 /// 非アクティブ化すべきと判定されたパーティションは、 /// 非アクティブ化中リストへ追加され、 /// 非同期に非アクティブ化を実行するためのタスク キューへ追加されます。 /// なお、同時に非アクティブ化可能なパーティションの数には上限があり、 /// 上限に到達した場合には、このフレームでの非アクティブ化は保留されます。 /// </summary> void Passivate() { Instrument.Begin(InstrumentPassivate); // メモ // // 非アクティブ化はパーティションのロックを伴う。 // このため、非アクティブ化判定そのものを非同期化することは難しい。 int count = Math.Min(partitions.Count, passivationSearchCapacity); for (int i = 0; i < count; i++) { // 同時実行数を越えるならば終了。 if (passivationCapacity <= passivatingPartitions.Count) { break; } var partition = partitions.Dequeue(); if (!Closing) { if (maxActiveVolume.Contains(eyePositionPartition, partition.Position)) { // アクティブ状態維持領域内ならばリストへ戻す。 partitions.Enqueue(partition); continue; } } // 非アクティブ化中としてマーク。 passivatingPartitions[partition.Position] = partition; // アクティブではない状態にする。 clusterManager.RemovePartition(partition.Position); // ※重要※ // // 描画で利用するオブジェクトが非同期に無効化されないように、 // 八分木ノードや頂点バッファなどを非アクティブ化の開始直前で開放しておく。 // これは、描画メソッドの呼び出しスレッドと同じスレッドで行わなければならない。 // 開始を通知。 // // 注意! // このメソッドのスレッドと同じであることを前提に、 // パーティションのアクティブ状態を監視するクラスもあるため、 // 処理を変更する場合には注意すること。 partition.OnPassivating(); // サブクラスへも通知。 OnPassivating(partition); // タスク実行。 ThreadPool.QueueUserWorkItem(passivatePartitionAction, partition); } Instrument.End(); }
void DrawShadowMap() { Instrument.Begin(InstrumentDrawShadowMap); //---------------------------------------------------------------- // 準備 ShadowMap.Prepare(activeCamera); //---------------------------------------------------------------- // 投影オブジェクトを収集 for (int i = 0; i < shadowCasters.Count; i++) { ShadowMap.TryAddShadowCaster(shadowCasters[i]); } //---------------------------------------------------------------- // シャドウ マップを描画 var lightDirection = activeDirectionalLight.Direction; ShadowMap.Draw(ref lightDirection); Instrument.End(); }
void Filter(IPostProcessorContext context) { Instrument.Begin(InstrumentFilter); //================================================================ // シーンにブラーを適用 blur.Filter(context.Source, bluredSceneMap); //================================================================ // シーンとブラー済みシーンを深度マップに基いて合成 //---------------------------------------------------------------- // エフェクト var distance = internalCamera.Projection.FarPlaneDistance - internalCamera.Projection.NearPlaneDistance; dofEffect.NearPlaneDistance = internalCamera.Projection.NearPlaneDistance; dofEffect.FarPlaneDistance = internalCamera.Projection.FarPlaneDistance / distance; dofEffect.FocusDistance = internalCamera.FocusDistance; dofEffect.FocusRange = internalCamera.FocusRange; dofEffect.DepthMap = depthMap; dofEffect.BluredSceneMap = bluredSceneMap; //---------------------------------------------------------------- // 描画 GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, dofEffect.Effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); DrawShadowScene(context); Filter(context); TextureDisplay.Add(shadowSceneMap); Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); DrawNormalDepth(context); Filter(context); TextureDisplay.Add(normalDepthMap); Instrument.End(); }
public void Update(GameTime gameTime) { Instrument.Begin(InstrumentUpdate); //---------------------------------------------------------------- // シーン設定 SceneSettings.Update(gameTime); //---------------------------------------------------------------- // 降雪パーティクル // TODO if (snowParticleSystem.Enabled) { int boundsX = 128 * 2; int boundsZ = 128 * 2; int minY = 32; int maxY = 64; for (int i = 0; i < 40; i++) { var randomX = random.Next(boundsX) - boundsX / 2; var randomY = random.Next(maxY - minY) + minY; var randomZ = random.Next(boundsZ) - boundsZ / 2; var position = new Vector3(randomX, randomY, randomZ) + sceneManager.ActiveCamera.View.Position; snowParticleSystem.AddParticle(position, Vector3.Zero); } } //---------------------------------------------------------------- // 降雨パーティクル // TODO if (rainParticleSystem.Enabled) { int boundsX = 128 * 2; int boundsZ = 128 * 2; int minY = 32; int maxY = 64; for (int i = 0; i < 80; i++) { var randomX = random.Next(boundsX) - boundsX / 2; var randomY = random.Next(maxY - minY) + minY; var randomZ = random.Next(boundsZ) - boundsZ / 2; var position = new Vector3(randomX, randomY, randomZ) + sceneManager.ActiveCamera.View.Position; rainParticleSystem.AddParticle(position, Vector3.Zero); } } Instrument.End(); }
public void Update(GameTime gameTime) { Instrument.Begin(InstrumentUpdate); //---------------------------------------------------------------- // カメラ更新 SceneManager.ActiveCamera.Update(); //---------------------------------------------------------------- // シーン設定 SceneSettings.Update(gameTime); SceneManager.AmbientLightColor = SceneSettings.CurrentAmbientLightColor; if (SceneSettings.Sunlight.Enabled && SceneSettings.SunAboveHorizon) { SceneManager.ActiveDirectionalLightName = SceneSettings.Sunlight.Name; } else if (SceneSettings.Moonlight.Enabled && SceneSettings.MoonAboveHorizon) { SceneManager.ActiveDirectionalLightName = SceneSettings.Moonlight.Name; } else { SceneManager.ActiveDirectionalLightName = null; } if (SceneSettings.FogEnabled) { var currentFarPlaneDistance = SceneManager.ActiveCamera.Projection.FarPlaneDistance; SceneManager.FogStart = currentFarPlaneDistance * SceneSettings.FogStartScale; SceneManager.FogEnd = currentFarPlaneDistance * SceneSettings.FogEndScale; SceneManager.FogColor = SceneSettings.CurrentSkyColor; } SceneManager.FogEnabled = SceneSettings.FogEnabled; // 太陽が見える場合にのみレンズ フレアを描画。 LensFlare.Enabled = SceneSettings.SunAboveHorizon; //---------------------------------------------------------------- // チャンク マネージャ ChunkManager.Update(SceneManager.ActiveCamera.View.Matrix, SceneManager.ActiveCamera.Projection.Matrix); //---------------------------------------------------------------- // リージョン マネージャ RegionManager.Update(gameTime); Instrument.End(); }
void DrawNormalDepth(IPostProcessorContext context) { Instrument.Begin(InstrumentDrawNormalDepth); var viewerCamera = context.ActiveCamera; //---------------------------------------------------------------- // 内部カメラの準備 internalCamera.View.Position = viewerCamera.View.Position; internalCamera.View.Direction = viewerCamera.View.Direction; internalCamera.View.Up = viewerCamera.View.Up; internalCamera.Projection.Fov = viewerCamera.Projection.Fov; internalCamera.Projection.AspectRatio = viewerCamera.Projection.AspectRatio; internalCamera.Projection.NearPlaneDistance = viewerCamera.Projection.NearPlaneDistance; internalCamera.Projection.FarPlaneDistance = FarPlaneDistance; internalCamera.Update(); internalCamera.Frustum.GetCorners(frustumCorners); frustumSphere = BoundingSphere.CreateFromPoints(frustumCorners); //---------------------------------------------------------------- // エフェクト normalDepthMapEffect.View = internalCamera.View.Matrix; normalDepthMapEffect.Projection = internalCamera.Projection.Matrix; //---------------------------------------------------------------- // 描画 GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.SetRenderTarget(normalDepthMap); GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.White, 1.0f, 0); // 不透明オブジェクトのみ対象。 for (int i = 0; i < context.OpaqueObjects.Count; i++) { var opaque = context.OpaqueObjects[i]; // 専用カメラの視錐台に含まれるもののみを描画。 if (IsVisibleObject(opaque)) { opaque.Draw(normalDepthMapEffect); } } GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.Draw(fillTexture, context.Destination.Bounds, Color); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); monochromeEffect.Cb = cbCr.X; monochromeEffect.Cr = cbCr.Y; GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, monochromeEffect.Effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
protected override void Draw(GameTime gameTime) { // モニタ Instrument.Begin(InstrumentDraw); // ワールドの描画 worldManager.Draw(gameTime); // ヘルプ ウィンドウの描画 DrawHelp(); // モニタ Instrument.End(); base.Draw(gameTime); }
void PostProcess() { Instrument.Begin(InstrumentPostProcess); for (int i = 0; i < PostProcessors.Count; i++) { var postProcessor = PostProcessors[i]; if (postProcessor.Enabled) { postProcessor.Process(postProcessorContext); SwapRenderTargets(); } } Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); var height = context.Destination.Height; density.SetValue(height * MathHelper.PiOver2); brightness.SetValue(Brightness); GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
void DrawParticles(GameTime gameTime) { Instrument.Begin(InstrumentDrawParticles); GraphicsDevice.SetRenderTarget(RenderTarget); for (int i = 0; i < ParticleSystems.Count; i++) { var particleSystem = ParticleSystems[i]; if (particleSystem.Enabled) { particleSystem.Draw(gameTime, activeCamera); } } GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
void Filter(IPostProcessorContext context) { Instrument.Begin(InstrumentFilter); //---------------------------------------------------------------- // エフェクト ssaoEffect.SsaoMap = ssaoMap; //---------------------------------------------------------------- // 描画 GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, ssaoEffect.Effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
void DrawShadowScene(IPostProcessorContext context) { Instrument.Begin(InstrumentDrawShadowScene); var camera = context.ActiveCamera; var shadowMap = context.ShadowMap; //---------------------------------------------------------------- // エフェクト shadowSceneEffect.View = camera.View.Matrix; shadowSceneEffect.Projection = camera.Projection.Matrix; shadowSceneEffect.SplitDistances = shadowMap.SplitDistances; shadowSceneEffect.SplitLightViewProjections = shadowMap.SplitLightViewProjections; shadowSceneEffect.SplitShadowMaps = shadowMap.SplitShadowMaps; //---------------------------------------------------------------- // 描画 GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.SetRenderTarget(shadowSceneMap); GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.White, 1.0f, 0); for (int i = 0; i < context.OpaqueObjects.Count; i++) { var opaque = context.OpaqueObjects[i]; opaque.Draw(shadowSceneEffect); } for (int i = 0; i < context.TranslucentObjects.Count; i++) { var translucent = context.TranslucentObjects[i]; translucent.Draw(shadowSceneEffect); } GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
/// <summary> /// 非アクティブ化の完了を検査します。 /// </summary> void CheckPassivations() { Instrument.Begin(InstrumentCheckPassivations); Partition partition; while (passivatedPartitions.TryDequeue(out partition)) { Partition removedPartition; if (!passivatingPartitions.TryRemove(partition.Position, out removedPartition)) { continue; } // 隣接パーティションへ通知。 NortifyNeighborPassivated(partition); // サブクラスへも通知。 OnPassivated(partition); } Instrument.End(); }
public override void Process(IPostProcessorContext context) { Instrument.Begin(InstrumentProcess); //---------------------------------------------------------------- // ブルーム エクストラクト マップ bloomExtractEffect.Threshold = Threshold; GraphicsDevice.SetRenderTarget(bloomExtractMap); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, bloomExtractEffect.Effect); SpriteBatch.Draw(context.Source, bloomExtractMap.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); //---------------------------------------------------------------- // ブルーム エクストラクト マップへブラーを適用 blur.Filter(bloomExtractMap); //---------------------------------------------------------------- // ブルーム bloomEffect.BloomIntensity = BloomIntensity; bloomEffect.BaseIntensity = BaseIntensity; bloomEffect.BloomSaturation = BloomSaturation; bloomEffect.BaseSaturation = BaseSaturation; bloomEffect.BloomExtractMap = bloomExtractMap; GraphicsDevice.SetRenderTarget(context.Destination); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, bloomEffect.Effect); SpriteBatch.Draw(context.Source, context.Destination.Bounds, Color.White); SpriteBatch.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }
public void Draw(GameTime gameTime) { if (gameTime == null) { throw new ArgumentNullException("gameTime"); } if (activeCamera == null) { throw new InvalidOperationException("ActiveCamera is null."); } Instrument.Begin(InstrumentDraw); activeCamera.Frustum.GetCorners(frustumCorners); frustumSphere = BoundingSphere.CreateFromPoints(frustumCorners); // カウンタをリセット。 SceneObjectCount = 0; OccludedSceneObjectCount = 0; #if DEBUG || TRACE // デバッグ エフェクトへカメラ情報を設定。 debugBoxEffect.View = activeCamera.View.Matrix; debugBoxEffect.Projection = activeCamera.Projection.Matrix; #endif octreeManager.Execute(activeCamera.Frustum, collectObjectsAction); SceneObjectCount = opaqueObjects.Count + translucentObjects.Count; // 視点からの距離でソート。 DistanceComparer.Instance.EyePosition = activeCamera.View.Position; // TODO // 不透明オブジェクトのソートは除外して良いかも。 opaqueObjects.Sort(DistanceComparer.Instance); translucentObjects.Sort(DistanceComparer.Instance); //---------------------------------------------------------------- // シャドウ マップ shadowMapAvailable = false; if (ShadowMap != null && shadowCasters.Count != 0 && activeDirectionalLight != null && activeDirectionalLight.Enabled) { DrawShadowMap(); shadowMapAvailable = true; ShadowMapUpdated(this, EventArgs.Empty); } //---------------------------------------------------------------- // シーン if (shadowMapAvailable && !SssmEnabled) { DrawScene(ShadowMap); } else { DrawScene(null); } //---------------------------------------------------------------- // パーティクル if (0 < ParticleSystems.Count) { DrawParticles(gameTime); } //---------------------------------------------------------------- // ポスト プロセス PostProcess(); //---------------------------------------------------------------- // レンズ フレア if (LensFlare != null && LensFlare.Enabled) { DrawLensFlare(); } //---------------------------------------------------------------- // シーン オブジェクトの境界ボックスの描画 DebugDrawBoundingBoxes(); //---------------------------------------------------------------- // 後処理 // 分類リストを初期化。 opaqueObjects.Clear(); translucentObjects.Clear(); shadowCasters.Clear(); Instrument.End(); }
protected override void Update(GameTime gameTime) { // タイム ルーラの計測開始 timeRuler.StartFrame(); // これをしないとデバッグできない。 if (!IsActive) { return; } // モニタ Instrument.Begin(InstrumentUpdate); //---------------------------------------------------------------- // マウスとキーボード状態の取得 currentKeyboardState = Keyboard.GetState(); var mouseState = Mouse.GetState(); //---------------------------------------------------------------- // アプリケーション終了 // TODO if (!worldManager.ChunkManager.Closing && !worldManager.ChunkManager.Closed && currentKeyboardState.IsKeyDown(Keys.Escape)) { worldManager.ChunkManager.Close(); logger.Info("Wait until all chunks are passivated..."); } if (worldManager.ChunkManager.Closed) { Exit(); } //---------------------------------------------------------------- // ビューの操作 viewInput.Update(gameTime, worldManager.SceneManager.ActiveCamera.View); if (currentKeyboardState.IsKeyDown(Keys.PageUp)) { viewInput.MoveVelocity += 10; } if (currentKeyboardState.IsKeyDown(Keys.PageDown)) { viewInput.MoveVelocity -= 10; if (viewInput.MoveVelocity < 10) { viewInput.MoveVelocity = 10; } } //---------------------------------------------------------------- // ワールドの更新 worldManager.Update(gameTime); //---------------------------------------------------------------- // ブラシ マネージャ // 右ボタン押下でペイント モードの開始。 if (mouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released) { brushManager.StartPaintMode(); } // 右ボタン解放でペイント モードの終了。 if (mouseState.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed) { brushManager.EndPaintMode(); } // ブラシ マネージャを更新。 // 内部でブラシの位置が決定される。 brushManager.Update(); // 左ボタンでブロック消去。 // ブロック消去は消去対象の判定との兼ね合いから、 // ボタンの押下から解放を行った時にだけ実行。 if (mouseState.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed && mouseState.RightButton == ButtonState.Released) { brushManager.Erase(); } // 右ボタン押下でペイント。 if (mouseState.RightButton == ButtonState.Pressed && mouseState.LeftButton == ButtonState.Released) { brushManager.Paint(); } // Undo。 if (currentKeyboardState.IsKeyDown(Keys.LeftControl) && IsKeyPressed(Keys.Z)) { commandManager.RequestUndo(); } // Redo。 if (currentKeyboardState.IsKeyDown(Keys.LeftControl) && IsKeyPressed(Keys.Y)) { commandManager.RequestRedo(); } // マウス中ボタン押下でブラシのある位置のブロックを選択 (スポイト)。 // TODO // ホイール クリックが反応してくれない。 // 手の打ちようがないのでキー [O] で対応。 if ((mouseState.MiddleButton == ButtonState.Released && lastMouseState.MiddleButton == ButtonState.Pressed) || IsKeyPressed(Keys.O)) { brushManager.Pick(); } if (IsKeyPressed(Keys.D1)) { brushManager.SetBrush(brushManager.FreeBrush); } if (IsKeyPressed(Keys.D2)) { brushManager.SetBrush(brushManager.StickyBrush); } // コマンド実行。 commandManager.Update(); //---------------------------------------------------------------- // その他 // F1 if (IsKeyPressed(Keys.F1)) { helpVisible = !helpVisible; } // F2 if (IsKeyPressed(Keys.F2)) { SceneManager.DebugBoxVisible = !SceneManager.DebugBoxVisible; } // F3 if (IsKeyPressed(Keys.F3)) { RegionManager.Wireframe = !RegionManager.Wireframe; } // F4 if (IsKeyPressed(Keys.F4)) { worldManager.SceneSettings.FogEnabled = !worldManager.SceneSettings.FogEnabled; } // F5 if (IsKeyPressed(Keys.F5)) { textureDisplay.Visible = !textureDisplay.Visible; } // F6 if (IsKeyPressed(Keys.F6)) { timeRuler.Visible = !timeRuler.Visible; } //---------------------------------------------------------------- // マウスとキーボード状態の記録 lastKeyboardState = currentKeyboardState; lastMouseState = mouseState; base.Update(gameTime); // モニタ Instrument.End(); }
void DrawSsaoMap(IPostProcessorContext context) { Instrument.Begin(InstrumentDrawSsaoMap); var viewerCamera = context.ActiveCamera; //================================================================ // // 法線深度マップを描画 // //---------------------------------------------------------------- // 内部カメラの準備 internalCamera.View.Position = viewerCamera.View.Position; internalCamera.View.Direction = viewerCamera.View.Direction; internalCamera.View.Up = viewerCamera.View.Up; internalCamera.Projection.Fov = viewerCamera.Projection.Fov; internalCamera.Projection.AspectRatio = viewerCamera.Projection.AspectRatio; internalCamera.Projection.NearPlaneDistance = viewerCamera.Projection.NearPlaneDistance; // TODO // 状況に応じて FarPlaneDistance を変化させられるように。 //internalCamera.Projection.FarPlaneDistance = viewerCamera.Projection.FarPlaneDistance; internalCamera.Projection.FarPlaneDistance = 32; internalCamera.Update(); internalCamera.Frustum.GetCorners(frustumCorners); frustumSphere = BoundingSphere.CreateFromPoints(frustumCorners); //---------------------------------------------------------------- // エフェクト normalDepthMapEffect.View = internalCamera.View.Matrix; normalDepthMapEffect.Projection = internalCamera.Projection.Matrix; //---------------------------------------------------------------- // 描画 GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.SetRenderTarget(normalDepthMap); GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.White, 1.0f, 0); // 不透明オブジェクトのみ対象。 for (int i = 0; i < context.OpaqueObjects.Count; i++) { var opaque = context.OpaqueObjects[i]; if (!(opaque is ShadowCaster)) { continue; } // 専用カメラの視錐台に含まれるもののみを描画。 if (IsVisibleObject(opaque)) { opaque.Draw(normalDepthMapEffect); } } GraphicsDevice.SetRenderTarget(null); //================================================================ // // SSAO マップを描画 // //---------------------------------------------------------------- // エフェクト var randomOffsetVector = viewerCamera.View.Position + viewerCamera.View.Direction; ssaoMapEffect.TotalStrength = TotalStrength; ssaoMapEffect.Strength = Strength; ssaoMapEffect.Falloff = Falloff; ssaoMapEffect.Radius = Radius; ssaoMapEffect.RandomOffset = randomOffsetVector.LengthSquared(); //---------------------------------------------------------------- // 描画 GraphicsDevice.SetRenderTarget(ssaoMap); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp, null, null, ssaoMapEffect.Effect); spriteBatch.Draw(normalDepthMap, ssaoMap.Bounds, Color.White); spriteBatch.End(); GraphicsDevice.SetRenderTarget(null); //================================================================ // // SSAO マップへブラーを適用 // // TODO for (int i = 0; i < 3; i++) { blur.Filter(ssaoMap, normalDepthMap); } Instrument.End(); }
/// <summary> /// パーティションのアクティブ化と非アクティブ化を行います。 /// </summary> /// <param name="eyePositionWorld">ワールド空間における視点の位置。</param> public void Update(Matrix view, Matrix projection) { if (Closed) { return; } Instrument.Begin(InstrumentUpdate); this.view = view; this.projection = projection; eyePositionWorld = View.GetPosition(view); eyePositionPartition.X = (int)Math.Floor(eyePositionWorld.X / PartitionSize.X); eyePositionPartition.Y = (int)Math.Floor(eyePositionWorld.Y / PartitionSize.Y); eyePositionPartition.Z = (int)Math.Floor(eyePositionWorld.Z / PartitionSize.Z); if (!Closing) { CheckPassivations(); CheckActivations(); Passivate(); // 開始前ならばアクティブ化候補探索スレッドを開始。 if (!activationCandidateFinder.Running) { activationCandidateFinder.Start(); } // アクティブ化候補探索スレッドのカメラ状態を更新。 activationCandidateFinder.UpdateCamera(view, projection, eyePositionWorld, eyePositionPartition); // サブクラスにおける追加の更新処理。 UpdateOverride(); } else { CheckPassivations(); CheckActivations(); Passivate(); // クローズが開始したらアクティブ化探索を停止。 if (activationCandidateFinder.Running) { activationCandidateFinder.Stop(); } // サブクラスにおける追加の更新処理。 // クローズ中に行うべきこともある。 UpdateOverride(); // 全ての非アクティブ化が完了していればクローズ完了。 if (activatingParitions.Count == 0 && passivatingPartitions.Count == 0 && partitions.Count == 0 && activatedPartitions.Count == 0 && passivatedPartitions.Count == 0) { Closing = false; Closed = true; OnClosed(); } } Instrument.End(); }
void DrawScene(ShadowMap shadowMap) { Instrument.Begin(InstrumentDrawScene); GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.SetRenderTarget(RenderTarget); GraphicsDevice.Clear(new Color(BackgroundColor)); //================================================================ // // オクルージョン クエリ // Instrument.Begin(InstrumentOcclusionQuery); GraphicsDevice.BlendState = colorWriteDisable; for (int i = 0; i < opaqueObjects.Count; i++) { opaqueObjects[i].UpdateOcclusion(); } //for (int i = 0; i < translucentObjects.Count; i++) // translucentObjects[i].UpdateOcclusion(); Instrument.End(); //================================================================ // // 描画 // Instrument.Begin(InstrumentDrawSceneObjects); //---------------------------------------------------------------- // 不透明オブジェクト GraphicsDevice.BlendState = BlendState.Opaque; for (int i = 0; i < opaqueObjects.Count; i++) { var opaque = opaqueObjects[i]; if (opaque.Occluded) { OccludedSceneObjectCount++; continue; } opaque.Draw(); } //---------------------------------------------------------------- // 半透明オブジェクト GraphicsDevice.BlendState = BlendState.AlphaBlend; for (int i = 0; i < translucentObjects.Count; i++) { var translucent = translucentObjects[i]; if (translucent.Occluded) { OccludedSceneObjectCount++; continue; } translucent.Draw(); } //---------------------------------------------------------------- // スカイ スフィア foreach (var obj in skySphereNode.Objects) { if (obj.Visible) { obj.Draw(); } } //if (skySphere != null && skySphere.Visible) // skySphere.Draw(); Instrument.End(); GraphicsDevice.SetRenderTarget(null); Instrument.End(); }