| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #pragma once
- #include "BsRenderBeastPrerequisites.h"
- #include "BsRendererMaterial.h"
- #include "BsParamBlocks.h"
- #include "BsRenderTexturePool.h"
- namespace BansheeEngine
- {
- /** @addtogroup RenderBeast
- * @{
- */
- /** Settings that control automatic exposure (eye adaptation) post-process. */
- struct AutoExposureSettings
- {
- AutoExposureSettings();
- /**
- * Determines minimum luminance value in the eye adaptation histogram. The histogram is used for calculating the
- * average brightness of the scene. Any luminance value below this value will not be included in the histogram and
- * ignored in scene brightness calculations. In log2 units (-8 = 1/256). In the range [-16, 0].
- */
- float histogramLog2Min;
- /**
- * Determines maximum luminance value in the eye adaptation histogram. The histogram is used for calculating the
- * average brightness of the scene. Any luminance value above this value will not be included in the histogram and
- * ignored in scene brightness calculations. In log2 units (4 = 16). In the range [0, 16].
- */
- float histogramLog2Max;
- /**
- * Percentage below which to ignore values in the eye adaptation histogram. The histogram is used for calculating
- * the average brightness of the scene. Total luminance in the histogram will be summed up and multiplied by this
- * value to calculate minimal luminance. Luminance values below the minimal luminance will be ignored and not used
- * in scene brightness calculations. This allows you to remove outliers on the lower end of the histogram (e.g. a
- * few very dark pixels in an otherwise bright image). In range [0.0f, 1.0f].
- */
- float histogramPctLow;
- /**
- * Percentage above which to ignore values in the eye adaptation histogram. The histogram is used for calculating
- * the average brightness of the scene. Total luminance in the histogram will be summed up and multiplied by this
- * value to calculate maximum luminance. Luminance values above the maximum luminance will be ignored and not used
- * in scene brightness calculations. This allows you to remove outliers on the high end of the histogram (e.g. a few
- * very bright pixels). In range [0.0f, 1.0f].
- */
- float histogramPctHigh;
- /**
- * Clamps the minimum eye adaptation scale to this value. This allows you to limit eye adaptation so that exposure
- * is never too high (e.g. when in a very dark room you probably do not want the exposure to be so high that
- * everything is still visible). In range [0.0f, 10.0f].
- */
- float minEyeAdaptation;
- /**
- * Clamps the maximum eye adaptation scale to this value. This allows you to limit eye adaptation so that exposure
- * is never too low (e.g. when looking at a very bright light source you probably don't want the exposure to be so
- * low that the rest of the scene is all white (overexposed). In range [0.0f, 10.0f].
- */
- float maxEyeAdaptation;
- /**
- * Determines how quickly does the eye adaptation adjust to larger values. This affects how quickly does the
- * automatic exposure changes when the scene brightness increases. In range [0.01f, 20.0f]. */
- float eyeAdaptationSpeedUp;
- /**
- * Determines how quickly does the eye adaptation adjust to smaller values. This affects how quickly does the
- * automatic exposure changes when the scene brightness decreases. In range [0.01f, 20.0f].
- */
- float eyeAdaptationSpeedDown;
- };
- /** Settings that control tonemap post-process. */
- struct TonemappingSettings
- {
- TonemappingSettings();
- /**
- * Controls the shoulder (upper non-linear) section of the filmic curve used for tonemapping. Mostly affects bright
- * areas of the image and allows you to reduce over-exposure.
- */
- float filmicCurveShoulderStrength;
- /**
- * Controls the linear (middle) section of the filmic curve used for tonemapping. Mostly affects mid-range areas of
- * the image.
- */
- float filmicCurveLinearStrength;
- /**
- * Controls the linear (middle) section of the filmic curve used for tonemapping. Mostly affects mid-range areas of
- * the image and allows you to control how quickly does the curve climb.
- */
- float filmicCurveLinearAngle;
- /**
- * Controls the toe (lower non-linear) section of the filmic curve used for tonemapping. Mostly affects dark areas
- * of the image and allows you to reduce under-exposure.
- */
- float filmicCurveToeStrength;
- /** Controls the toe (lower non-linear) section of the filmic curve. used for tonemapping. Affects low-range. */
- float filmicCurveToeNumerator;
- /** Controls the toe (lower non-linear) section of the filmic curve used for tonemapping. Affects low-range. */
- float filmicCurveToeDenominator;
- /** Controls the white point of the filmic curve used for tonemapping. Affects the entire curve. */
- float filmicCurveLinearWhitePoint;
- };
- /** Settings that control white balance post-process. */
- struct WhiteBalanceSettings
- {
- WhiteBalanceSettings();
- /**
- * Temperature used for white balancing, in Kelvins.
- *
- * Moves along the Planckian locus. In range [1500.0f, 15000.0f].
- */
- float temperature;
- /**
- * Additional tint to be applied during white balancing. Can be used to further tweak the white balancing effect by
- * modifying the tint of the light. The tint is chosen on the Planckian locus isothermal, depending on the light
- * temperature specified by ::whiteTemperature.
- *
- * In range [-1.0f, 1.0f].
- */
- float tint;
- };
- /** Settings that control color grading post-process. */
- struct ColorGradingSettings
- {
- ColorGradingSettings();
- /**
- * Saturation to be applied during color grading. Larger values increase vibrancy of the image.
- * In range [0.0f, 2.0f].
- */
- Vector3 saturation;
- /**
- * Contrast to be applied during color grading. Larger values increase difference between light and dark areas of
- * the image. In range [0.0f, 2.0f]. */
- Vector3 contrast;
- /**
- * Gain to be applied during color grading. Simply increases all color values by an equal scale.
- * In range [0.0f, 2.0f].
- */
- Vector3 gain;
- /**
- * Gain to be applied during color grading. Simply offsets all color values by an equal amount.
- * In range [-1.0f, 1.0f].
- */
- Vector3 offset;
- };
- /** Settings that control the post-process operations. */
- struct PostProcessSettings
- {
- PostProcessSettings();
- /**
- * Determines should automatic exposure be applied to the HDR image. When turned on the average scene brightness
- * will be calculated and used to automatically expose the image to the optimal range. Use the parameters provided
- * by ::autoExposure to customize the automatic exposure effect. You may also use ::exposureScale to
- * manually adjust the automatic exposure. When automatic exposure is turned off you can use ::exposureScale to
- * manually set the exposure.
- */
- bool enableAutoExposure;
- /**
- * Parameters used for customizing automatic scene exposure.
- *
- * @see enableAutoExposure
- */
- AutoExposureSettings autoExposure;
- /**
- * Determines should the image be tonemapped. Tonemapping converts an HDR image into LDR image by applying
- * a filmic curve to the image, simulating the effect of film cameras. Filmic curve improves image quality by
- * tapering off lows and highs, preventing under- and over-exposure. This is useful if an image contains both
- * very dark and very bright areas, in which case the global exposure parameter would leave some areas either over-
- * or under-exposed. Use ::tonemapping to customize how tonemapping performed.
- *
- * If this is disabled, then color grading and white balancing will not be enabled either. Only relevant for HDR
- * images.
- */
- bool enableTonemapping;
- /**
- * Parameters used for customizing tonemapping.
- *
- * @see enableTonemapping
- */
- TonemappingSettings tonemapping;
- /**
- * Parameters used for customizing white balancing. White balancing converts a scene illuminated by a light of the
- * specified temperature into a scene illuminated by a standard D65 illuminant (average midday light) in order to
- * simulate the effects of chromatic adaptation of the human visual system.
- */
- WhiteBalanceSettings whiteBalance;
- /** Parameters used for customizing color grading. */
- ColorGradingSettings colorGrading;
- /**
- * Log2 value to scale the eye adaptation by (e.g. 2^0 = 1). Smaller values yield darker image, while larger yield
- * brighter image. Allows you to customize exposure manually, applied on top of eye adaptation exposure (if
- * enabled). In range [-8, 8].
- */
- float exposureScale;
- /**
- * Gamma value to adjust the image for. Larger values result in a brighter image. When tonemapping is turned
- * on the best gamma curve for the output device is chosen automatically and this value can by used to merely tweak
- * that curve. If tonemapping is turned off this is the exact value of the gamma curve that will be applied.
- */
- float gamma;
- };
- /** Contains per-camera data used by post process effects. */
- struct PostProcessInfo
- {
- PostProcessSettings settings;
- SPtr<PooledRenderTexture> downsampledSceneTex;
- SPtr<PooledRenderTexture> histogramTex;
- SPtr<PooledRenderTexture> histogramReduceTex;
- SPtr<PooledRenderTexture> eyeAdaptationTex[2];
- SPtr<PooledRenderTexture> colorLUT;
- INT32 lastEyeAdaptationTex = 0;
- };
- BS_PARAM_BLOCK_BEGIN(DownsampleParams)
- BS_PARAM_BLOCK_ENTRY(Vector2, gInvTexSize)
- BS_PARAM_BLOCK_END
- /** Shader that downsamples a texture to half its size. */
- class DownsampleMat : public RendererMaterial<DownsampleMat>
- {
- RMAT_DEF("PPDownsample.bsl");
- public:
- DownsampleMat();
- /** Renders the post-process effect with the provided parameters. */
- void execute(const SPtr<RenderTextureCore>& target, PostProcessInfo& ppInfo);
- /** Releases the output render target. */
- void release(PostProcessInfo& ppInfo);
- /** Returns the render texture where the output will be written. */
- SPtr<RenderTextureCore> getOutput() const { return mOutput; }
- private:
- DownsampleParams mParams;
- MaterialParamVec2Core mInvTexSize;
- MaterialParamTextureCore mInputTexture;
- POOLED_RENDER_TEXTURE_DESC mOutputDesc;
- SPtr<RenderTextureCore> mOutput;
- };
- BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramParams)
- BS_PARAM_BLOCK_ENTRY(Vector4I, gPixelOffsetAndSize)
- BS_PARAM_BLOCK_ENTRY(Vector2, gHistogramParams)
- BS_PARAM_BLOCK_ENTRY(Vector2I, gThreadGroupCount)
- BS_PARAM_BLOCK_END
- /** Shader that creates a luminance histogram used for eye adaptation. */
- class EyeAdaptHistogramMat : public RendererMaterial<EyeAdaptHistogramMat>
- {
- RMAT_DEF("PPEyeAdaptHistogram.bsl");
- public:
- EyeAdaptHistogramMat();
- /** Executes the post-process effect with the provided parameters. */
- void execute(PostProcessInfo& ppInfo);
- /** Releases the output render target. */
- void release(PostProcessInfo& ppInfo);
- /** Returns the render texture where the output was written. */
- SPtr<RenderTextureCore> getOutput() const { return mOutput; }
- /** Calculates the number of thread groups that need to execute to cover the provided render target. */
- static Vector2I getThreadGroupCount(const SPtr<RenderTextureCore>& target);
- /**
- * Returns a vector containing scale and offset (in that order) that will be applied to luminance values
- * to determine their position in the histogram.
- */
- static Vector2 getHistogramScaleOffset(const PostProcessInfo& ppInfo);
- static const UINT32 THREAD_GROUP_SIZE_X = 8;
- static const UINT32 THREAD_GROUP_SIZE_Y = 8;
-
- static const UINT32 HISTOGRAM_NUM_TEXELS = (THREAD_GROUP_SIZE_X * THREAD_GROUP_SIZE_Y) / 4;
- private:
- EyeAdaptHistogramParams mParams;
- MaterialParamTextureCore mSceneColor;
- MaterialParamLoadStoreTextureCore mOutputTex;
- POOLED_RENDER_TEXTURE_DESC mOutputDesc;
- SPtr<RenderTextureCore> mOutput;
- static const UINT32 LOOP_COUNT_X = 8;
- static const UINT32 LOOP_COUNT_Y = 8;
- };
- BS_PARAM_BLOCK_BEGIN(EyeAdaptHistogramReduceParams)
- BS_PARAM_BLOCK_ENTRY(int, gThreadGroupCount)
- BS_PARAM_BLOCK_END
- /** Shader that reduces the luminance histograms created by EyeAdaptHistogramMat into a single histogram. */
- class EyeAdaptHistogramReduceMat : public RendererMaterial<EyeAdaptHistogramReduceMat>
- {
- RMAT_DEF("PPEyeAdaptHistogramReduce.bsl");
- public:
- EyeAdaptHistogramReduceMat();
- /** Executes the post-process effect with the provided parameters. */
- void execute(PostProcessInfo& ppInfo);
- /** Releases the output render target. */
- void release(PostProcessInfo& ppInfo);
- /** Returns the render texture where the output was written. */
- SPtr<RenderTextureCore> getOutput() const { return mOutput; }
- private:
- EyeAdaptHistogramReduceParams mParams;
- MaterialParamTextureCore mHistogramTex;
- MaterialParamTextureCore mEyeAdaptationTex;
- POOLED_RENDER_TEXTURE_DESC mOutputDesc;
- SPtr<RenderTextureCore> mOutput;
- };
- BS_PARAM_BLOCK_BEGIN(EyeAdaptationParams)
- BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gEyeAdaptationParams, 3)
- BS_PARAM_BLOCK_END
- /** Shader that computes the eye adaptation value based on scene luminance. */
- class EyeAdaptationMat : public RendererMaterial<EyeAdaptationMat>
- {
- RMAT_DEF("PPEyeAdaptation.bsl");
- public:
- EyeAdaptationMat();
- /** Executes the post-process effect with the provided parameters. */
- void execute(PostProcessInfo& ppInfo, float frameDelta);
- private:
- EyeAdaptationParams mParams;
- MaterialParamTextureCore mReducedHistogramTex;
- };
- BS_PARAM_BLOCK_BEGIN(CreateTonemapLUTParams)
- BS_PARAM_BLOCK_ENTRY_ARRAY(Vector4, gTonemapParams, 2)
- BS_PARAM_BLOCK_ENTRY(float, gGammaAdjustment)
- BS_PARAM_BLOCK_ENTRY(int, gGammaCorrectionType)
- BS_PARAM_BLOCK_ENTRY(Vector3, gSaturation)
- BS_PARAM_BLOCK_ENTRY(Vector3, gContrast)
- BS_PARAM_BLOCK_ENTRY(Vector3, gGain)
- BS_PARAM_BLOCK_ENTRY(Vector3, gOffset)
- BS_PARAM_BLOCK_END
- BS_PARAM_BLOCK_BEGIN(WhiteBalanceParams)
- BS_PARAM_BLOCK_ENTRY(float, gWhiteTemp)
- BS_PARAM_BLOCK_ENTRY(float, gWhiteOffset)
- BS_PARAM_BLOCK_END
- /**
- * Shader that creates a 3D lookup texture that is used to apply tonemapping, color grading, white balancing and gamma
- * correction.
- */
- class CreateTonemapLUTMat : public RendererMaterial<CreateTonemapLUTMat>
- {
- RMAT_DEF("PPCreateTonemapLUT.bsl");
- public:
- CreateTonemapLUTMat();
- /** Executes the post-process effect with the provided parameters. */
- void execute(PostProcessInfo& ppInfo);
- /** Releases the output render target. */
- void release(PostProcessInfo& ppInfo);
- /** Size of the 3D color lookup table. */
- static const UINT32 LUT_SIZE = 32;
- private:
- CreateTonemapLUTParams mParams;
- WhiteBalanceParams mWhiteBalanceParams;
- };
- BS_PARAM_BLOCK_BEGIN(TonemappingParams)
- BS_PARAM_BLOCK_ENTRY(float, gRawGamma)
- BS_PARAM_BLOCK_ENTRY(float, gManualExposureScale)
- BS_PARAM_BLOCK_END
- /** Shader that applies tonemapping and converts a HDR image into a LDR image. */
- template<bool GammaOnly, bool AutoExposure>
- class TonemappingMat : public RendererMaterial<TonemappingMat<GammaOnly, AutoExposure>>
- {
- RMAT_DEF("PPTonemapping.bsl");
- public:
- TonemappingMat();
- /** Executes the post-process effect with the provided parameters. */
- void execute(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
- PostProcessInfo& ppInfo);
- private:
- TonemappingParams mParams;
- MaterialParamTextureCore mInputTex;
- MaterialParamTextureCore mColorLUT;
- MaterialParamTextureCore mEyeAdaptationTex;
- };
- /**
- * Renders post-processing effects for the provided render target.
- *
- * @note Core thread only.
- */
- class BS_BSRND_EXPORT PostProcessing : public Module<PostProcessing>
- {
- public:
- /** Renders post-processing effects for the provided render target. */
- void postProcess(const SPtr<RenderTextureCore>& sceneColor, const SPtr<ViewportCore>& outputViewport,
- PostProcessInfo& ppInfo, float frameDelta);
-
- private:
- DownsampleMat mDownsample;
- EyeAdaptHistogramMat mEyeAdaptHistogram;
- EyeAdaptHistogramReduceMat mEyeAdaptHistogramReduce;
- EyeAdaptationMat mEyeAdaptation;
- CreateTonemapLUTMat mCreateLUT;
- TonemappingMat<false, true> mTonemapping_AE;
- TonemappingMat<true, true> mTonemapping_AE_GO;
- TonemappingMat<false, false> mTonemapping;
- TonemappingMat<true, false> mTonemapping_GO;
- };
- /** @} */
- }
|