Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Graphics.PackedVector;
- using nulltech.Cameras;
- using nulltech.Services;
- namespace nulltech.Illumination.AO
- {
- public abstract class AmbientOcclusion
- {
- private const int RandomTextureSize = 64;
- protected readonly VertexPositionTexture[] Vertices = new VertexPositionTexture[4];
- private readonly Vector3[] _cornersViewSpace = new Vector3[8];
- private readonly Vector3[] _cornersWorldSpace = new Vector3[8];
- private readonly Vector3[] _currentFrustumCorners = new Vector3[4];
- private readonly BoundingFrustum _frustum = new BoundingFrustum(Matrix.Identity);
- protected Effect AOEffect;
- private EffectParameter _cornerParam;
- private EffectParameter _farParam;
- private EffectParameter _inverseViewportParam;
- private EffectParameter _randomTextureParam;
- private EffectParameter _rayParam;
- private Texture2D _randomTexture;
- protected AmbientOcclusion(EngineServices services)
- {
- GraphicsDevice = services.GraphicsDevice;
- Content = services.ContentManager;
- GenerateQuad();
- GenerateRandomTexture();
- }
- public ContentManager Content { get; private set; }
- public GraphicsDevice GraphicsDevice { get; private set; }
- public abstract void Calculate(CameraEntity camera);
- public abstract void Draw(CameraEntity camera);
- private void GenerateRandomTexture()
- {
- _randomTexture = new Texture2D(GraphicsDevice, RandomTextureSize, RandomTextureSize, false,
- SurfaceFormat.HalfVector2);
- var rand = new Random();
- var samples = new HalfVector2[RandomTextureSize * RandomTextureSize];
- for (int i = 0; i < RandomTextureSize * RandomTextureSize; i++)
- {
- Vector2 sVec = Vector2.Zero;
- sVec.X = (float)((rand.NextDouble() - .5) * 2.0);
- sVec.Y = (float)((rand.NextDouble() - .5) * 2.0);
- sVec.Normalize();
- samples[i] = new HalfVector2(sVec);
- }
- _randomTexture.SetData(samples);
- }
- protected void GenerateQuad()
- {
- Vertices[0].Position = new Vector3(-1, 1, 1);
- Vertices[1].Position = new Vector3(1, 1, 1);
- Vertices[2].Position = new Vector3(-1, -1, 1);
- Vertices[3].Position = new Vector3(1, -1, 1);
- Vertices[0].TextureCoordinate = new Vector2(0, 0);
- Vertices[1].TextureCoordinate = new Vector2(1, 0);
- Vertices[2].TextureCoordinate = new Vector2(0, 1);
- Vertices[3].TextureCoordinate = new Vector2(1, 1);
- }
- protected void GenerateCorners(CameraEntity camera)
- {
- _inverseViewportParam.SetValue(camera.InverseViewport);
- _farParam.SetValue(camera.ProjectionController.Far);
- _frustum.Matrix = camera.ViewProjection;
- _frustum.GetCorners(_cornersWorldSpace);
- Matrix matView = camera.View;
- Vector3.Transform(_cornersWorldSpace, ref matView, _cornersViewSpace);
- for (int i = 0; i < 4; i++) //take only the 4 farthest points
- {
- _currentFrustumCorners[i] = _cornersViewSpace[i + 4];
- }
- Vector3 temp = _currentFrustumCorners[3];
- _currentFrustumCorners[3] = _currentFrustumCorners[2];
- _currentFrustumCorners[2] = temp;
- _cornerParam.SetValue(_currentFrustumCorners);
- _rayParam.SetValue(_currentFrustumCorners[1]);
- }
- protected virtual void ProcessEffect()
- {
- _inverseViewportParam = AOEffect.Parameters["InverseViewportDimensions"];
- _cornerParam = AOEffect.Parameters["FrustumCorners"];
- _rayParam = AOEffect.Parameters["FrustumRay"];
- _farParam = AOEffect.Parameters["Far"];
- _randomTextureParam = AOEffect.Parameters["RandomTexture"];
- _randomTextureParam.SetValue(_randomTexture);
- }
- }
- }
Add Comment
Please, Sign In to add comment