제목 없음

Crepuscular Rays, Depth of Field and Bloom Post Processors

Currently most of the Post Processors are handled loosely and internally by the vxRenderer class. This is great for keeping everything in one place, but it causes a lot of redundant information to be sent to the GPU each call. A perfect illustration of this is in this excerpt from the Edge Detection Post Processor code:

EffectParameterCollection parameters = xEngine.Assets.PostProcessShaders.CartoonEdgeDetection.Parameters;

Vector2 resolution = new Vector2(RT\_MainScene.Width,

RT\_MainScene.Height);

// Pass in the current screen resolution.

parameters\["ScreenResolution"\].SetValue(resolution);

parameters\["NormalTexture"\].SetValue(RT\_NormalMap);

parameters\["DepthTexture"\].SetValue(RT\_DepthMap);

// Settings controlling the edge detection filter.

parameters\["EdgeWidth"\].SetValue(Settings.EdgeWidth);

parameters\["EdgeIntensity"\].SetValue(Settings.EdgeIntensity);

// How sensitive should the edge detection be to tiny variations in the input data?

// Smaller settings will make it pick up more subtle edges, while larger values get

// rid of unwanted noise.

parameters\["NormalThreshold"\].SetValue(0.5f);

parameters\["DepthThreshold"\].SetValue(0.001f);

// How dark should the edges get in response to changes in the input data?

parameters\["NormalSensitivity"\].SetValue(1.0f);

parameters\["DepthSensitivity"\].SetValue(10000.0f);

Matrix orthoproj = Matrix.CreateOrthographicOffCenter(0,

vxEngine.GraphicsDevice.Viewport.Width,

vxEngine.GraphicsDevice.Viewport.Height,

0, 0, 1);

Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

parameters\["MatrixTransform"\].SetValue(halfPixelOffset \* orthoproj);

// Activate the appropriate effect technique.

vxEngine.Assets.PostProcessShaders.CartoonEdgeDetection.CurrentTechnique = vxEngine.Assets.PostProcessShaders.CartoonEdgeDetection.Techniques\["EdgeDetect"\];

// Draw a fullscreen sprite to apply the postprocessing effect.

vxEngine.SpriteBatch.Begin(0, BlendState.Opaque, null, null, null, vxEngine.Assets.PostProcessShaders.CartoonEdgeDetection);

vxEngine.SpriteBatch.Draw(RT\_FinalScene, Vector2.Zero, Color.White);

vxEngine.SpriteBatch.End();

[view raw](https://gist.github.com/rtroe/ea6b627f4d69ffb197fe2c2222717419/raw/e568f67189e2759d8c86417f0d62bce0ed174f9f/OldEdgeDetect.cs) [OldEdgeDetect.cs](https://gist.github.com/rtroe/ea6b627f4d69ffb197fe2c2222717419#file-oldedgedetect-cs) hosted with ❤ by [GitHub](https://github.com)

As you can see above, there’s a number of redundant calls to items which wouldn’t had changed from the last loop. A more efficient way would be to add these into get/set Properties and to manage the effects from within their own class.

public Matrix MatrixTransform

{

set

{

if (Parameters\["MatrixTransform"\] != null)

Parameters\["MatrixTransform"\].SetValue(value);

}

}

view raw Parameters Example.cs hosted with ❤ by GitHub

I could’ve put each of these get/set Properties within the vxRenderer class, but then that would only add lines of code to an already very full *.cs file and makes debugging any post processor issues even more complicated.

I decided a cleaner and better way to implement this would be to encapsulate each post processor into it’s own class which inherited from a base Post Processor class and Interface.

namespace Virtex.Lib.Vrtc.Graphics

{

public interface vxPostProcessorInterface

{

void SetResoultion();

void LoadContent();

void Apply();

}

}

view raw vxPostProcessorInterface.cs hosted with ❤ by GitHub

As you can see above from the interface, There’s a ‘SetResolution()‘ method which holds any and all code that’s required to update everytime the resolution changes. This makes updating Viewport bounds that are required for most post processors to be easily reset.

There’s also a ‘LoadContent()’ method which is essentially for setting up any code outside of the Constructor.

Finally is the ‘Apply()‘ method, where the magic happens. This is a generic method where the actual effect is applied to the scene.

Further to all of this, All of the Post Processors are added to an Effects list in the Renderer.  This makes any batch changes very easy to perform by simply just looping through the collection when needed and calling the required method.

jvdjp4n

Again, Crepuscular Rays, Bloom and Cartoon Edge Detection Post Processors

In the end, this creates for a very structured way in which to handle all of the post processing effects, allowing not only a more efficient rendering loop by lessening the amount of information sent to the GPU each loop, as well as minimizes on lines of code.