Copied changes from old HDR branch to new one.

This commit is contained in:
Jonathas Costa
2019-01-10 14:17:29 -05:00
parent ebf55f3029
commit 88ad250c85
20 changed files with 1158 additions and 62 deletions
@@ -65,6 +65,12 @@ public:
void setHDRExposure(float hdrExposure) override;
void setHDRBackground(float hdrBackground) override;
void setGamma(float gamma) override;
void setMaxWhite(float maxWhite) override;
void setToneMapOperator(int tmOp) override;
void setBloomThreMin(float minV) override;
void setBloomThreMax(float maxV) override;
void setBloomOrigFactor(float origFactor) override;
void setBloomNewFactor(float newFactor) override;
float hdrBackground() const override;
int nAaSamples() const override;
@@ -135,7 +141,13 @@ private:
float _hdrExposure = 0.4f;
float _hdrBackground = 2.8f;
float _gamma = 2.2f;
float _maxWhite = 1.f;
float _blackoutFactor;
float _bloomThresholdMin = 0.0;
float _bloomThresholdMax = 1.0;
float _bloomOrigFactor = 1.0;
float _bloomNewFactor = 1.0;
int _toneMapOperator = 0;
std::vector<double> _mSAAPattern;
@@ -76,7 +76,9 @@ public:
void updateResolution();
void updateRaycastData();
void updateDeferredcastData();
void updateHDRData();
void updateHDRAndFiltering();
void updateAveLum();
void updateBloomConfig();
void updateMSAASamplingPattern();
void setResolution(glm::ivec2 res) override;
@@ -84,6 +86,12 @@ public:
void setHDRExposure(float hdrExposure) override;
void setHDRBackground(float hdrBackground) override;
void setGamma(float gamma) override;
void setMaxWhite(float maxWhite) override;
void setToneMapOperator(int tmOp) override;
void setBloomThreMin(float minV) override;
void setBloomThreMax(float maxV) override;
void setBloomOrigFactor(float origFactor) override;
void setBloomNewFactor(float newFactor) override;
float hdrBackground() const override;
int nAaSamples() const override;
@@ -105,6 +113,11 @@ public:
virtual void deferredcastersChanged(Deferredcaster& deferredcaster,
DeferredcasterListener::IsAttached isAttached) override;
private:
float computeBufferAveLuminance();
float computeBufferAveLuminanceGPU();
void applyBloomFilter();
private:
std::map<VolumeRaycaster*, RaycastData> _raycastData;
RaycasterProgObjMap _exitPrograms;
@@ -113,14 +126,26 @@ private:
std::map<Deferredcaster*, DeferredcastData> _deferredcastData;
DeferredcasterProgObjMap _deferredcastPrograms;
std::unique_ptr<ghoul::opengl::ProgramObject> _hdrBackGroundProgram;
std::unique_ptr<ghoul::opengl::ProgramObject> _hdrFilteringProgram;
std::unique_ptr<ghoul::opengl::ProgramObject> _aveLumProgram;
std::unique_ptr<ghoul::opengl::ProgramObject> _bloomProgram;
std::unique_ptr<ghoul::opengl::ProgramObject> _bloomResolveProgram;
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram;
UniformCache(mainColorTexture, blackoutFactor, nAaSamples) _uniformCache;
UniformCache(deferredResultsTexture, blackoutFactor, backgroundConstant,
backgroundExposure, gamma, toneMapOperator, aveLum, maxWhite)
_hdrUniformCache;
UniformCache(renderedImage, bloomImage, bloomThresholdMin, bloomThresholdMax,
bloomOrigFactor, bloomNewFactor) _bloomUniformCache;
GLuint _screenQuad;
GLuint _vertexPositionBuffer;
GLuint _mainColorTexture;
GLuint _mainFilterTexture;
GLuint _mainPositionTexture;
GLuint _mainNormalTexture;
GLuint _mainDepthTexture;
@@ -128,8 +153,14 @@ private:
GLuint _mainFramebuffer;
GLuint _exitDepthTexture;
GLuint _exitFramebuffer;
GLuint _deferredFramebuffer;
GLuint _deferredColorTexture;
GLuint _hdrFilteringFramebuffer;
GLuint _hdrFilteringTexture;
GLuint _bloomFilterFBO[3];
GLuint _bloomTexture[3];
GLuint _computeAveLumFBO;
GLuint _computeAveLumTexture;
bool _dirtyDeferredcastData;
bool _dirtyRaycastData;
@@ -141,6 +172,12 @@ private:
float _hdrExposure = 0.4f;
float _hdrBackground = 2.8f;
float _gamma = 2.2f;
float _maxWhite = 1.0f;
float _bloomThresholdMin = 0.0;
float _bloomThresholdMax = 1.0;
float _bloomOrigFactor = 1.0;
float _bloomNewFactor = 1.0;
int _toneMapOperator = 0;
std::vector<double> _mSAAPattern;
@@ -64,6 +64,20 @@ public:
Invalid
};
enum class ToneMapOperators {
EXPONENTIAL = 0,
LINEAR,
SIMPLE_REINHARD,
LUM_BASED_REINHARD,
WHITE_PRESERVING,
ROM_BIN_DA_HOUSE,
FILMIC,
UNCHARTED,
COSTA,
ADAPTIVE,
GLOBAL
};
RenderEngine();
~RenderEngine();
@@ -193,6 +207,12 @@ private:
properties::FloatProperty _hdrExposure;
properties::FloatProperty _hdrBackground;
properties::FloatProperty _gamma;
properties::FloatProperty _maxWhite;
properties::FloatProperty _bloomThreshouldMin;
properties::FloatProperty _bloomThreshouldMax;
properties::FloatProperty _bloomOrigColorFactor;
properties::FloatProperty _bloomNewColorFactor;
properties::OptionProperty _toneMapOperator;
uint64_t _frameNumber = 0;
+6
View File
@@ -53,6 +53,12 @@ public:
virtual void setHDRExposure(float hdrExposure) = 0;
virtual void setHDRBackground(float hdrBackground) = 0;
virtual void setGamma(float gamma) = 0;
virtual void setMaxWhite(float maxWhite) = 0;
virtual void setToneMapOperator(int tmOp) = 0;
virtual void setBloomThreMin(float minV) = 0;
virtual void setBloomThreMax(float maxV) = 0;
virtual void setBloomOrigFactor(float origFactor) = 0;
virtual void setBloomNewFactor(float newFactor) = 0;
virtual float hdrBackground() const = 0;
virtual int nAaSamples() const = 0;
@@ -633,7 +633,8 @@ void main() {
if (position.xyz != vec3(0.0) && (pixelDepth < offset)) {
// ATM Occluded - Something in fron of ATM.
atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
//atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
atmosphereFinalColor += vec4(color.xyz * backgroundConstant, color.a);
} else {
// Following paper nomenclature
double t = offset;
@@ -682,13 +683,15 @@ void main() {
}
// Final Color of ATM plus terrain:
vec4 finalRadiance = vec4(HDR(inscatterColor + groundColorV + sunColorV, atmExposure), 1.0);
//vec4 finalRadiance = vec4(HDR(inscatterColor + groundColorV + sunColorV, atmExposure), 1.0);
vec4 finalRadiance = vec4(inscatterColor + groundColorV + sunColorV, 1.0);
atmosphereFinalColor += finalRadiance;
}
}
else { // no intersection
atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
//atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a);
atmosphereFinalColor += vec4(color.xyz * backgroundConstant, color.a);
}
}
@@ -704,7 +707,8 @@ void main() {
bColor += texelFetch(mainColorTexture, fragCoords, f);
}
bColor /= float(nAaSamples);
renderTarget = vec4(HDR(bColor.xyz * backgroundConstant, atmExposure), bColor.a);
//renderTarget = vec4(HDR(bColor.xyz * backgroundConstant, atmExposure), bColor.a);
renderTarget = vec4(bColor.xyz * backgroundConstant, bColor.a);
}
else {
discard;
@@ -71,5 +71,8 @@ Fragment getFragment() {
// There is no normal here
frag.gNormal = vec4(0.0, 0.0, -1.0, 1.0);
// Bloom filter
frag.filterFlag = 1;
return frag;
}
+1
View File
@@ -32,6 +32,7 @@ struct Fragment {
vec4 color;
vec4 gPosition;
vec4 gNormal;
uint filterFlag;
float depth;
uint blend;
bool forceFboRendering;
+75
View File
@@ -0,0 +1,75 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout (location = 0) out vec4 finalColor;
uniform int pass;
uniform sampler2DMS filterImage;
uniform sampler2D filterFirstPass;
// Gaussian Weights from OpenGL SuperBible 7 ed.
const float weights[] = float[](0.0024499299678342,
0.0043538453346397,
0.0073599963704157,
0.0118349786570722,
0.0181026699707781,
0.0263392293891488,
0.0364543006660986,
0.0479932050577658,
0.0601029809166942,
0.0715974486241365,
0.0811305381519717,
0.0874493212267511,
0.0896631113333857,
0.0874493212267511,
0.0811305381519717,
0.0715974486241365,
0.0601029809166942,
0.0479932050577658,
0.0364543006660986,
0.0263392293891488,
0.0181026699707781,
0.0118349786570722,
0.0073599963704157,
0.0043538453346397,
0.0024499299678342);
void main(void)
{
vec4 color = vec4(0.0);
// Transpose the image so the filter can be applied on X and Y
ivec2 P = ivec2(gl_FragCoord.yx) - ivec2(0, weights.length() >> 1);
for (int i = 0; i < weights.length(); i++)
{
if (pass == 1)
color += vec4(texelFetch(filterImage, P + ivec2(0, i), 0).rgb, 1.0) * weights[i];
else if (pass == 2)
color += vec4(texelFetch(filterFirstPass, P + ivec2(0, i), 0).rgb, 1.0) * weights[i];
}
finalColor = vec4(color.rgb, 1.0);
}
+35
View File
@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
void main(void)
{
const vec4 vertices[] = vec4[](vec4(-1.0, -1.0, 0.5, 1.0),
vec4( 1.0, -1.0, 0.5, 1.0),
vec4(-1.0, 1.0, 0.5, 1.0),
vec4( 1.0, 1.0, 0.5, 1.0));
gl_Position = vertices[gl_VertexID];
}
@@ -0,0 +1,43 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout (location = 0) out vec4 finalColor;
uniform float bloomOrigFactor;
uniform float bloomNewFactor;
uniform sampler2D renderedImage;
uniform sampler2D bloomImage;
void main(void)
{
vec4 color = vec4(0.0);
color += texelFetch(renderedImage, ivec2(gl_FragCoord.xy), 0) * bloomOrigFactor;
float alpha = color.a;
color += texelFetch(bloomImage, ivec2(gl_FragCoord.xy), 0) * bloomNewFactor;
finalColor = vec4(color.rgb, alpha);
}
@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
void main(void)
{
const vec4 vertices[] = vec4[](vec4(-1.0, -1.0, 0.5, 1.0),
vec4( 1.0, -1.0, 0.5, 1.0),
vec4(-1.0, 1.0, 0.5, 1.0),
vec4( 1.0, 1.0, 0.5, 1.0));
gl_Position = vertices[gl_VertexID];
}
+51
View File
@@ -0,0 +1,51 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout (location = 0) out vec4 finalColor;
uniform int bufferWidth;
uniform int bufferHeight;
uniform sampler2D hdrTexture;
in vec2 texCoord;
void main() {
vec4 color = vec4(0.0);
float fH = float(bufferHeight);
float fW = float(bufferWidth);
float sum = 0.f;
for (int i = 0; i < bufferHeight; ++i) {
for (int j = 0; j < bufferWidth; ++j) {
vec2 texCoord = vec2(float(i) / fH, float(j) / fW);
vec4 tmpColor = texture(hdrTexture, texCoord);
float lum = dot(tmpColor.xyz, vec3(0.2126f, 0.7152f, 0.0722f));
sum += log(lum + 0.00001);
}
}
finalColor = vec4(vec3(exp(sum / (fH * fW))), 1.0);
}
+31
View File
@@ -0,0 +1,31 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(location = 0) in vec4 position;
void main() {
gl_Position = position;
}
+120
View File
@@ -0,0 +1,120 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
#include "hdr.glsl"
layout (location = 0) out vec4 finalColor;
uniform float backgroundConstant;
uniform float backgroundExposure;
uniform float blackoutFactor;
uniform float gamma;
uniform float maxWhite;
uniform float aveLum;
uniform int toneMapOperator;
uniform sampler2D deferredResultsTexture;
in vec2 texCoord;
vec4 adaptiveToneMap() {
int i;
float lum[25];
vec2 tex_scale = vec2(1.0) / textureSize(deferredResultsTexture, 0);
for (i = 0; i < 25; i++)
{
vec2 tc = (gl_FragCoord.xy + 3.5 * vec2(i % 5 - 2, i / 5 - 2));
vec3 col = texture(deferredResultsTexture, tc * tex_scale).rgb;
lum[i] = dot(col, vec3(0.3, 0.59, 0.11));
}
// Calculate weighted color of region
vec3 vColor = texelFetch(deferredResultsTexture, ivec2(gl_FragCoord.xy), 0).rgb;
float kernelLuminance = (
(1.0 * (lum[0] + lum[4] + lum[20] + lum[24])) +
(4.0 * (lum[1] + lum[3] + lum[5] + lum[9] +
lum[15] + lum[19] + lum[21] + lum[23])) +
(7.0 * (lum[2] + lum[10] + lum[14] + lum[22])) +
(16.0 * (lum[6] + lum[8] + lum[16] + lum[18])) +
(26.0 * (lum[7] + lum[11] + lum[13] + lum[17])) +
(41.0 * lum[12])
) / 273.0;
// Compute the corresponding exposure
float exposure = sqrt(8.0 / (kernelLuminance + 0.25));
// Apply the exposure to this texel
vec4 fColor;
fColor.rgb = 1.0 - exp2(-vColor * exposure);
fColor.a = 1.0f;
return fColor;
}
void main() {
vec4 color = vec4(0.0);
color = texture(deferredResultsTexture, texCoord);
//color = texelFetch(deferredResultsTexture, ivec2(gl_FragCoord.xy), 0);
color.a *= blackoutFactor;
if (toneMapOperator == EXPONENTIAL) {
vec3 tColor = exponentialToneMapping(color.rgb, backgroundExposure, gamma);
finalColor = vec4(tColor, color.a);
} else if (toneMapOperator == LINEAR) {
vec3 tColor = linearToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == SIMPLE_REINHARD) {
vec3 tColor = simpleReinhardToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == LUM_BASED_REINHARD) {
vec3 tColor = lumaBasedReinhardToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == WHITE_PRESERVING) {
vec3 tColor = whitePreservingLumaBasedReinhardToneMapping(color.rgb, backgroundExposure, maxWhite);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == ROM_BIN_DA_HOUSE) {
vec3 tColor = RomBinDaHouseToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == FILMIC) {
vec3 tColor = filmicToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == UNCHARTED) {
vec3 tColor = Uncharted2ToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == COSTA) {
vec3 tColor = jToneMapping(color.rgb, backgroundExposure);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == ADAPTIVE) {
vec3 tColor = vec3(adaptiveToneMap());
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
} else if (toneMapOperator == GLOBAL) {
vec3 tColor = globalToneMappingOperatorRTR(color.rgb, backgroundExposure, maxWhite, aveLum);
finalColor = vec4(gammaCorrection(tColor, gamma), color.a);
}
}
+33
View File
@@ -0,0 +1,33 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2018 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(location = 0) in vec4 position;
out vec2 texCoord;
void main() {
texCoord = 0.5 + position.xy * 0.5;
gl_Position = position;
}
@@ -28,11 +28,29 @@
layout(location = 0) out vec4 _out_color_;
layout(location = 1) out vec4 gPosition;
layout(location = 2) out vec4 gNormal;
layout(location = 3) out vec4 filterBuffer;
void main() {
Fragment f = getFragment();
_out_color_ = f.color;
gPosition = f.gPosition;
gNormal = f.gNormal;
bool automaticBloom = false;
if (automaticBloom) {
// Extract luminance
float Y = dot(f.color.rgb, vec3(0.299, 0.587, 0.144));
// Apply Bloom on the bloom threshold range values
//vec4 bColor = f.color * 4.0 * smoothstep(bloom_thresh_min, bloom_thresh_max, Y);
//filterBuffer = bColor
filterBuffer = vec4(f.filterFlag);
} else {
if (f.filterFlag == 1)
filterBuffer = f.color;
else
filterBuffer = vec4(0);
}
gl_FragDepth = normalizeFloat(f.depth);
}
+53 -15
View File
@@ -21,10 +21,51 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
uniform float gamma;
vec3 exponentialToneMapping(vec3 color, float exposure) {
#define EXPONENTIAL 0
#define LINEAR 1
#define SIMPLE_REINHARD 2
#define LUM_BASED_REINHARD 3
#define WHITE_PRESERVING 4
#define ROM_BIN_DA_HOUSE 5
#define FILMIC 6
#define UNCHARTED 7
#define COSTA 8
#define ADAPTIVE 9
#define GLOBAL 10
const mat3 rgb2xyz = mat3(
0.4124564, 0.2126729, 0.0193339,
0.3575761, 0.7151522, 0.1191920,
0.1804375, 0.0721750, 0.9503041 );
const mat3 xyz2rgb = mat3(
3.2404542, -0.9692660, 0.0556434,
-1.5371385, 1.8760108, -0.2040259,
-0.4985314, 0.0415560, 1.0572252 );
vec3 globalToneMappingOperatorRTR(vec3 color, float exposure, float maxWhite, float aveLum) {
// Convert color to XYZ
vec3 xyzCol = rgb2xyz * color;
// Convert from XYZ to xyY
float xyzSum = xyzCol.x + xyzCol.y + xyzCol.z;
vec3 xyYCol = vec3( xyzCol.x / xyzSum, xyzCol.y / xyzSum, xyzCol.y);
// Apply the tone mapping operation to the luminance (xyYCol.z or xyzCol.y)
float L = (exposure * xyYCol.z) / aveLum;
L = (L * ( 1 + L / (maxWhite * maxWhite) )) / ( 1 + L );
// Using the new luminance, convert back to XYZ
xyzCol.x = (L * xyYCol.x) / (xyYCol.y);
xyzCol.y = L;
xyzCol.z = (L * (1 - xyYCol.x - xyYCol.y))/xyYCol.y;
// Convert back to RGB and send to output buffer
return xyz2rgb * xyzCol;
}
vec3 exponentialToneMapping(vec3 color, float exposure, float gamma) {
color *= exposure;
color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / gamma) : 1.0 - exp(-color.r);
@@ -37,14 +78,12 @@ vec3 exponentialToneMapping(vec3 color, float exposure) {
vec3 linearToneMapping(vec3 color, float exposure) {
float tExposure = 0.08f;
color = clamp(tExposure * color, 0.f, 1.f);
color = pow(color, vec3(1.f / gamma));
return color;
}
vec3 simpleReinhardToneMapping(vec3 color, float exposure) {
float tExposure = 1.5f;
float tExposure = exposure;
color *= tExposure/(1.f + color / tExposure);
color = pow(color, vec3(1.f / gamma));
return color;
}
@@ -52,23 +91,19 @@ vec3 lumaBasedReinhardToneMapping(vec3 color, float exposure) {
float luma = dot(color, vec3(0.2126f, 0.7152f, 0.0722f));
float toneMappedLuma = luma / (1.f + luma);
color *= toneMappedLuma / luma;
color = pow(color, vec3(1.f / gamma));
return color;
}
vec3 whitePreservingLumaBasedReinhardToneMapping(vec3 color, float exposure) {
float white = 4.f;
vec3 whitePreservingLumaBasedReinhardToneMapping(vec3 color, float exposure, float maxWhite) {
//float luma = dot(color, vec3(0.2126f, 0.7152f, 0.0722f));
float luma = dot(color, vec3(0.4126f, 0.9152f, 0.2722f));
float toneMappedLuma = luma * (1.f + luma / (white * white)) / (1.f + luma);
float toneMappedLuma = luma * (1.f + luma / (maxWhite * maxWhite)) / (1.f + luma);
color *= toneMappedLuma / luma;
color = pow(color, vec3(1.f / gamma));
return color;
}
vec3 RomBinDaHouseToneMapping(vec3 color, float exposure) {
color = exp( -1.f / ( 2.72f * color + 0.15f ) );
color = pow(color, vec3(1.7f / gamma));
return color;
}
@@ -92,7 +127,6 @@ vec3 Uncharted2ToneMapping(vec3 color, float exposure) {
color = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F;
float white = ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F;
color /= white;
color = pow(color, vec3(1.0f / gamma));
return color;
}
@@ -100,6 +134,10 @@ vec3 jToneMapping(vec3 color, float exposure) {
return 1.0 - exp(-exposure * color);
}
vec3 gammaCorrection(vec3 color, float gamma) {
return pow(color, vec3(1.0f / gamma));
}
vec3 HDR(vec3 color, float exposure) {
//return exponentialToneMapping(color, exposure);
//return linearToneMapping(color, exposure);
@@ -107,7 +145,7 @@ vec3 HDR(vec3 color, float exposure) {
//return lumaBasedReinhardToneMapping(color, exposure);
//return whitePreservingLumaBasedReinhardToneMapping(color, exposure);
//return RomBinDaHouseToneMapping(color, exposure);
//return filmicToneMapping(color, exposure);
return filmicToneMapping(color, exposure);
//return Uncharted2ToneMapping(color, exposure);
return jToneMapping(color, exposure);
//return jToneMapping(color, exposure);
}
+28
View File
@@ -727,6 +727,34 @@ void ABufferRenderer::setGamma(float gamma) {
}
}
void ABufferRenderer::setMaxWhite(float maxWhite) {
_maxWhite = maxWhite;
}
void ABufferRenderer::setToneMapOperator(int tmOp) {
_toneMapOperator = tmpOp;
};
void ABufferRenderer::setToneMapOperator(int tmOp) {
_toneMapOperator = tmOp;
}
void ABufferRenderer::setBloomThreMin(float minV) {
_bloomThresholdMin = minV;
}
void ABufferRenderer::setBloomThreMax(float maxV) {
_bloomThresholdMax = maxV;
}
void ABufferRenderer::setBloomOrigFactor(float origFactor) {
_bloomOrigFactor = origFactor;
}
void ABufferRenderer::setBloomNewFactor(float newFactor) {
_bloomNewFactor = newFactor;
}
float ABufferRenderer::hdrBackground() const {
return _hdrBackground;
}
+445 -38
View File
@@ -55,6 +55,16 @@ namespace {
"mainColorTexture", "blackoutFactor", "nAaSamples"
};
constexpr const std::array<const char*, 8> HDRUniformNames = {
"deferredResultsTexture", "blackoutFactor", "backgroundConstant",
"backgroundExposure", "gamma", "toneMapOperator", "aveLum", "maxWhite"
};
constexpr const std::array<const char*, 6> BLoomUniformNames = {
"renderedImage", "bloomImage", "bloomThresholdMin", "bloomThresholdMax",
"bloomOrigFactor", "bloomNewFactor"
};
constexpr const char* ExitFragmentShaderPath =
"${SHADERS}/framebuffer/exitframebuffer.frag";
constexpr const char* RaycastFragmentShaderPath =
@@ -127,6 +137,7 @@ void FramebufferRenderer::initialize() {
// Main framebuffer
glGenTextures(1, &_mainColorTexture);
glGenTextures(1, &_mainDepthTexture);
glGenTextures(1, &_mainFilterTexture);
glGenFramebuffers(1, &_mainFramebuffer);
// Exit framebuffer
@@ -134,16 +145,27 @@ void FramebufferRenderer::initialize() {
glGenTextures(1, &_exitDepthTexture);
glGenFramebuffers(1, &_exitFramebuffer);
// Deferred framebuffer
glGenTextures(1, &_deferredColorTexture);
// Deferred textures
glGenTextures(1, &_mainPositionTexture);
glGenTextures(1, &_mainNormalTexture);
glGenFramebuffers(1, &_deferredFramebuffer);
// HDR / Filtering Framebuffer
glGenFramebuffers(1, &_hdrFilteringFramebuffer);
glGenTextures(1, &_hdrFilteringTexture);
// Compute Average Luminosity
glGenTextures(1, &_computeAveLumTexture);
glGenFramebuffers(1, &_computeAveLumFBO);
// Bloom Filter
glGenFramebuffers(3, _bloomFilterFBO);
glGenTextures(3, _bloomTexture);
updateResolution();
updateRendererData();
updateRaycastData();
updateRaycastData();
// Builds Main Framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
@@ -152,7 +174,6 @@ void FramebufferRenderer::initialize() {
_mainColorTexture,
0
);
// G-buffer
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
@@ -167,6 +188,13 @@ void FramebufferRenderer::initialize() {
_mainNormalTexture,
0
);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT3,
GL_TEXTURE_2D_MULTISAMPLE,
_mainFilterTexture,
0
);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
@@ -180,6 +208,7 @@ void FramebufferRenderer::initialize() {
LERROR("Main framebuffer is not complete");
}
// Builds Exit Framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
@@ -201,23 +230,59 @@ void FramebufferRenderer::initialize() {
LERROR("Exit framebuffer is not complete");
}
glBindFramebuffer(GL_FRAMEBUFFER, _deferredFramebuffer);
// Builds HDR/Filtering Framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _hdrFilteringFramebuffer);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
_deferredColorTexture,
_hdrFilteringTexture,
0
);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Deferred framebuffer is not complete");
LERROR("HDR/Filtering framebuffer is not complete");
}
// Buids Average Lum FBO
glBindFramebuffer(GL_FRAMEBUFFER, _computeAveLumFBO);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
_computeAveLumTexture,
0
);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Average Luminosity framebuffer is not complete");
}
// Builds Bloom Filter FBOs
//const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
const GLenum buffers[] = { GL_COLOR_ATTACHMENT0 };
for (int i = 0; i < 3; i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[i]);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _bloomTexture[i], 0);
glDrawBuffers(1, buffers);
}
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Bloom framebuffer is not complete");
}
// JCC: Moved to here to avoid NVidia: "Program/shader state performance warning"
updateHDRData();
// Builds HDR and Filtering programs
updateHDRAndFiltering();
updateAveLum();
updateBloomConfig();
// Builds deferred casters programs
updateDeferredcastData();
_dirtyMsaaSamplingPattern = true;
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
@@ -228,8 +293,21 @@ void FramebufferRenderer::initialize() {
absPath("${SHADERS}/framebuffer/resolveframebuffer.frag")
);
ghoul::opengl::updateUniformLocations(*_resolveProgram, _uniformCache, UniformNames);
ghoul::opengl::updateUniformLocations(
*_resolveProgram,
_uniformCache,
UniformNames
);
ghoul::opengl::updateUniformLocations(
*_hdrFilteringProgram,
_hdrUniformCache,
HDRUniformNames
);
ghoul::opengl::updateUniformLocations(
*_bloomResolveProgram,
_bloomUniformCache,
BLoomUniformNames
);
global::raycasterManager.addListener(*this);
global::deferredcasterManager.addListener(*this);
}
@@ -239,15 +317,18 @@ void FramebufferRenderer::deinitialize() {
glDeleteFramebuffers(1, &_mainFramebuffer);
glDeleteFramebuffers(1, &_exitFramebuffer);
glDeleteFramebuffers(1, &_deferredFramebuffer);
glDeleteFramebuffers(1, &_hdrFilteringFramebuffer);
glDeleteFramebuffers(1, &_computeAveLumFBO);
glDeleteFramebuffers(3, _bloomFilterFBO);
glDeleteTextures(1, &_mainColorTexture);
glDeleteTextures(1, &_mainDepthTexture);
// DEBUG: deferred g-buffer
glDeleteTextures(1, &_deferredColorTexture);
glDeleteTextures(1, &_hdrFilteringTexture);
glDeleteTextures(1, &_mainPositionTexture);
glDeleteTextures(1, &_mainNormalTexture);
glDeleteTextures(1, &_computeAveLumTexture);
glDeleteTextures(3, _bloomTexture);
glDeleteTextures(1, &_exitColorTexture);
glDeleteTextures(1, &_exitDepthTexture);
@@ -271,6 +352,155 @@ void FramebufferRenderer::deferredcastersChanged(Deferredcaster&,
_dirtyDeferredcastData = true;
}
float FramebufferRenderer::computeBufferAveLuminance() {
unsigned int texDimension = _resolution.x * _resolution.y;
std::unique_ptr<GLfloat[]> texData(new GLfloat[texDimension * 3]);
ghoul::opengl::TextureUnit hdrTextureUnit;
hdrTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _hdrFilteringTexture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, texData.get());
float sum = 0.0f;
for (unsigned int i = 0; i < texDimension; i++) {
float lum = glm::dot(
glm::vec3(texData[i * 3 + 0], texData[i * 3 + 1], texData[i * 3 + 2]),
glm::vec3(0.2126f, 0.7152f, 0.0722f)
);
sum += logf(lum + 0.00001f);
}
return expf(sum / texDimension);
}
float FramebufferRenderer::computeBufferAveLuminanceGPU() {
// Capture standard fbo
GLint defaultFbo;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
glBindFramebuffer(GL_FRAMEBUFFER, _computeAveLumFBO);
GLenum textureBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, textureBuffers);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 1, 1);
_aveLumProgram->activate();
//float averageLuminaceInFB = computeBufferAveLuminance();
//std::cout << "=== Average Lum on CPU = " << averageLuminaceInFB << " ===" << std::endl;
ghoul::opengl::TextureUnit hdrTextureUnit;
hdrTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _hdrFilteringTexture);
_aveLumProgram->setUniform("hdrTexture", hdrTextureUnit);
_aveLumProgram->setUniform("bufferWidth", _resolution.x);
_aveLumProgram->setUniform("bufferHeight", _resolution.y);
glBindVertexArray(_screenQuad);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
_aveLumProgram->deactivate();
std::vector<double> gpuAveLum;
saveTextureToMemory(GL_COLOR_ATTACHMENT0, 1, 1, gpuAveLum);
//std::cout << "=== Average Lum on GPU = " << gpuAveLum[0] << " ===" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
glViewport(0, 0, _resolution.x, _resolution.y);
return static_cast<float>(gpuAveLum[0]);
}
void FramebufferRenderer::applyBloomFilter() {
GLint defaultFbo;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[0]);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, _resolution.y, _resolution.x);
glBindVertexArray(vao);
_bloomProgram->activate();
{
ghoul::opengl::TextureUnit filterTextureUnit;
filterTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainFilterTexture);
_bloomProgram->setUniform("pass", 1);
_bloomProgram->setUniform("filterImage", filterTextureUnit);
ghoul::opengl::TextureUnit dummyTextureUnit;
dummyTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _bloomTexture[0]);
_bloomProgram->setUniform("filterFirstPass", dummyTextureUnit);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[1]);
glViewport(0, 0, _resolution.x, _resolution.y);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
{
ghoul::opengl::TextureUnit filterTextureUnit;
filterTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _bloomTexture[0]);
_bloomProgram->setUniform("pass", 2);
_bloomProgram->setUniform("filterFirstPass", filterTextureUnit);
ghoul::opengl::TextureUnit dummyTextureUnit;
_bloomProgram->setUniform("filterImage", dummyTextureUnit);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
_bloomProgram->deactivate();
glBindFramebuffer(GL_FRAMEBUFFER, _bloomFilterFBO[2]);
glViewport(0, 0, _resolution.x, _resolution.y);
glClear(GL_COLOR_BUFFER_BIT);
_bloomResolveProgram->activate();
{
ghoul::opengl::TextureUnit deferredResultsTextureUnit;
deferredResultsTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _hdrFilteringTexture);
_bloomResolveProgram->setUniform(
_bloomUniformCache.renderedImage,
deferredResultsTextureUnit
);
ghoul::opengl::TextureUnit bloomTextureUnit;
bloomTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _bloomTexture[1]);
_bloomResolveProgram->setUniform(_bloomUniformCache.bloomImage, bloomTextureUnit);
_bloomResolveProgram->setUniform(
_bloomUniformCache.bloomOrigFactor,
_bloomOrigFactor
);
_bloomResolveProgram->setUniform(
_bloomUniformCache.bloomNewFactor,
_bloomNewFactor
);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
_bloomResolveProgram->deactivate();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
}
void FramebufferRenderer::update() {
if (_dirtyMsaaSamplingPattern) {
updateMSAASamplingPattern();
@@ -289,12 +519,6 @@ void FramebufferRenderer::update() {
updateDeferredcastData();
}
// If the resolve dictionary changed (or a file changed on disk)
// then rebuild the resolve program.
if (_hdrBackGroundProgram && _hdrBackGroundProgram->isDirty()) {
_hdrBackGroundProgram->rebuildFromFile();
}
if (_resolveProgram->isDirty()) {
_resolveProgram->rebuildFromFile();
@@ -303,6 +527,34 @@ void FramebufferRenderer::update() {
_uniformCache,
UniformNames
);
}
if (_aveLumProgram->isDirty()) {
_aveLumProgram->rebuildFromFile();
}
if (_bloomProgram->isDirty()) {
_bloomProgram->rebuildFromFile();
}
if (_bloomResolveProgram->isDirty()) {
_bloomResolveProgram->rebuildFromFile();
ghoul::opengl::updateUniformLocations(
*_bloomResolveProgram,
_bloomUniformCache,
BLoomUniformNames
);
}
if (_hdrFilteringProgram->isDirty()) {
_hdrFilteringProgram->rebuildFromFile();
ghoul::opengl::updateUniformLocations(
*_hdrFilteringProgram,
_hdrUniformCache,
HDRUniformNames
);
}
using K = VolumeRaycaster*;
@@ -362,14 +614,25 @@ void FramebufferRenderer::updateResolution() {
glTexImage2DMultisample(
GL_TEXTURE_2D_MULTISAMPLE,
_nAaSamples,
GL_RGBA,
GL_RGBA32F,
_resolution.x,
_resolution.y,
true
);
// G-buffer
glBindTexture(GL_TEXTURE_2D, _deferredColorTexture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainFilterTexture);
glTexImage2DMultisample(
GL_TEXTURE_2D_MULTISAMPLE,
_nAaSamples,
GL_RGBA32F,
_resolution.x,
_resolution.y,
true
);
// HDR / Filtering
glBindTexture(GL_TEXTURE_2D, _hdrFilteringTexture);
glTexImage2D(
GL_TEXTURE_2D,
@@ -386,6 +649,36 @@ void FramebufferRenderer::updateResolution() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Average Luminosity Computation Texture
glBindTexture(GL_TEXTURE_2D, _computeAveLumTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA32F,
1,
1,
0,
GL_RGBA,
GL_FLOAT,
nullptr
);
// Bloom Filter
for (int i = 0; i < 3; i++)
{
glBindTexture(GL_TEXTURE_2D, _bloomTexture[i]);
glTexStorage2D(
GL_TEXTURE_2D,
1,
GL_RGBA16F,
i ? _resolution.x : _resolution.y,
i ? _resolution.y : _resolution.x
);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture);
glTexImage2DMultisample(
@@ -422,7 +715,7 @@ void FramebufferRenderer::updateResolution() {
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA16,
GL_RGBA16F,
_resolution.x,
_resolution.y,
0,
@@ -577,15 +870,45 @@ void FramebufferRenderer::updateDeferredcastData() {
_dirtyDeferredcastData = false;
}
void FramebufferRenderer::updateHDRData() {
_hdrBackGroundProgram = ghoul::opengl::ProgramObject::Build(
"HDR Background Control",
absPath("${SHADERS}/framebuffer/hdrBackground.vert"),
absPath("${SHADERS}/framebuffer/hdrBackground.frag")
void FramebufferRenderer::updateAveLum() {
_aveLumProgram = ghoul::opengl::ProgramObject::Build(
"Computes Average Luminace on GPU",
absPath("${SHADERS}/framebuffer/computeAveLum.vert"),
absPath("${SHADERS}/framebuffer/computeAveLum.frag")
);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_hdrBackGroundProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
_hdrBackGroundProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
//_aveLumProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
//_aveLumProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
}
void FramebufferRenderer::updateBloomConfig() {
_bloomProgram = ghoul::opengl::ProgramObject::Build(
"Appies the Bloom Filter",
absPath("${SHADERS}/framebuffer/bloomFilter.vert"),
absPath("${SHADERS}/framebuffer/bloomFilter.frag")
);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
//_bloomProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
//_bloomProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
_bloomResolveProgram = ghoul::opengl::ProgramObject::Build(
"Adds bloom to final image",
absPath("${SHADERS}/framebuffer/bloomResolveFilter.vert"),
absPath("${SHADERS}/framebuffer/bloomResolveFilter.frag")
);
//_bloomResolveProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
//_bloomResolveProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
}
void FramebufferRenderer::updateHDRAndFiltering() {
_hdrFilteringProgram = ghoul::opengl::ProgramObject::Build(
"HDR and Filtering Program",
absPath("${SHADERS}/framebuffer/hdrAndFiltering.vert"),
absPath("${SHADERS}/framebuffer/hdrAndfiltering.frag")
);
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
//_hdrFilteringProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
//_hdrFilteringProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
}
void FramebufferRenderer::updateMSAASamplingPattern() {
@@ -921,9 +1244,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
if (!scene || !camera) {
return;
}
glEnable(GL_DEPTH_TEST);
}
// Capture standard fbo
GLint defaultFbo;
@@ -932,18 +1253,20 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
glEnable(GL_DEPTH_TEST);
// deferred g-buffer
GLenum textureBuffers[3] = {
// deferred g-buffer plus filter
GLenum textureBuffers[4] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
glDrawBuffers(3, textureBuffers);
glDrawBuffers(4, textureBuffers);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnablei(GL_BLEND, 0);
glDisablei(GL_BLEND, 1);
glDisablei(GL_BLEND, 2);
glDisablei(GL_BLEND, 3);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Time time = global::timeManager.time();
@@ -977,9 +1300,11 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
performRaycasterTasks(tasks.raycasterTasks);
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
//glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
glBindFramebuffer(GL_FRAMEBUFFER, _hdrFilteringFramebuffer);
GLenum dBuffer[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, dBuffer);
glClear(GL_COLOR_BUFFER_BIT);
{
std::unique_ptr<performance::PerformanceMeasurement> perfInternal;
@@ -991,6 +1316,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
performDeferredTasks(tasks.deferredcasterTasks);
}
/*
if (tasks.deferredcasterTasks.empty()) {
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
_resolveProgram->activate();
@@ -1008,6 +1334,62 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
_resolveProgram->deactivate();
}
*/
// DEBUG - JCC
{
glDisable(GL_DEPTH_TEST);
applyBloomFilter();
float averageLuminaceInFB = 0.0;
if (_toneMapOperator ==
static_cast<int>(openspace::RenderEngine::ToneMapOperators::GLOBAL)
)
{
averageLuminaceInFB = computeBufferAveLuminanceGPU();
if (std::isnan(averageLuminaceInFB)) {
averageLuminaceInFB = 1000.0;
}
}
//float averageLuminaceInFB = 0.5;
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
glViewport(0, 0, _resolution.x, _resolution.y);
_hdrFilteringProgram->activate();
// No Bloom
/*ghoul::opengl::TextureUnit deferredResultsTextureUnit;
deferredResultsTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _hdrFilteringTexture);
_hdrFilteringProgram->setUniform(_hdrUniformCache.deferredResultsTexture,
deferredResultsTextureUnit);*/
// Bloom Enabled
ghoul::opengl::TextureUnit bloomResultsTextureUnit;
bloomResultsTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D, _bloomTexture[2]);
_hdrFilteringProgram->setUniform(_hdrUniformCache.deferredResultsTexture,
bloomResultsTextureUnit);
_hdrFilteringProgram->setUniform(_hdrUniformCache.blackoutFactor, blackoutFactor);
_hdrFilteringProgram->setUniform(_hdrUniformCache.backgroundConstant,
_hdrBackground);
_hdrFilteringProgram->setUniform(_hdrUniformCache.backgroundExposure, _hdrExposure);
_hdrFilteringProgram->setUniform(_hdrUniformCache.gamma, _gamma);
_hdrFilteringProgram->setUniform(_hdrUniformCache.toneMapOperator, _toneMapOperator);
_hdrFilteringProgram->setUniform(_hdrUniformCache.aveLum, averageLuminaceInFB);
_hdrFilteringProgram->setUniform(_hdrUniformCache.maxWhite, _maxWhite);
glBindVertexArray(_screenQuad);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
_hdrFilteringProgram->deactivate();
}
//glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
}
void FramebufferRenderer::performRaycasterTasks(const std::vector<RaycasterTask>& tasks) {
@@ -1222,6 +1604,31 @@ void FramebufferRenderer::setGamma(float gamma) {
_gamma = gamma;
}
void FramebufferRenderer::setMaxWhite(float maxWhite) {
ghoul_assert(gamma > 0.f, "Max White value must be greater than zero");
_maxWhite = maxWhite;
}
void FramebufferRenderer::setToneMapOperator(int tmOp) {
_toneMapOperator = tmOp;
}
void FramebufferRenderer::setBloomThreMin(float minV) {
_bloomThresholdMin = minV;
}
void FramebufferRenderer::setBloomThreMax(float maxV) {
_bloomThresholdMax = maxV;
}
void FramebufferRenderer::setBloomOrigFactor(float origFactor) {
_bloomOrigFactor = origFactor;
}
void FramebufferRenderer::setBloomNewFactor(float newFactor) {
_bloomNewFactor = newFactor;
}
float FramebufferRenderer::hdrBackground() const {
return _hdrBackground;
}
+99
View File
@@ -195,6 +195,43 @@ namespace {
"Gamma, is the nonlinear operation used to encode and decode luminance or "
"tristimulus values in the image."
};
constexpr openspace::properties::Property::PropertyInfo MaxWhiteInfo = {
"MaxWhite",
"Max White Value",
"Max value for white color [0.01-10.0] to be used by tone mapping operators."
};
constexpr openspace::properties::Property::PropertyInfo BloomThreshouldMinInfo = {
"BloomThreshouldMin",
"Bloom Threshould Min Value",
"Min value a pixel must have to be bloomed."
};
constexpr openspace::properties::Property::PropertyInfo BloomThreshouldMaxInfo = {
"BloomThreshouldMax",
"Bloom Threshould Max Value",
"Max value a pixel must have to be bloomed."
};
constexpr openspace::properties::Property::PropertyInfo BloomOrigColorFactorInfo = {
"BloomOrigColorFactor",
"Bloom Original Color Factor Value",
"Bloom Original Color Factor Value."
};
constexpr openspace::properties::Property::PropertyInfo BloomNewColorFactorInfo = {
"BloomNewColorFactor",
"Bloom New Color Factor Value",
"Bloom New Color Factor Value."
};
constexpr openspace::properties::Property::PropertyInfo ToneMapOperatorInfo = {
"ToneMapOperator",
"ToneMap Operator",
"ToneMap Operator is the method used to tranform the pixels using a HDR to"
"pixels using a LDR distribution."
};
} // namespace
@@ -216,6 +253,12 @@ RenderEngine::RenderEngine()
, _hdrExposure(HDRExposureInfo, 0.4f, 0.01f, 10.0f)
, _hdrBackground(BackgroundExposureInfo, 2.8f, 0.01f, 10.0f)
, _gamma(GammaInfo, 2.2f, 0.01f, 10.0f)
, _bloomThreshouldMin(BloomThreshouldMinInfo, 0.5, 0.0, 100.0)
, _bloomThreshouldMax(BloomThreshouldMaxInfo, 1.0, 0.0, 100.0)
, _bloomOrigColorFactor(BloomOrigColorFactorInfo, 1.0, 0.0, 100.0)
, _bloomNewColorFactor(BloomNewColorFactorInfo, 1.0, 0.0, 100.0)
, _maxWhite(MaxWhiteInfo, 4.f, 0.001f, 10000.0f)
, _toneMapOperator(ToneMapOperatorInfo, properties::OptionProperty::DisplayType::Dropdown)
{
_doPerformanceMeasurements.onChange([this](){
global::performanceManager.setEnabled(_doPerformanceMeasurements);
@@ -255,6 +298,62 @@ RenderEngine::RenderEngine()
});
addProperty(_gamma);
_maxWhite.onChange([this]() {
if (_renderer) {
_renderer->setMaxWhite(_maxWhite);
}
});
addProperty(_maxWhite);
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::EXPONENTIAL), "Exponential");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::LINEAR), "Linear");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::SIMPLE_REINHARD), "Simple Reinhard");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::LUM_BASED_REINHARD), "Lum based Reinhard");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::WHITE_PRESERVING), "White Preserving");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::ROM_BIN_DA_HOUSE), "RomBin da House");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::FILMIC), "Filmic");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::UNCHARTED), "Uncharted 2");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::COSTA), "Costa");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::ADAPTIVE), "Adaptive");
_toneMapOperator.addOption(static_cast<int>(ToneMapOperators::GLOBAL), "Global");
_toneMapOperator.set(8);
_toneMapOperator.onChange([this]() {
if (_renderer) {
_renderer->setToneMapOperator(_toneMapOperator);
}
});
addProperty(_toneMapOperator);
addProperty(_bloomThreshouldMin);
_bloomThreshouldMin.onChange([this]() {
if (_renderer) {
_renderer->setBloomThreMin(_bloomThreshouldMin);
}
});
addProperty(_bloomThreshouldMax);
_bloomThreshouldMax.onChange([this]() {
if (_renderer) {
_renderer->setBloomThreMax(_bloomThreshouldMax);
}
});
addProperty(_bloomOrigColorFactor);
_bloomOrigColorFactor.onChange([this]() {
if (_renderer) {
_renderer->setBloomOrigFactor(_bloomOrigColorFactor);
}
});
addProperty(_bloomNewColorFactor);
_bloomNewColorFactor.onChange([this]() {
if (_renderer) {
_renderer->setBloomNewFactor(_bloomNewColorFactor);
}
});
addProperty(_applyWarping);
_takeScreenshot.onChange([this](){