Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using nulltech.Cameras;
- using nulltech.Sampling;
- using nulltech.Services;
- using MathHelper = Microsoft.Xna.Framework.MathHelper;
- namespace nulltech.Illumination.AO
- {
- public class AlchemyAmbientOcclusion : AmbientOcclusion
- {
- private readonly Effect _blurEffect;
- private readonly EngineServices _services;
- private int _aoSampleCount = 12;
- private RenderTarget2D _aoTarget;
- private float _bias;
- private EffectParameter _biasParam;
- private float _blurDepthThreshold;
- private EffectParameter _blurDepthThresholdParam;
- private EffectParameter _blurInvertViewportParam;
- private Vector2[] _blurOffset;
- private EffectParameter _blurOffsetParam;
- private RenderTarget2D _blurPassTarget;
- private int _blurSampleCount = 25;
- private EffectParameter _blurWeightParam;
- private float _contrast;
- private EffectParameter _contrastParam;
- private float _intensityScale;
- private EffectParameter _intensityScaleParam;
- private EffectParameter _projConstParam;
- private float _radius;
- private EffectParameter _radiusParam;
- private float[] _sampleOffsets;
- private float[] _sampleWeights;
- private Vector2[] _samples;
- private EffectParameter _samplesParam;
- public AlchemyAmbientOcclusion(EngineServices services)
- : base(services)
- {
- _services = services;
- AOEffect = services.ContentManager.Load<Effect>(@"Effects\AO\AlchemyAO");
- _blurEffect = services.ContentManager.Load<Effect>(@"Effects\AO\BilateralBlur");
- ProcessEffect();
- CalculateSamples();
- Radius = 0.01f;
- Bias = 0.0018f;
- BlurRadius = .25f;
- IntensityScale = 13f;
- Contrast = 5f;
- BlurDepthThreshold = 0.02f;
- HalfResolution = false;
- GenerateRenderTargets();
- CalculateBlurSamples();
- }
- public bool HalfResolution { get; set; }
- public float Radius
- {
- get { return _radius; }
- set
- {
- _radius = value;
- _radiusParam.SetValue(value);
- }
- }
- public float BlurRadius { get; set; }
- public float BlurDepthThreshold
- {
- get { return _blurDepthThreshold; }
- set
- {
- _blurDepthThreshold = value;
- _blurDepthThresholdParam.SetValue(value);
- }
- }
- public float IntensityScale
- {
- get { return _intensityScale; }
- set
- {
- _intensityScale = value;
- _intensityScaleParam.SetValue(value);
- }
- }
- public float Contrast
- {
- get { return _contrast; }
- set
- {
- _contrast = value;
- _contrastParam.SetValue(value);
- }
- }
- public float Bias
- {
- get { return _bias; }
- set
- {
- _bias = value;
- _biasParam.SetValue(value);
- }
- }
- private void GenerateRenderTargets()
- {
- PresentationParameters pp = _services.GraphicsDevice.PresentationParameters;
- int width = pp.BackBufferWidth;
- int halfwidth = HalfResolution ? width/2 : width;
- int height = pp.BackBufferHeight;
- int halfheight = HalfResolution ? height/2 : height;
- _aoTarget = new RenderTarget2D(GraphicsDevice, halfwidth, halfheight, false, SurfaceFormat.Color,
- DepthFormat.None);
- _blurPassTarget = new RenderTarget2D(GraphicsDevice, width, height, false, SurfaceFormat.Color,
- DepthFormat.None);
- }
- private void CalculateBlurSamples()
- {
- _sampleWeights = new float[_blurSampleCount];
- _sampleOffsets = new float[_blurSampleCount];
- _blurOffset = new Vector2[_blurSampleCount];
- const float theta = 2f;
- _sampleWeights[0] = (float) ((1.0/Math.Sqrt(2*Math.PI*theta))*Math.Exp(-(0*(float) 0)/(2*theta*theta)));
- _sampleOffsets[0] = 0;
- float minweight = _sampleWeights[0];
- for (int i = 0; i < _blurSampleCount/2; i++)
- {
- float n = (i + 1);
- var weight = (float) ((1.0/Math.Sqrt(2*Math.PI*theta))*Math.Exp(-(n*n)/(2*theta*theta)));
- _sampleWeights[i*2 + 1] = weight;
- _sampleWeights[i*2 + 2] = weight;
- minweight = Math.Min(weight, minweight);
- float sampleOffset = i + 1.5f;
- _sampleOffsets[i*2 + 1] = sampleOffset;
- _sampleOffsets[i*2 + 2] = -sampleOffset;
- }
- for (int i = 0; i < _blurSampleCount; i++)
- {
- _sampleWeights[i] /= minweight;
- }
- _blurWeightParam.SetValue(_sampleWeights);
- }
- protected override sealed void ProcessEffect()
- {
- _samplesParam = AOEffect.Parameters["samples"];
- _aoSampleCount = _samplesParam.Elements.Count;
- _projConstParam = AOEffect.Parameters["projConst"];
- _intensityScaleParam = AOEffect.Parameters["intensityScale"];
- _contrastParam = AOEffect.Parameters["contrast"];
- _biasParam = AOEffect.Parameters["bias"];
- _radiusParam = AOEffect.Parameters["radius"];
- _blurWeightParam = _blurEffect.Parameters["blurWeights"];
- _blurOffsetParam = _blurEffect.Parameters["blurOffsets"];
- _blurSampleCount = _blurOffsetParam.Elements.Count;
- _blurDepthThresholdParam = _blurEffect.Parameters["BlurDepthThreshold"];
- _blurInvertViewportParam = _blurEffect.Parameters["InverseViewportDimensions"];
- base.ProcessEffect();
- }
- private void CalculateSamples()
- {
- _samples = new Vector2[_aoSampleCount];
- List<Vector2> samples = UniformPoissonDiskSampler.SampleCircle(_aoSampleCount, Vector2.Zero, 1.0f, .25f);
- for (int i = 0; i < _aoSampleCount; i++)
- {
- _samples[i] = samples[i];
- }
- _samplesParam.SetValue(_samples);
- }
- public override void Calculate(CameraEntity camera)
- {
- PresentationParameters pp = GraphicsDevice.PresentationParameters;
- float halffov = camera.ProjectionController.Fov*.5f;
- int ph = pp.BackBufferHeight;
- float ar = camera.ProjectionController.AspectRatio;
- var hftg = (float) Math.Tan(MathHelper.ToRadians(halffov/ar));
- float near = camera.ProjectionController.Near;
- _projConstParam.SetValue(ph/(2*hftg*near));
- GenerateCorners(camera);
- Vector2 ivp = camera.InverseViewport;
- _blurInvertViewportParam.SetValue(ivp);
- GraphicsDevice.SetRenderTarget(_aoTarget);
- AOEffect.CurrentTechnique.Passes[0].Apply();
- GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, Vertices, 0, 2);
- GraphicsDevice.SetRenderTarget(_blurPassTarget);
- for (int i = 0; i < _blurSampleCount; i++)
- {
- _blurOffset[i].X = _sampleOffsets[i]*ivp.X*BlurRadius;
- _blurOffset[i].Y = 0;
- }
- _blurOffsetParam.SetValue(_blurOffset);
- GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
- GraphicsDevice.Textures[0] = _aoTarget;
- _blurEffect.CurrentTechnique.Passes[0].Apply();
- GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, Vertices, 0, 2);
- }
- public override void Draw(CameraEntity camera)
- {
- Vector2 ivp = camera.InverseViewport;
- for (int i = 0; i < _blurSampleCount; i++)
- {
- _blurOffset[i].X = 0;
- _blurOffset[i].Y = _sampleOffsets[i]*ivp.Y*BlurRadius;
- }
- _blurOffsetParam.SetValue(_blurOffset);
- GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
- GraphicsDevice.Textures[0] = _blurPassTarget;
- _blurEffect.CurrentTechnique.Passes[0].Apply();
- GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, Vertices, 0, 2);
- }
- }
- }
Add Comment
Please, Sign In to add comment