mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 10:40:09 -06:00
@@ -69,16 +69,16 @@ public:
|
||||
void updateRaycastData();
|
||||
void updateDeferredcastData();
|
||||
void updateHDRAndFiltering();
|
||||
void updateFXAA();
|
||||
|
||||
void setResolution(glm::ivec2 res) override;
|
||||
void setNAaSamples(int nAaSamples) override;
|
||||
void setHDRExposure(float hdrExposure) override;
|
||||
void setGamma(float gamma) override;
|
||||
void setHue(float hue) override;
|
||||
void setValue(float value) override;
|
||||
void setSaturation(float sat) override;
|
||||
|
||||
int nAaSamples() const override;
|
||||
void enableFXAA(bool enable) override;
|
||||
void setDisableHDR(bool disable) override;
|
||||
|
||||
void update() override;
|
||||
@@ -109,6 +109,7 @@ private:
|
||||
|
||||
void resolveMSAA(float blackoutFactor);
|
||||
void applyTMO(float blackoutFactor);
|
||||
void applyFXAA();
|
||||
|
||||
std::map<VolumeRaycaster*, RaycastData> _raycastData;
|
||||
RaycasterProgObjMap _exitPrograms;
|
||||
@@ -120,12 +121,13 @@ private:
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _hdrFilteringProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _tmoProgram;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _resolveProgram;
|
||||
UniformCache(mainColorTexture, blackoutFactor, nAaSamples) _uniformCache;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _fxaaProgram;
|
||||
|
||||
UniformCache(mainColorTexture, blackoutFactor) _uniformCache;
|
||||
UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma,
|
||||
Hue, Saturation, Value, nAaSamples) _hdrUniformCache;
|
||||
Hue, Saturation, Value) _hdrUniformCache;
|
||||
UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache;
|
||||
|
||||
GLint _defaultFBO;
|
||||
GLuint _screenQuad;
|
||||
@@ -148,19 +150,24 @@ private:
|
||||
} _pingPongBuffers;
|
||||
|
||||
struct {
|
||||
GLuint _hdrFilteringFramebuffer;
|
||||
GLuint _hdrFilteringTexture;
|
||||
GLuint hdrFilteringFramebuffer;
|
||||
GLuint hdrFilteringTexture;
|
||||
} _hdrBuffers;
|
||||
|
||||
struct {
|
||||
GLuint fxaaFramebuffer;
|
||||
GLuint fxaaTexture;
|
||||
} _fxaaBuffers;
|
||||
|
||||
unsigned int _pingPongIndex = 0u;
|
||||
|
||||
bool _dirtyDeferredcastData;
|
||||
bool _dirtyRaycastData;
|
||||
bool _dirtyResolution;
|
||||
bool _dirtyMsaaSamplingPattern;
|
||||
|
||||
|
||||
glm::ivec2 _resolution = glm::ivec2(0);
|
||||
int _nAaSamples;
|
||||
bool _enableFXAA = true;
|
||||
bool _disableHDR = false;
|
||||
|
||||
float _hdrExposure = 3.7f;
|
||||
|
||||
@@ -208,8 +208,9 @@ private:
|
||||
properties::BoolProperty _disableMasterRendering;
|
||||
|
||||
properties::FloatProperty _globalBlackOutFactor;
|
||||
properties::IntProperty _nAaSamples;
|
||||
|
||||
properties::BoolProperty _enableFXAA;
|
||||
|
||||
properties::BoolProperty _disableHDRPipeline;
|
||||
properties::FloatProperty _hdrExposure;
|
||||
properties::FloatProperty _gamma;
|
||||
|
||||
@@ -49,13 +49,12 @@ public:
|
||||
virtual void deinitialize() = 0;
|
||||
|
||||
virtual void setResolution(glm::ivec2 res) = 0;
|
||||
virtual void setNAaSamples(int nAaSamples) = 0;
|
||||
virtual void setHDRExposure(float hdrExposure) = 0;
|
||||
virtual void setGamma(float gamma) = 0;
|
||||
virtual void setHue(float hue) = 0;
|
||||
virtual void setValue(float value) = 0;
|
||||
virtual void setSaturation(float sat) = 0;
|
||||
virtual int nAaSamples() const = 0;
|
||||
virtual void enableFXAA(bool enable) = 0;
|
||||
virtual void setDisableHDR(bool disable) = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,15 +65,16 @@
|
||||
|
||||
out vec4 renderTarget;
|
||||
in vec3 interpolatedNDCPos;
|
||||
in vec2 texCoord;
|
||||
|
||||
uniform int nAaSamples;
|
||||
uniform int cullAtmosphere;
|
||||
|
||||
uniform sampler2D irradianceTexture;
|
||||
uniform sampler3D inscatterTexture;
|
||||
uniform sampler2DMS mainPositionTexture;
|
||||
uniform sampler2DMS mainNormalTexture;
|
||||
uniform sampler2DMS mainColorTexture;
|
||||
uniform sampler2D mainPositionTexture;
|
||||
uniform sampler2D mainNormalTexture;
|
||||
uniform sampler2D mainColorTexture;
|
||||
|
||||
uniform dmat4 dInverseModelTransformMatrix;
|
||||
uniform dmat4 dModelTransformMatrix;
|
||||
@@ -230,7 +231,7 @@ bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const d
|
||||
* This method avoids matrices multiplications
|
||||
* wherever is possible.
|
||||
*/
|
||||
void dCalculateRayRenderableGlobe(in int mssaSample, out dRay ray,
|
||||
void dCalculateRayRenderableGlobe(out dRay ray,
|
||||
out dvec4 planetPositionObjectCoords,
|
||||
out dvec4 cameraPositionInObject) {
|
||||
dvec4 clipCoords = dvec4(interpolatedNDCPos.xy, 1.0, 1.0);
|
||||
@@ -529,8 +530,6 @@ vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const flo
|
||||
}
|
||||
|
||||
void main() {
|
||||
ivec2 fragCoords = ivec2(gl_FragCoord);
|
||||
|
||||
if (cullAtmosphere == 0) {
|
||||
vec4 atmosphereFinalColor = vec4(0.0f);
|
||||
int nSamples = 1;
|
||||
@@ -538,153 +537,141 @@ void main() {
|
||||
// First we determine if the pixel is complex (different fragments on it)
|
||||
bool complex = false;
|
||||
vec4 oldColor, currentColor;
|
||||
vec4 colorArray[16];
|
||||
vec4 colorTexture;
|
||||
|
||||
colorArray[0] = texelFetch(mainColorTexture, fragCoords, 0);
|
||||
for (int i = 1; i < nAaSamples; i++) {
|
||||
colorArray[i] = texelFetch(mainColorTexture, fragCoords, i);
|
||||
if (colorArray[i] != colorArray[i-1]) {
|
||||
complex = true;
|
||||
}
|
||||
}
|
||||
nSamples = complex ? nAaSamples / 2 : 1;
|
||||
colorTexture = texture(mainColorTexture, texCoord);
|
||||
|
||||
for (int i = 0; i < nSamples; i++) {
|
||||
// Color from G-Buffer
|
||||
vec4 color = colorArray[i];
|
||||
// Ray in object space
|
||||
dRay ray;
|
||||
dvec4 planetPositionObjectCoords = dvec4(0.0);
|
||||
dvec4 cameraPositionInObject = dvec4(0.0);
|
||||
// Color from G-Buffer
|
||||
vec4 color = colorTexture;
|
||||
// Ray in object space
|
||||
dRay ray;
|
||||
dvec4 planetPositionObjectCoords = dvec4(0.0);
|
||||
dvec4 cameraPositionInObject = dvec4(0.0);
|
||||
|
||||
// Get the ray from camera to atm in object space
|
||||
dCalculateRayRenderableGlobe(ray, planetPositionObjectCoords,
|
||||
cameraPositionInObject);
|
||||
|
||||
bool insideATM = false;
|
||||
double offset = 0.0; // in Km
|
||||
double maxLength = 0.0; // in Km
|
||||
|
||||
bool intersectATM = false;
|
||||
|
||||
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray,
|
||||
Rt - (ATM_EPSILON * 0.001), insideATM, offset, maxLength);
|
||||
|
||||
// Get the ray from camera to atm in object space
|
||||
dCalculateRayRenderableGlobe(i * 3, ray, planetPositionObjectCoords,
|
||||
cameraPositionInObject);
|
||||
|
||||
bool insideATM = false;
|
||||
double offset = 0.0; // in Km
|
||||
double maxLength = 0.0; // in Km
|
||||
if ( intersectATM ) {
|
||||
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
|
||||
// in the G-Buffer positions is less than the distance to the atmosphere then the atmosphere
|
||||
// is occluded
|
||||
// Fragments positions into G-Buffer are written in SGCT Eye Space (View plus Camera Rig Coords)
|
||||
// when using their positions later, one must convert them to the planet's coords
|
||||
|
||||
// Get data from G-Buffer
|
||||
vec4 normal = texture(mainNormalTexture, texCoord);
|
||||
// Data in the mainPositionTexture are written in view space (view plus camera rig)
|
||||
vec4 position = texture(mainPositionTexture, texCoord);
|
||||
|
||||
bool intersectATM = false;
|
||||
// OS Eye to World coords
|
||||
dvec4 positionWorldCoords = dSGCTViewToWorldMatrix * position;
|
||||
|
||||
intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray,
|
||||
Rt - (ATM_EPSILON * 0.001), insideATM, offset, maxLength);
|
||||
|
||||
if ( intersectATM ) {
|
||||
// Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel
|
||||
// in the G-Buffer positions is less than the distance to the atmosphere then the atmosphere
|
||||
// is occluded
|
||||
// Fragments positions into G-Buffer are written in SGCT Eye Space (View plus Camera Rig Coords)
|
||||
// when using their positions later, one must convert them to the planet's coords
|
||||
|
||||
// Get data from G-Buffer
|
||||
vec4 normal = texelFetch(mainNormalTexture, fragCoords, i);
|
||||
// Data in the mainPositionTexture are written in view space (view plus camera rig)
|
||||
vec4 position = texelFetch(mainPositionTexture, fragCoords, i);
|
||||
// World to Object (Normal and Position in meters)
|
||||
dvec4 positionObjectsCoords = dInverseModelTransformMatrix * positionWorldCoords;
|
||||
|
||||
// OS Eye to World coords
|
||||
dvec4 positionWorldCoords = dSGCTViewToWorldMatrix * position;
|
||||
|
||||
// Distance of the pixel in the gBuffer to the observer
|
||||
// JCC (12/12/2017): AMD distance function is buggy.
|
||||
//double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz);
|
||||
double pixelDepth = length(cameraPositionInObject.xyz - positionObjectsCoords.xyz);
|
||||
|
||||
// JCC (12/13/2017): Trick to remove floating error in texture.
|
||||
// We see a squared noise on planet's surface when seeing the planet
|
||||
// from far away.
|
||||
float dC = float(length(cameraPositionInObject.xyz));
|
||||
float x1 = 1e8;
|
||||
if (dC > x1) {
|
||||
pixelDepth += 1000.0;
|
||||
float alpha = 1000.0;
|
||||
float beta = 1000000.0;
|
||||
float x2 = 1e9;
|
||||
float diffGreek = beta - alpha;
|
||||
float diffDist = x2 - x1;
|
||||
float varA = diffGreek/diffDist;
|
||||
float varB = (alpha - varA * x1);
|
||||
pixelDepth += double(varA * dC + varB);
|
||||
}
|
||||
|
||||
// World to Object (Normal and Position in meters)
|
||||
dvec4 positionObjectsCoords = dInverseModelTransformMatrix * positionWorldCoords;
|
||||
|
||||
|
||||
// Distance of the pixel in the gBuffer to the observer
|
||||
// JCC (12/12/2017): AMD distance function is buggy.
|
||||
//double pixelDepth = distance(cameraPositionInObject.xyz, positionObjectsCoords.xyz);
|
||||
double pixelDepth = length(cameraPositionInObject.xyz - positionObjectsCoords.xyz);
|
||||
|
||||
// JCC (12/13/2017): Trick to remove floating error in texture.
|
||||
// We see a squared noise on planet's surface when seeing the planet
|
||||
// from far away.
|
||||
float dC = float(length(cameraPositionInObject.xyz));
|
||||
float x1 = 1e8;
|
||||
if (dC > x1) {
|
||||
pixelDepth += 1000.0;
|
||||
float alpha = 1000.0;
|
||||
float beta = 1000000.0;
|
||||
float x2 = 1e9;
|
||||
float diffGreek = beta - alpha;
|
||||
float diffDist = x2 - x1;
|
||||
float varA = diffGreek/diffDist;
|
||||
float varB = (alpha - varA * x1);
|
||||
pixelDepth += double(varA * dC + varB);
|
||||
}
|
||||
|
||||
// All calculations are done in Km:
|
||||
pixelDepth *= 0.001;
|
||||
positionObjectsCoords.xyz *= 0.001;
|
||||
|
||||
if (pixelDepth < offset) {
|
||||
// ATM Occluded - Something in fron of ATM.
|
||||
atmosphereFinalColor += color;
|
||||
} else {
|
||||
// Following paper nomenclature
|
||||
double t = offset;
|
||||
vec3 attenuation;
|
||||
|
||||
// Moving observer from camera location to top atmosphere
|
||||
// If the observer is already inside the atm, offset = 0.0
|
||||
// and no changes at all.
|
||||
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
|
||||
float r = 0.0f;//length(x);
|
||||
vec3 v = vec3(ray.direction.xyz);
|
||||
float mu = 0.0f;//dot(x, v) / r;
|
||||
vec3 s = vec3(sunDirectionObj);
|
||||
float tF = float(maxLength - t);
|
||||
|
||||
// Because we may move the camera origin to the top of atmosphere
|
||||
// we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the
|
||||
// next comparison with the planet's ground make sense:
|
||||
pixelDepth -= offset;
|
||||
|
||||
dvec4 onATMPos = dModelTransformMatrix * dvec4(x * 1000.0, 1.0);
|
||||
vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false);
|
||||
float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x;
|
||||
|
||||
float irradianceFactor = 0.0;
|
||||
|
||||
bool groundHit = false;
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v,
|
||||
s, r, mu, attenuation,
|
||||
vec3(positionObjectsCoords.xyz),
|
||||
groundHit, maxLength, pixelDepth,
|
||||
color, sunIntensityInscatter);
|
||||
vec3 groundColorV = vec3(0.0);
|
||||
vec3 sunColorV = vec3(0.0);
|
||||
if (groundHit) {
|
||||
vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true);
|
||||
float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x;
|
||||
groundColorV = groundColor(x, tF, v, s, r, mu, attenuation,
|
||||
color, normal.xyz, irradianceFactor,
|
||||
normal.a, sunIntensityGround);
|
||||
} else {
|
||||
// In order to get better performance, we are not tracing
|
||||
// multiple rays per pixel when the ray doesn't intersect
|
||||
// the ground.
|
||||
sunColorV = sunColor(x, tF, v, s, r, mu, irradianceFactor);
|
||||
}
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
vec4 finalRadiance = vec4(inscatterColor + groundColorV + sunColorV, 1.0);
|
||||
|
||||
atmosphereFinalColor += finalRadiance;
|
||||
}
|
||||
}
|
||||
else { // no intersection
|
||||
// Buffer color
|
||||
// All calculations are done in Km:
|
||||
pixelDepth *= 0.001;
|
||||
positionObjectsCoords.xyz *= 0.001;
|
||||
|
||||
if (pixelDepth < offset) {
|
||||
// ATM Occluded - Something in fron of ATM.
|
||||
atmosphereFinalColor += color;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Following paper nomenclature
|
||||
double t = offset;
|
||||
vec3 attenuation;
|
||||
|
||||
renderTarget = atmosphereFinalColor / float(nSamples);
|
||||
// Moving observer from camera location to top atmosphere
|
||||
// If the observer is already inside the atm, offset = 0.0
|
||||
// and no changes at all.
|
||||
vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz);
|
||||
float r = 0.0f;//length(x);
|
||||
vec3 v = vec3(ray.direction.xyz);
|
||||
float mu = 0.0f;//dot(x, v) / r;
|
||||
vec3 s = vec3(sunDirectionObj);
|
||||
float tF = float(maxLength - t);
|
||||
|
||||
// Because we may move the camera origin to the top of atmosphere
|
||||
// we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the
|
||||
// next comparison with the planet's ground make sense:
|
||||
pixelDepth -= offset;
|
||||
|
||||
dvec4 onATMPos = dModelTransformMatrix * dvec4(x * 1000.0, 1.0);
|
||||
vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false);
|
||||
float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x;
|
||||
|
||||
float irradianceFactor = 0.0;
|
||||
|
||||
bool groundHit = false;
|
||||
vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v,
|
||||
s, r, mu, attenuation,
|
||||
vec3(positionObjectsCoords.xyz),
|
||||
groundHit, maxLength, pixelDepth,
|
||||
color, sunIntensityInscatter);
|
||||
vec3 groundColorV = vec3(0.0);
|
||||
vec3 sunColorV = vec3(0.0);
|
||||
if (groundHit) {
|
||||
vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true);
|
||||
float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x;
|
||||
groundColorV = groundColor(x, tF, v, s, r, mu, attenuation,
|
||||
color, normal.xyz, irradianceFactor,
|
||||
normal.a, sunIntensityGround);
|
||||
} else {
|
||||
// In order to get better performance, we are not tracing
|
||||
// multiple rays per pixel when the ray doesn't intersect
|
||||
// the ground.
|
||||
sunColorV = sunColor(x, tF, v, s, r, mu, irradianceFactor);
|
||||
}
|
||||
|
||||
// Final Color of ATM plus terrain:
|
||||
vec4 finalRadiance = vec4(inscatterColor + groundColorV + sunColorV, 1.0);
|
||||
|
||||
atmosphereFinalColor += finalRadiance;
|
||||
}
|
||||
}
|
||||
else { // no intersection
|
||||
// Buffer color
|
||||
atmosphereFinalColor += color;
|
||||
}
|
||||
|
||||
|
||||
renderTarget = atmosphereFinalColor;
|
||||
}
|
||||
else { // culling
|
||||
vec4 bColor = vec4(0.0f);
|
||||
for (int f = 0; f < nAaSamples; f++) {
|
||||
bColor += texelFetch(mainColorTexture, fragCoords, f);
|
||||
}
|
||||
bColor /= float(nAaSamples);
|
||||
vec4 bColor = texture(mainColorTexture, texCoord);
|
||||
renderTarget = bColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
layout(location = 0) in vec4 in_position;
|
||||
|
||||
out vec3 interpolatedNDCPos;
|
||||
out vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
texCoord = 0.5 + in_position.xy * 0.5;
|
||||
interpolatedNDCPos = in_position.xyz;
|
||||
gl_Position = in_position;
|
||||
}
|
||||
|
||||
@@ -361,6 +361,8 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
glBindVertexArray(info._vaoID);
|
||||
if (renderLines) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
p->setUniform(c.renderPhase, RenderPhaseLines);
|
||||
// Subclasses of this renderer might be using the index array or might now be
|
||||
// so we check if there is data available and if there isn't, we use the
|
||||
@@ -380,6 +382,7 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
reinterpret_cast<void*>(info.first * sizeof(unsigned int))
|
||||
);
|
||||
}
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
if (renderPoints) {
|
||||
// Subclasses of this renderer might be using the index array or might now be
|
||||
|
||||
233
shaders/framebuffer/fxaa.frag
Normal file
233
shaders/framebuffer/fxaa.frag
Normal file
@@ -0,0 +1,233 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* 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__
|
||||
|
||||
#define EDGE_THRESHOLD_MIN 0.0312f
|
||||
#define EDGE_THRESHOLD_MAX 0.125f
|
||||
#define ITERATIONS 12
|
||||
#define SUBPIXEL_QUALITY 0.75f
|
||||
|
||||
const float[12] QUALITY = {1.f, 1.f, 1.f, 1.f, 1.f, 1.5f, 2.f, 2.f, 2.f, 2.f, 4.f, 8.f};
|
||||
// const float[24] QUALITY = {2.f, 4.f, 6.f, 8.f, 10.f, 12.f, 12.f, 12.f, 12.f, 12.f, 14.f, 18.f,
|
||||
// 18.f, 18.f, 18.f, 18.f, 18.f, 18.f, 18.f, 18.f, 18.f, 18.f,
|
||||
// 18.f, 18.f};
|
||||
|
||||
layout (location = 0) out vec4 aaFinalColor;
|
||||
|
||||
uniform vec2 inverseScreenSize;
|
||||
uniform sampler2D renderedTexture;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
// Relative luminance
|
||||
float getLum(vec3 rgb){
|
||||
return dot(vec3(0.2126, 0.7152, 0.0722), rgb);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 colorCenter = texture(renderedTexture,texCoord);
|
||||
|
||||
// ============================
|
||||
// Detecting where to apply AA:
|
||||
// ============================
|
||||
|
||||
float pixelLumCenter = getLum(colorCenter.rgb);
|
||||
float pixelLumDown = getLum(textureOffset(renderedTexture, texCoord, ivec2(0,-1)).rgb);
|
||||
float pixelLumUp = getLum(textureOffset(renderedTexture, texCoord, ivec2(0,1)).rgb);
|
||||
float pixelLumLeft = getLum(textureOffset(renderedTexture, texCoord, ivec2(-1,0)).rgb);
|
||||
float pixelLumRight = getLum(textureOffset(renderedTexture, texCoord, ivec2(1,0)).rgb);
|
||||
|
||||
float pixelLumMin = min(pixelLumCenter, min(min(pixelLumDown, pixelLumUp), min(pixelLumLeft, pixelLumRight)));
|
||||
float pixelLumMax = max(pixelLumCenter, max(max(pixelLumDown, pixelLumUp), max(pixelLumLeft, pixelLumRight)));
|
||||
|
||||
// Delta.
|
||||
float pixelLumRange = pixelLumMax - pixelLumMin;
|
||||
|
||||
// If the pixelLum variation is lower that a threshold (or if we are in a really dark area),
|
||||
// we are not on an edge, don't perform any AA.
|
||||
if (pixelLumRange < max(EDGE_THRESHOLD_MIN, pixelLumMax * EDGE_THRESHOLD_MAX)) {
|
||||
aaFinalColor = colorCenter;
|
||||
return;
|
||||
}
|
||||
|
||||
// ============================
|
||||
// Estimating the gradient:
|
||||
// ============================
|
||||
float pixelLumDownLeft = getLum(textureOffset(renderedTexture, texCoord, ivec2(-1,-1)).rgb);
|
||||
float pixelLumUpRight = getLum(textureOffset(renderedTexture, texCoord, ivec2(1,1)).rgb);
|
||||
float pixelLumUpLeft = getLum(textureOffset(renderedTexture, texCoord, ivec2(-1,1)).rgb);
|
||||
float pixelLumDownRight = getLum(textureOffset(renderedTexture, texCoord, ivec2(1,-1)).rgb);
|
||||
|
||||
float pixelLumDownUp = pixelLumDown + pixelLumUp;
|
||||
float pixelLumLeftRight = pixelLumLeft + pixelLumRight;
|
||||
float pixelLumLeftCorners = pixelLumDownLeft + pixelLumUpLeft;
|
||||
float pixelLumDownCorners = pixelLumDownLeft + pixelLumDownRight;
|
||||
float pixelLumRightCorners = pixelLumDownRight + pixelLumUpRight;
|
||||
float pixelLumUpCorners = pixelLumUpRight + pixelLumUpLeft;
|
||||
|
||||
// Compute an estimation of the gradient
|
||||
float edgeHorizontal = abs(-2.0 * pixelLumLeft + pixelLumLeftCorners) +
|
||||
abs(-2.0 * pixelLumCenter + pixelLumDownUp ) * 2.0 + abs(-2.0 * pixelLumRight + pixelLumRightCorners);
|
||||
float edgeVertical = abs(-2.0 * pixelLumUp + pixelLumUpCorners) +
|
||||
abs(-2.0 * pixelLumCenter + pixelLumLeftRight) * 2.0 + abs(-2.0 * pixelLumDown + pixelLumDownCorners);
|
||||
|
||||
// ============================
|
||||
// Choosing Edge Orientation:
|
||||
// ============================
|
||||
bool isHorizontal = (edgeHorizontal >= edgeVertical);
|
||||
float pixelLum1 = isHorizontal ? pixelLumDown : pixelLumLeft;
|
||||
float pixelLum2 = isHorizontal ? pixelLumUp : pixelLumRight;
|
||||
|
||||
// Gradients
|
||||
float gradient1 = pixelLum1 - pixelLumCenter;
|
||||
float gradient2 = pixelLum2 - pixelLumCenter;
|
||||
|
||||
bool is1Steepest = abs(gradient1) >= abs(gradient2);
|
||||
float gradientScaled = 0.25 * max(abs(gradient1), abs(gradient2));
|
||||
|
||||
// Step size (one pixel) according to the edge direction.
|
||||
float stepLength = isHorizontal ? inverseScreenSize.y : inverseScreenSize.x;
|
||||
|
||||
float pixelLumLocalAverage = 0.0;
|
||||
|
||||
if (is1Steepest) {
|
||||
stepLength = - stepLength;
|
||||
pixelLumLocalAverage = 0.5 * (pixelLum1 + pixelLumCenter);
|
||||
} else {
|
||||
pixelLumLocalAverage = 0.5 * (pixelLum2 + pixelLumCenter);
|
||||
}
|
||||
|
||||
vec2 currentUv = texCoord;
|
||||
if (isHorizontal) {
|
||||
currentUv.y += stepLength * 0.5;
|
||||
} else {
|
||||
currentUv.x += stepLength * 0.5;
|
||||
}
|
||||
|
||||
// ============================
|
||||
// Iterations:
|
||||
// ============================
|
||||
vec2 offset = isHorizontal ? vec2(inverseScreenSize.x, 0.0) : vec2(0.0, inverseScreenSize.y);
|
||||
|
||||
vec2 uv1 = currentUv - offset;
|
||||
vec2 uv2 = currentUv + offset;
|
||||
|
||||
// Read the pixelLums at both current extremities of the exploration segment,
|
||||
// and compute the delta wrt to the local average pixelLum.
|
||||
float pixelLumEnd1 = getLum(texture(renderedTexture, uv1).rgb);
|
||||
float pixelLumEnd2 = getLum(texture(renderedTexture, uv2).rgb);
|
||||
pixelLumEnd1 -= pixelLumLocalAverage;
|
||||
pixelLumEnd2 -= pixelLumLocalAverage;
|
||||
|
||||
bool reached1 = abs(pixelLumEnd1) >= gradientScaled;
|
||||
bool reached2 = abs(pixelLumEnd2) >= gradientScaled;
|
||||
bool reachedBoth = reached1 && reached2;
|
||||
|
||||
if (!reached1) {
|
||||
uv1 -= offset;
|
||||
}
|
||||
|
||||
if (!reached2) {
|
||||
uv2 += offset;
|
||||
}
|
||||
|
||||
// Still exploring
|
||||
if (!reachedBoth) {
|
||||
for (int i = 2; i < ITERATIONS; i++) {
|
||||
// If needed, read pixelLum in 1st direction, compute delta.
|
||||
if (!reached1) {
|
||||
pixelLumEnd1 = getLum(texture(renderedTexture, uv1).rgb);
|
||||
pixelLumEnd1 = pixelLumEnd1 - pixelLumLocalAverage;
|
||||
}
|
||||
// If needed, read pixelLum in opposite direction, compute delta.
|
||||
if (!reached2) {
|
||||
pixelLumEnd2 = getLum(texture(renderedTexture, uv2).rgb);
|
||||
pixelLumEnd2 = pixelLumEnd2 - pixelLumLocalAverage;
|
||||
}
|
||||
reached1 = abs(pixelLumEnd1) >= gradientScaled;
|
||||
reached2 = abs(pixelLumEnd2) >= gradientScaled;
|
||||
reachedBoth = reached1 && reached2;
|
||||
|
||||
// If the side is not reached
|
||||
if (!reached1) {
|
||||
uv1 -= offset * QUALITY[i];
|
||||
}
|
||||
|
||||
if (!reached2) {
|
||||
uv2 += offset * QUALITY[i];
|
||||
}
|
||||
|
||||
// If both sides have been reached
|
||||
if (reachedBoth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================
|
||||
// Estimating the offset:
|
||||
// ============================
|
||||
float distance1 = isHorizontal ? (texCoord.x - uv1.x) : (texCoord.y - uv1.y);
|
||||
float distance2 = isHorizontal ? (uv2.x - texCoord.x) : (uv2.y - texCoord.y);
|
||||
|
||||
bool isDirection1 = distance1 < distance2;
|
||||
float distanceFinal = min(distance1, distance2);
|
||||
|
||||
float edgeThickness = (distance1 + distance2);
|
||||
|
||||
// Read in the direction of the closest side of the edge.
|
||||
float pixelOffset = - distanceFinal / edgeThickness + 0.5;
|
||||
|
||||
bool ispixelLumCenterSmaller = pixelLumCenter < pixelLumLocalAverage;
|
||||
|
||||
// If the pixelLum at center is smaller than at its neighbour, the delta pixelLum at
|
||||
// each end should be positive (same variation).
|
||||
bool correctVariation = ((isDirection1 ? pixelLumEnd1 : pixelLumEnd2) < 0.0) != ispixelLumCenterSmaller;
|
||||
|
||||
// If the pixelLum variation is incorrect, do not offset.
|
||||
float finalOffset = correctVariation ? pixelOffset : 0.0;
|
||||
|
||||
// ============================
|
||||
// Subpixel antialiasing:
|
||||
// ============================
|
||||
float pixelLumAverage = (1.0/12.0) * (2.0 * (pixelLumDownUp + pixelLumLeftRight) +
|
||||
pixelLumLeftCorners + pixelLumRightCorners);
|
||||
|
||||
float subPixelOffset1 = clamp(abs(pixelLumAverage - pixelLumCenter) / pixelLumRange, 0.0, 1.0);
|
||||
float subPixelOffset2 = (-2.0 * subPixelOffset1 + 3.0) * subPixelOffset1 * subPixelOffset1;
|
||||
float subPixelOffsetFinal = subPixelOffset2 * subPixelOffset2 * SUBPIXEL_QUALITY;
|
||||
|
||||
// Biggest of the two offsets.
|
||||
finalOffset = max(finalOffset, subPixelOffsetFinal);
|
||||
|
||||
vec2 finalUV = texCoord;
|
||||
if (isHorizontal) {
|
||||
finalUV.y += finalOffset * stepLength;
|
||||
} else {
|
||||
finalUV.x += finalOffset * stepLength;
|
||||
}
|
||||
|
||||
aaFinalColor = texture(renderedTexture, finalUV);
|
||||
}
|
||||
33
shaders/framebuffer/fxaa.vert
Normal file
33
shaders/framebuffer/fxaa.vert
Normal file
@@ -0,0 +1,33 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2019 *
|
||||
* *
|
||||
* 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;
|
||||
}
|
||||
@@ -40,19 +40,12 @@ uniform float Value;
|
||||
uniform float Lightness;
|
||||
uniform int nAaSamples;
|
||||
|
||||
uniform sampler2DMS hdrFeedingTexture;
|
||||
uniform sampler2D hdrFeedingTexture;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
void main() {
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
// Resolving...
|
||||
for (int i = 0; i < nAaSamples; i++) {
|
||||
color += texelFetch(hdrFeedingTexture, ivec2(gl_FragCoord), i);
|
||||
}
|
||||
|
||||
color /= nAaSamples;
|
||||
vec4 color = texture(hdrFeedingTexture, texCoord);
|
||||
color.rgb *= blackoutFactor;
|
||||
|
||||
// Applies TMO
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
uniform sampler2D exitColorTexture;
|
||||
uniform sampler2D exitDepthTexture;
|
||||
uniform sampler2DMS mainDepthTexture;
|
||||
uniform sampler2D mainDepthTexture;
|
||||
|
||||
uniform bool insideRaycaster;
|
||||
uniform vec3 cameraPosInRaycaster;
|
||||
@@ -46,9 +46,6 @@ out vec4 finalColor;
|
||||
|
||||
#define ALPHA_LIMIT 0.99
|
||||
#define RAYCAST_MAX_STEPS 1000
|
||||
#define MAX_AA_SAMPLES 8
|
||||
|
||||
uniform int nAaSamples;
|
||||
|
||||
#include <#{getEntryPath}>
|
||||
|
||||
@@ -76,25 +73,12 @@ void main() {
|
||||
vec3 direction = normalize(diff);
|
||||
float raycastDepth = length(diff);
|
||||
|
||||
float raycastDepths[MAX_AA_SAMPLES];
|
||||
|
||||
int i, j;
|
||||
float tmp;
|
||||
|
||||
for (i = 0; i < nAaSamples; i++) {
|
||||
float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x);
|
||||
float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0);
|
||||
raycastDepths[i] = geoRatio * raycastDepth;
|
||||
}
|
||||
|
||||
for(i = 1; i < nAaSamples; ++i) {
|
||||
tmp = raycastDepths[i];
|
||||
for(j = i; j > 0 && tmp < raycastDepths[j - 1]; --j) {
|
||||
raycastDepths[j] = raycastDepths[j-1];
|
||||
}
|
||||
raycastDepths[j] = tmp;
|
||||
}
|
||||
|
||||
float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x);
|
||||
float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0);
|
||||
raycastDepth = geoRatio * raycastDepth;
|
||||
|
||||
float currentDepth = 0.0;
|
||||
// todo: shorten depth if geometry is intersecting!
|
||||
@@ -106,20 +90,20 @@ void main() {
|
||||
|
||||
float aaOpacity = 1.0;
|
||||
int sampleIndex = 0;
|
||||
float opacityDecay = 1.0 / nAaSamples;
|
||||
float opacityDecay = 1.0;
|
||||
|
||||
vec3 accumulatedColor = vec3(0.0);
|
||||
vec3 accumulatedAlpha = vec3(0.0);
|
||||
|
||||
|
||||
for (steps = 0; (accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT || accumulatedAlpha.b < ALPHA_LIMIT) && steps < RAYCAST_MAX_STEPS; ++steps) {
|
||||
while (sampleIndex < nAaSamples && currentDepth + nextStepSize * jitterFactor > raycastDepths[sampleIndex]) {
|
||||
sampleIndex++;
|
||||
for (steps = 0; (accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT ||
|
||||
accumulatedAlpha.b < ALPHA_LIMIT) && steps < RAYCAST_MAX_STEPS; ++steps) {
|
||||
if (currentDepth + nextStepSize * jitterFactor > raycastDepth) {
|
||||
aaOpacity -= opacityDecay;
|
||||
}
|
||||
bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0;
|
||||
|
||||
if (sampleIndex >= nAaSamples || shortStepSize) {
|
||||
if (shortStepSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -139,7 +123,7 @@ void main() {
|
||||
|
||||
previousJitterDistance = currentStepSize - jitteredStepSize;
|
||||
|
||||
float maxStepSize = raycastDepths[nAaSamples - 1] - currentDepth;
|
||||
float maxStepSize = raycastDepth - currentDepth;
|
||||
|
||||
nextStepSize = min(nextStepSize, maxStepSize);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
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();
|
||||
|
||||
@@ -50,13 +50,17 @@
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "FramebufferRenderer";
|
||||
|
||||
constexpr const std::array<const char*, 3> UniformNames = {
|
||||
"mainColorTexture", "blackoutFactor", "nAaSamples"
|
||||
constexpr const std::array<const char*, 2> UniformNames = {
|
||||
"mainColorTexture", "blackoutFactor"
|
||||
};
|
||||
|
||||
constexpr const std::array<const char*, 8> HDRUniformNames = {
|
||||
constexpr const std::array<const char*, 7> HDRUniformNames = {
|
||||
"hdrFeedingTexture", "blackoutFactor", "hdrExposure", "gamma",
|
||||
"Hue", "Saturation", "Value", "nAaSamples"
|
||||
"Hue", "Saturation", "Value"
|
||||
};
|
||||
|
||||
constexpr const std::array<const char*, 2> FXAAUniformNames = {
|
||||
"renderedTexture", "inverseScreenSize"
|
||||
};
|
||||
|
||||
constexpr const char* ExitFragmentShaderPath =
|
||||
@@ -177,8 +181,12 @@ void FramebufferRenderer::initialize() {
|
||||
glGenFramebuffers(1, &_exitFramebuffer);
|
||||
|
||||
// HDR / Filtering Buffers
|
||||
glGenFramebuffers(1, &_hdrBuffers._hdrFilteringFramebuffer);
|
||||
glGenTextures(1, &_hdrBuffers._hdrFilteringTexture);
|
||||
glGenFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer);
|
||||
glGenTextures(1, &_hdrBuffers.hdrFilteringTexture);
|
||||
|
||||
// FXAA Buffers
|
||||
glGenFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer);
|
||||
glGenTextures(1, &_fxaaBuffers.fxaaTexture);
|
||||
|
||||
// Allocate Textures/Buffers Memory
|
||||
updateResolution();
|
||||
@@ -190,31 +198,27 @@ void FramebufferRenderer::initialize() {
|
||||
//===== GBuffers Buffers =====//
|
||||
//==============================//
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_gBuffers.colorTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_gBuffers.positionTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_gBuffers.normalTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_gBuffers.depthTexture,
|
||||
0
|
||||
);
|
||||
@@ -228,24 +232,21 @@ void FramebufferRenderer::initialize() {
|
||||
//===== PingPong Buffers =====//
|
||||
//==============================//
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _pingPongBuffers.framebuffer);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_pingPongBuffers.colorTexture[0],
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_pingPongBuffers.colorTexture[1],
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_gBuffers.depthTexture,
|
||||
0
|
||||
);
|
||||
@@ -260,17 +261,15 @@ void FramebufferRenderer::initialize() {
|
||||
//======================================//
|
||||
// Builds Exit Framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
_exitColorTexture,
|
||||
0
|
||||
);
|
||||
glFramebufferTexture2D(
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D,
|
||||
_exitDepthTexture,
|
||||
0
|
||||
);
|
||||
@@ -283,12 +282,11 @@ void FramebufferRenderer::initialize() {
|
||||
//===================================//
|
||||
//===== HDR/Filtering Buffers =====//
|
||||
//===================================//
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _hdrBuffers._hdrFilteringFramebuffer);
|
||||
glFramebufferTexture2D(
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _hdrBuffers.hdrFilteringFramebuffer);
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
_hdrBuffers._hdrFilteringTexture,
|
||||
_hdrBuffers.hdrFilteringTexture,
|
||||
0
|
||||
);
|
||||
|
||||
@@ -297,13 +295,28 @@ void FramebufferRenderer::initialize() {
|
||||
LERROR("HDR/Filtering framebuffer is not complete");
|
||||
}
|
||||
|
||||
//===================================//
|
||||
//========== FXAA Buffers =========//
|
||||
//===================================//
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fxaaBuffers.fxaaFramebuffer);
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
_fxaaBuffers.fxaaTexture,
|
||||
0
|
||||
);
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERROR("FXAA framebuffer is not complete");
|
||||
}
|
||||
|
||||
// JCC: Moved to here to avoid NVidia: "Program/shader state performance warning"
|
||||
// Building programs
|
||||
updateHDRAndFiltering();
|
||||
updateFXAA();
|
||||
updateDeferredcastData();
|
||||
|
||||
_dirtyMsaaSamplingPattern = true;
|
||||
|
||||
// Sets back to default FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
|
||||
@@ -323,13 +336,17 @@ void FramebufferRenderer::initialize() {
|
||||
_hdrUniformCache,
|
||||
HDRUniformNames
|
||||
);
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_fxaaProgram,
|
||||
_fxaaUniformCache,
|
||||
FXAAUniformNames
|
||||
);
|
||||
|
||||
global::raycasterManager.addListener(*this);
|
||||
global::deferredcasterManager.addListener(*this);
|
||||
|
||||
// Default GL State for Blending
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
}
|
||||
|
||||
void FramebufferRenderer::deinitialize() {
|
||||
@@ -337,13 +354,15 @@ void FramebufferRenderer::deinitialize() {
|
||||
|
||||
glDeleteFramebuffers(1, &_gBuffers.framebuffer);
|
||||
glDeleteFramebuffers(1, &_exitFramebuffer);
|
||||
glDeleteFramebuffers(1, &_hdrBuffers._hdrFilteringFramebuffer);
|
||||
glDeleteFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer);
|
||||
glDeleteFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer);
|
||||
glDeleteFramebuffers(1, &_pingPongBuffers.framebuffer);
|
||||
|
||||
glDeleteTextures(1, &_gBuffers.colorTexture);
|
||||
glDeleteTextures(1, &_gBuffers.depthTexture);
|
||||
|
||||
glDeleteTextures(1, &_hdrBuffers._hdrFilteringTexture);
|
||||
glDeleteTextures(1, &_hdrBuffers.hdrFilteringTexture);
|
||||
glDeleteTextures(1, &_fxaaBuffers.fxaaTexture);
|
||||
glDeleteTextures(1, &_gBuffers.positionTexture);
|
||||
glDeleteTextures(1, &_gBuffers.normalTexture);
|
||||
|
||||
@@ -371,23 +390,6 @@ void FramebufferRenderer::deferredcastersChanged(Deferredcaster&,
|
||||
_dirtyDeferredcastData = true;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::resolveMSAA(float blackoutFactor) {
|
||||
_resolveProgram->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit mainColorTextureUnit;
|
||||
mainColorTextureUnit.activate();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.colorTexture);
|
||||
_resolveProgram->setUniform(_uniformCache.mainColorTexture, mainColorTextureUnit);
|
||||
_resolveProgram->setUniform(_uniformCache.blackoutFactor, blackoutFactor);
|
||||
_resolveProgram->setUniform(_uniformCache.nAaSamples, _nAaSamples);
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_resolveProgram->deactivate();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::applyTMO(float blackoutFactor) {
|
||||
const bool doPerformanceMeasurements = global::performanceManager.isEnabled();
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perfInternal;
|
||||
@@ -402,7 +404,7 @@ void FramebufferRenderer::applyTMO(float blackoutFactor) {
|
||||
ghoul::opengl::TextureUnit hdrFeedingTextureUnit;
|
||||
hdrFeedingTextureUnit.activate();
|
||||
glBindTexture(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
GL_TEXTURE_2D,
|
||||
_pingPongBuffers.colorTexture[_pingPongIndex]
|
||||
);
|
||||
|
||||
@@ -418,8 +420,6 @@ void FramebufferRenderer::applyTMO(float blackoutFactor) {
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.Hue, _hue);
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.Saturation, _saturation);
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.Value, _value);
|
||||
_hdrFilteringProgram->setUniform(_hdrUniformCache.nAaSamples, _nAaSamples);
|
||||
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
@@ -428,6 +428,40 @@ void FramebufferRenderer::applyTMO(float blackoutFactor) {
|
||||
_hdrFilteringProgram->deactivate();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::applyFXAA() {
|
||||
const bool doPerformanceMeasurements = global::performanceManager.isEnabled();
|
||||
std::unique_ptr<performance::PerformanceMeasurement> perfInternal;
|
||||
|
||||
if (doPerformanceMeasurements) {
|
||||
perfInternal = std::make_unique<performance::PerformanceMeasurement>(
|
||||
"FramebufferRenderer::render::FXAA"
|
||||
);
|
||||
}
|
||||
|
||||
_fxaaProgram->activate();
|
||||
|
||||
ghoul::opengl::TextureUnit renderedTextureUnit;
|
||||
renderedTextureUnit.activate();
|
||||
glBindTexture(
|
||||
GL_TEXTURE_2D,
|
||||
_fxaaBuffers.fxaaTexture
|
||||
);
|
||||
|
||||
_fxaaProgram->setUniform(
|
||||
_fxaaUniformCache.renderedTexture,
|
||||
renderedTextureUnit
|
||||
);
|
||||
|
||||
glm::vec2 inverseScreenSize(1.f/_resolution.x, 1.f/_resolution.y);
|
||||
_fxaaProgram->setUniform(_fxaaUniformCache.inverseScreenSize, inverseScreenSize);
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_fxaaProgram->deactivate();
|
||||
}
|
||||
|
||||
void FramebufferRenderer::update() {
|
||||
if (_dirtyResolution) {
|
||||
updateResolution();
|
||||
@@ -460,6 +494,16 @@ void FramebufferRenderer::update() {
|
||||
);
|
||||
}
|
||||
|
||||
if (_fxaaProgram->isDirty()) {
|
||||
_fxaaProgram->rebuildFromFile();
|
||||
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_fxaaProgram,
|
||||
_fxaaUniformCache,
|
||||
FXAAUniformNames
|
||||
);
|
||||
}
|
||||
|
||||
using K = VolumeRaycaster*;
|
||||
using V = std::unique_ptr<ghoul::opengl::ProgramObject>;
|
||||
for (const std::pair<const K, V>& program : _exitPrograms) {
|
||||
@@ -512,61 +556,7 @@ void FramebufferRenderer::update() {
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateResolution() {
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.colorTexture);
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
GL_TRUE
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.positionTexture);
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
GL_TRUE
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.normalTexture);
|
||||
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
GL_TRUE
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.depthTexture);
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
GL_TRUE
|
||||
);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _pingPongBuffers.colorTexture[1]);
|
||||
glTexImage2DMultisample(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
_nAaSamples,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
GL_TRUE
|
||||
);
|
||||
|
||||
|
||||
// HDR / Filtering
|
||||
glBindTexture(GL_TEXTURE_2D, _hdrBuffers._hdrFilteringTexture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.colorTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
@@ -578,7 +568,98 @@ void FramebufferRenderer::updateResolution() {
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.positionTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.normalTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_DEPTH_COMPONENT,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, _pingPongBuffers.colorTexture[1]);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// HDR / Filtering
|
||||
glBindTexture(GL_TEXTURE_2D, _hdrBuffers.hdrFilteringTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA32F,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// FXAA
|
||||
glBindTexture(GL_TEXTURE_2D, _fxaaBuffers.fxaaTexture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
_resolution.x,
|
||||
_resolution.y,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
@@ -754,6 +835,17 @@ void FramebufferRenderer::updateHDRAndFiltering() {
|
||||
//_hdrFilteringProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateFXAA() {
|
||||
_fxaaProgram = ghoul::opengl::ProgramObject::Build(
|
||||
"FXAA Program",
|
||||
absPath("${SHADERS}/framebuffer/fxaa.vert"),
|
||||
absPath("${SHADERS}/framebuffer/fxaa.frag")
|
||||
);
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
|
||||
//_fxaaProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
|
||||
//_fxaaProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) {
|
||||
// Set OpenGL default rendering state
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
|
||||
@@ -842,18 +934,25 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac
|
||||
// Disabling depth test for filtering and hdr
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// When applying the TMO, the result is saved to the default FBO to be displayed
|
||||
// by the Operating System. Also, the resolve procedure is executed in this step.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
glViewport(0, 0, _resolution.x, _resolution.y);
|
||||
|
||||
if (_disableHDR) {
|
||||
resolveMSAA(blackoutFactor);
|
||||
if (_enableFXAA) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fxaaBuffers.fxaaFramebuffer);
|
||||
}
|
||||
else {
|
||||
// Apply the selected TMO on the results and resolve the result for the default FBO
|
||||
applyTMO(blackoutFactor);
|
||||
// When applying the TMO, the result is saved to the default FBO to be displayed
|
||||
// by the Operating System. Also, the resolve procedure is executed in this step.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
}
|
||||
|
||||
glViewport(0, 0, _resolution.x, _resolution.y);
|
||||
|
||||
// Apply the selected TMO on the results and resolve the result for the default FBO
|
||||
applyTMO(blackoutFactor);
|
||||
|
||||
if (_enableFXAA) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
applyFXAA();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FramebufferRenderer::performRaycasterTasks(const std::vector<RaycasterTask>& tasks) {
|
||||
@@ -916,10 +1015,9 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector<RaycasterTask>
|
||||
|
||||
ghoul::opengl::TextureUnit mainDepthTextureUnit;
|
||||
mainDepthTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.depthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture);
|
||||
raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit);
|
||||
|
||||
raycastProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
raycastProgram->setUniform("windowSize", static_cast<glm::vec2>(_resolution));
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@@ -971,9 +1069,8 @@ void FramebufferRenderer::performDeferredTasks(
|
||||
// adding G-Buffer
|
||||
ghoul::opengl::TextureUnit mainDColorTextureUnit;
|
||||
mainDColorTextureUnit.activate();
|
||||
//glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers._colorTexture);
|
||||
glBindTexture(
|
||||
GL_TEXTURE_2D_MULTISAMPLE,
|
||||
GL_TEXTURE_2D,
|
||||
_pingPongBuffers.colorTexture[fromIndex]
|
||||
);
|
||||
deferredcastProgram->setUniform(
|
||||
@@ -983,7 +1080,7 @@ void FramebufferRenderer::performDeferredTasks(
|
||||
|
||||
ghoul::opengl::TextureUnit mainPositionTextureUnit;
|
||||
mainPositionTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.positionTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.positionTexture);
|
||||
deferredcastProgram->setUniform(
|
||||
"mainPositionTexture",
|
||||
mainPositionTextureUnit
|
||||
@@ -991,14 +1088,12 @@ void FramebufferRenderer::performDeferredTasks(
|
||||
|
||||
ghoul::opengl::TextureUnit mainNormalTextureUnit;
|
||||
mainNormalTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _gBuffers.normalTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _gBuffers.normalTexture);
|
||||
deferredcastProgram->setUniform(
|
||||
"mainNormalTexture",
|
||||
mainNormalTextureUnit
|
||||
);
|
||||
|
||||
deferredcastProgram->setUniform("nAaSamples", _nAaSamples);
|
||||
|
||||
deferredcaster->preRaycast(
|
||||
deferredcasterTask.renderData,
|
||||
_deferredcastData[deferredcaster],
|
||||
@@ -1036,22 +1131,6 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) {
|
||||
_dirtyResolution = true;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setNAaSamples(int nAaSamples) {
|
||||
ghoul_assert(
|
||||
nAaSamples >= 1 && nAaSamples <= 8,
|
||||
"Number of AA samples has to be between 1 and 8"
|
||||
);
|
||||
_nAaSamples = nAaSamples;
|
||||
if (_nAaSamples == 0) {
|
||||
_nAaSamples = 1;
|
||||
}
|
||||
if (_nAaSamples > 8) {
|
||||
LERROR("Framebuffer renderer does not support more than 8 MSAA samples.");
|
||||
_nAaSamples = 8;
|
||||
}
|
||||
_dirtyMsaaSamplingPattern = true;
|
||||
}
|
||||
|
||||
void FramebufferRenderer::setDisableHDR(bool disable) {
|
||||
_disableHDR = std::move(disable);
|
||||
}
|
||||
@@ -1079,8 +1158,8 @@ void FramebufferRenderer::setSaturation(float sat) {
|
||||
_saturation = std::move(sat);
|
||||
}
|
||||
|
||||
int FramebufferRenderer::nAaSamples() const {
|
||||
return _nAaSamples;
|
||||
void FramebufferRenderer::enableFXAA(bool enable) {
|
||||
_enableFXAA = std::move(enable);
|
||||
}
|
||||
|
||||
void FramebufferRenderer::updateRendererData() {
|
||||
|
||||
@@ -192,13 +192,6 @@ namespace {
|
||||
"direction for tilted display systems in clustered immersive environments."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AaSamplesInfo = {
|
||||
"AaSamples",
|
||||
"Number of Anti-aliasing samples",
|
||||
"This value determines the number of anti-aliasing samples to be used in the "
|
||||
"rendering for the MSAA method."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DisableHDRPipelineInfo = {
|
||||
"DisableHDRPipeline",
|
||||
"Disable HDR Rendering",
|
||||
@@ -253,6 +246,12 @@ namespace {
|
||||
"The blackout factor of the rendering. This can be used for fading in or out the "
|
||||
"rendering window"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FXAAInfo = {
|
||||
"FXAA",
|
||||
"Enable FXAA",
|
||||
"Enable FXAA"
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -273,7 +272,7 @@ RenderEngine::RenderEngine()
|
||||
#endif // OPENSPACE_WITH_INSTRUMENTATION
|
||||
, _disableMasterRendering(DisableMasterInfo, false)
|
||||
, _globalBlackOutFactor(GlobalBlackoutFactorInfo, 1.f, 0.f, 1.f)
|
||||
, _nAaSamples(AaSamplesInfo, 4, 1, 8)
|
||||
, _enableFXAA(FXAAInfo, true)
|
||||
, _disableHDRPipeline(DisableHDRPipelineInfo, false)
|
||||
, _hdrExposure(HDRExposureInfo, 3.7f, 0.01f, 10.0f)
|
||||
, _gamma(GammaInfo, 0.95f, 0.01f, 5.0f)
|
||||
@@ -310,12 +309,12 @@ RenderEngine::RenderEngine()
|
||||
addProperty(_showVersionInfo);
|
||||
addProperty(_showCameraInfo);
|
||||
|
||||
_nAaSamples.onChange([this](){
|
||||
_enableFXAA.onChange([this]() {
|
||||
if (_renderer) {
|
||||
_renderer->setNAaSamples(_nAaSamples);
|
||||
_renderer->enableFXAA(_enableFXAA);
|
||||
}
|
||||
});
|
||||
addProperty(_nAaSamples);
|
||||
});
|
||||
addProperty(_enableFXAA);
|
||||
|
||||
_disableHDRPipeline.onChange([this]() {
|
||||
if (_renderer) {
|
||||
@@ -457,8 +456,6 @@ void RenderEngine::initialize() {
|
||||
void RenderEngine::initializeGL() {
|
||||
LTRACE("RenderEngine::initializeGL(begin)");
|
||||
|
||||
_nAaSamples = global::windowDelegate.currentNumberOfAaSamples();
|
||||
|
||||
std::string renderingMethod = global::configuration.renderingMethod;
|
||||
if (renderingMethod == "ABuffer") {
|
||||
using Version = ghoul::systemcapabilities::Version;
|
||||
@@ -1086,7 +1083,7 @@ void RenderEngine::setRenderer(std::unique_ptr<Renderer> renderer) {
|
||||
|
||||
_renderer = std::move(renderer);
|
||||
_renderer->setResolution(renderingResolution());
|
||||
_renderer->setNAaSamples(_nAaSamples);
|
||||
_renderer->enableFXAA(true);
|
||||
_renderer->setHDRExposure(_hdrExposure);
|
||||
_renderer->initialize();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user