public void Prepare(ICamera viewerCamera) { if (viewerCamera == null) { throw new ArgumentNullException("viewerCamera"); } internalCamera.View.Position = viewerCamera.View.Position; internalCamera.View.Direction = viewerCamera.View.Direction; internalCamera.View.Up = viewerCamera.View.Up; //internalCamera.Projection.Fov = viewerCamera.Projection.Fov; // TODO internalCamera.Projection.Fov = MathHelper.PiOver4 / 2; internalCamera.Projection.AspectRatio = viewerCamera.Projection.AspectRatio; internalCamera.Projection.NearPlaneDistance = viewerCamera.Projection.NearPlaneDistance; internalCamera.Projection.FarPlaneDistance = settings.FarPlaneDistance; internalCamera.Update(); PrepareSplitCameras(); }
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(); }
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(); }