#ifndef _DEFERREDRENDERER_H__ #define _DEFERREDRENDERER_H__ #include "common.h" #include "Matrix4x4.h" #include "Vector3.h" namespace CHCDemoEngine { class FrameBufferObject; class Vector3; class PerspectiveCamera; class Matrix4x4; class ShadowMap; class DirectionalLight; /** This class implements a deferred shading algorithm that takes a frame buffer object as input and outputs an image in the given size */ class DeferredRenderer { public: /** Constructor for a deferred shader taking the requested output image size, the current camera, and if the ssao should be full or half resolution */ DeferredRenderer(int w, int h, PerspectiveCamera *cam, bool ssaoUsefulResolution); /** Destructor */ ~DeferredRenderer(); /** The main render function Currently our fbo consists of one combined color + depth buffer, a normal buffer, and a buffer holding the difference of the pixel positions from the last frame. Set useToneMapping to true if tone mapping should be applied Set useAntiAliasing true if some basic edge antialiasing should be performed If a shadowMap is specified that is not NULL, the shadow mapped shading algorithm is applied. The temporal coherence factor is the maximal number of ssao samples that are accumulated without losing any prior sample information. Set this number too low and flickering can be seen, too high and the adaption to some changes in the ssao might be too slow. Usually from about 1000 samples a flickering cannot be seen. */ void Render(FrameBufferObject *fbo, float tempCohFactor, DirectionalLight *light, bool useToneMapping, bool useAntiAliasing, ShadowMap *shadowMap = NULL ); enum SAMPLING_METHOD {SAMPLING_POISSON, SAMPLING_QUADRATIC, SAMPLING_DEFAULT}; /** Use ssao or ssao + color bleeding */ enum SHADING_METHOD {DEFAULT, SSAO, GI}; /** Set the samplig method for the indirect illumination */ void SetSamplingMethod(SAMPLING_METHOD s); /** Set the shading method (SSAO, SSAO + color bleeding */ void SetShadingMethod(SHADING_METHOD s); /** Sort the samples so texture access is faster */ void SetSortSamples(bool sortSamples); /** Sets ssao sample intensity. */ void SetSampleIntensity(float sampleIntensity); /** Sets ssao kernel radius. */ void SetKernelRadius(float kernelRadius); /** Sets ssao filter radius. */ void SetSsaoFilterRadius(float radius); /** Sets the number of visible pixels of the sun */ void SetSunVisiblePixels(int visiblePixels); /** If true tem poral coherence is used for ssao */ void SetUseTemporalCoherence(bool temporal); /** if set to something other than -1 the current frame is stored on disc using the specified frame number */ void SetSaveFrame(const std::string &suffix, int frameNumber); // hack: store the color buffer idx for the currently used flip flop-MRT here // TODO matt: make this less hacky static int colorBufferIdx; protected: void ComputeSsao(FrameBufferObject *fbo, float tempCohFactor); void ComputeGlobIllum(FrameBufferObject *fbo, float tempCohFactor); void FirstPass(FrameBufferObject *fbo, DirectionalLight *light); void FirstPassShadow(FrameBufferObject *fbo, DirectionalLight *light, ShadowMap *shadowMap); void ComputeToneParameters(FrameBufferObject *fbo, DirectionalLight *light, float &imageKey, float &whiteLum, float &middleGrey); void ToneMap(FrameBufferObject *fbo, float imageKey, float whiteLum, float middleGrey); void CombineSsao(FrameBufferObject *fbo); void CombineIllum(FrameBufferObject *fbo); /** Does some basic antialiasing (searches for edges using a edge detector, smoothes these edges. This function is usually the last function in the pipeline, so one can specify if the frame should be put out directly or stored to another texture. */ void AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light, bool displayFrame = true); /** Downsample buffer of fbo to buffer of downSampleFbo. The downSampleFbo must have half the resolution of fbo. */ void DownSample(FrameBufferObject *fbo, int bufferIdx, FrameBufferObject *downSampleFbo, int downSampleBufferIdx, ShaderProgram *program); void DrawQuad(ShaderProgram *p); void Output(FrameBufferObject *fbo); /** Initialises the deferred shader and loads the required shaders: This function has to be called only once. */ void InitCg(); /** Is called once per render call and sets the most important parameters. */ void InitFrame(); void FlipFbos(FrameBufferObject *fbo); void PrepareSsao(FrameBufferObject *fbo); void SortSamples(); void LenseFlare(FrameBufferObject *fbo, DirectionalLight *light); void PrepareSsaoFilter(); void SaveFrame(FrameBufferObject *fbo); void DepthOfField(FrameBufferObject *fbo); //////////// /// deferred shading output image width int mWidth; /// deferred shading output image height int mHeight; ////////////////// PerspectiveCamera *mCamera; bool mUseTemporalCoherence; int mSamplingMethod; int mShadingMethod; bool mRegenerateSamples; int mIllumFboIndex; /// the fbo for indirect illumination (ssao + color bleeding) FrameBufferObject *mIllumFbo; FrameBufferObject *mDownSampleFbo; FBOContainer mFBOs; Matrix4x4 mProjViewMatrix; Matrix4x4 mOldProjViewMatrix; Vector3 mCornersView[4]; Vector3 mOldCornersView[4]; Vector3 mEyePos; Vector3 mOldEyePos; bool mSortSamples; float mKernelRadius; float mSsaoFilterRadius; float mSampleIntensity; int mSunVisiblePixels; int mSavedFrameNumber; std::string mSavedFrameSuffix; }; } // namespace #endif // _SSAOSHADER_H__