From 45df1d498ae5fabd5ad2fabef171a176280095b5 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 2 Nov 2017 15:05:32 -0400 Subject: [PATCH] Fixed ATM acne after changing the MSAA patterns. --- include/openspace/rendering/abufferrenderer.h | 6 +- .../openspace/rendering/framebufferrenderer.h | 4 +- include/openspace/rendering/renderer.h | 2 +- .../rendering/atmospheredeferredcaster.cpp | 4 -- .../shaders/atmosphere_deferred_fs.glsl | 65 +++++++++---------- src/rendering/abufferrenderer.cpp | 14 ++-- src/rendering/framebufferrenderer.cpp | 26 ++++---- 7 files changed, 61 insertions(+), 60 deletions(-) diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index 69f1a20bb4..ca3abe8265 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -76,7 +76,7 @@ public: float hdrBackground() const override; const int nAaSamples() const override; - const float * mSSAPattern() const override; + const double * mSSAPattern() const override; void preRaycast(const RaycasterTask& raycasterTask); void postRaycast(const RaycasterTask& raycasterTask); @@ -99,7 +99,7 @@ private: void updateResolveDictionary(); void updateMSAASamplingPattern(); void saveTextureToMemory(const GLenum color_buffer_attachment, - const int width, const int height, float ** memory) const; + const int width, const int height, double ** memory) const; Camera* _camera; Scene* _scene; @@ -145,7 +145,7 @@ private: float _gamma; float _blackoutFactor; - float * _mSAAPattern; + double * _mSAAPattern; ghoul::Dictionary _rendererData; }; diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 2ce7d38b70..7bdf4c3232 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -74,7 +74,7 @@ public: float hdrBackground() const override; const int nAaSamples() const override; - const float * mSSAPattern() const override; + const double * mSSAPattern() const override; void update() override; void render(float blackoutFactor, bool doPerformanceMeasurements) override; @@ -126,7 +126,7 @@ private: float _hdrBackground; float _gamma; - float * _mSAAPattern; + double * _mSAAPattern; ghoul::Dictionary _rendererData; }; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index 54674d74db..9ae3e561e3 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -62,7 +62,7 @@ public: virtual float hdrBackground() const = 0; virtual const int nAaSamples() const = 0; - virtual const float * mSSAPattern() const = 0; + virtual const double * mSSAPattern() const = 0; /** * Set raycasting uniforms on the program object, and setup raycasting. diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index d2c3a22dfe..e27bf21302 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -195,10 +195,6 @@ void AtmosphereDeferredcaster::deinitialize() void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData, const DeferredcastData& deferredData, ghoul::opengl::ProgramObject& program) { - // MSAA pixel position pattern - const Renderer * currentRenderer = OsEng.renderEngine().renderer(); - const float * mssaPatternArray = currentRenderer->mSSAPattern(); - // Atmosphere Frustum Culling glm::dvec3 tPlanetPosWorld = glm::dvec3(_modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0)); diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index 2ab4aa5437..f36ffbb87d 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -59,7 +59,6 @@ #version __CONTEXT__ -#define EPSILON 0.0001f #include "floatoperations.glsl" #include "hdr.glsl" @@ -69,7 +68,7 @@ out vec4 renderTarget; in vec3 interpolatedNDCPos; uniform int nAaSamples; -uniform float msaaSamplePatter[48]; +uniform double msaaSamplePatter[48]; uniform int cullAtmosphere; // Background exposure hack @@ -194,7 +193,7 @@ bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const d dvec3 l = planetPosition - ray.origin.xyz; double s = dot(l, ray.direction.xyz); double l2 = dot(l, l); - double r2 = (atmRadius - EPSILON) * (atmRadius - EPSILON); // avoiding surface acne + double r2 = atmRadius * atmRadius; // avoiding surface acne // Ray origin (eye position) is behind sphere if ((s < 0.0) && (l2 > r2)) { @@ -252,10 +251,9 @@ void dCalculateRayRenderableGlobe(in int mssaSample, out dRay ray, // NDC to clip coordinates (gl_FragCoord.w = 1.0/w_clip) // Using the interpolated coords: // Assuming Red Book is right: z_ndc e [0, 1] and not [-1, 1] - dvec3 samplePos = dvec3(0.0); - samplePos[0] = double(msaaSamplePatter[mssaSample]); - samplePos[1] = double(msaaSamplePatter[mssaSample+1]); - dvec4 clipCoords = dvec4(interpolatedNDCPos + samplePos, 1.0) / gl_FragCoord.w; + dvec2 samplePos = dvec2(msaaSamplePatter[mssaSample], + msaaSamplePatter[mssaSample+1]); + dvec4 clipCoords = dvec4(interpolatedNDCPos.xy + samplePos, interpolatedNDCPos.z, 1.0) / gl_FragCoord.w; // Clip to SGCT Eye dvec4 sgctEyeCoords = dInverseSgctProjectionMatrix * clipCoords; @@ -276,6 +274,7 @@ void dCalculateRayRenderableGlobe(in int mssaSample, out dRay ray, // JCC: Applying the inverse of the model transformation on the object postion in World // space results in imprecision. planetPositionObjectCoords = dvec4(0.0,0.0,0.0,1.0);//dInverseModelTransformMatrix * dvec4(dObjpos.xyz, 1.0); + //planetPositionObjectCoords = dInverseModelTransformMatrix * dvec4(dObjpos.xyz, 1.0); // Camera Position in Object Space cameraPositionInObject = dInverseModelTransformMatrix * dvec4(dCampos, 1.0); @@ -344,10 +343,14 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if ((pixelDepth > 0.0) && (pixelDepth < maxLength)) { t = float(pixelDepth); groundHit = true; + // Transmittance from point r, direction mu, distance t // By Analytical calculation - attenuation = analyticTransmittance(r, mu, t); - + //attenuation = analyticTransmittance(r, mu, t); + // JCC: change from analytical to LUT transmittance to avoid + // acme on planet surface when looking from far away. (11/02/2017) + attenuation = transmittance(r, mu, t); + // Here we use the idea of S[L](a->b) = S[L](b->a), and get the S[L](x0, v, s) // Then we calculate S[L] = S[L]|x - T(x, x0)*S[L]|x0 // The "infinite" ray hist something inside the atmosphere, so we need to remove @@ -361,7 +364,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor } else { attenuation = analyticTransmittance(r, mu, t); } - + // cos(PI-thetaH) = dist/r // cos(thetaH) = - dist/r // muHorizon = -sqrt(r^2-Rg^2)/r = -sqrt(1-(Rg/r)^2) @@ -464,21 +467,22 @@ vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const // Normal of intersection point. vec3 n = normalize(normal); //vec4 groundReflectance = groundColor * vec4(.37); - vec4 groundReflectance = groundColor - * vec4(groundRadianceEmittion, groundRadianceEmittion, groundRadianceEmittion, 1.0f); - + vec4 groundReflectance = groundColor * + vec4(groundRadianceEmittion, groundRadianceEmittion, groundRadianceEmittion, 1.0f); + // L0 is not included in the irradiance texture. // We first calculate the light attenuation from the top of the atmosphere // to x0. float dotNS = dot(n, s); - float muSun = max(dotNS, 0.0); + float muSun = max(dotNS, 0.0f); + // Is direct Sun light arriving at x0? If not, there is no direct light from Sun (shadowed) vec3 transmittanceL0 = muSun < -sqrt(1.0f - ((Rg * Rg) / (r0 * r0))) ? vec3(0.0f) : transmittanceLUT(r0, muSun); // E[L*] at x0 vec3 irradianceReflected = irradiance(irradianceTexture, r0, muSun) * irradianceFactor; // R[L0] + R[L*] - vec3 groundRadiance = (dotNS < -0.2f ? groundReflectance.rgb * 10 : groundReflectance.rgb) * + vec3 groundRadiance = (dotNS < -0.2f ? groundReflectance.rgb * 15 : groundReflectance.rgb) * (muSun * transmittanceL0 + irradianceReflected) * sunIntensity / M_PI; @@ -493,12 +497,12 @@ vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const // (After adding the sunRadiance and the attenuation of the Sun through atmosphere) groundRadiance += waterReflectance * max(waterBrdf, 0.0) * transmittanceL0 * sunIntensity; } - + //return groundRadiance; // Finally, we attenuate the surface Radiance from the the point x0 to the camera location. reflectedRadiance = attenuationXtoX0 * groundRadiance; // Returns reflectedRadiance = 0.0 if the ray doesn't hit the ground. - return reflectedRadiance; + return reflectedRadiance; } /* @@ -548,10 +552,10 @@ void main() { if (complex) { nSamples = nAaSamples; } - + for (int i = 0; i < nSamples; i++) { - vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i); - vec4 color = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); + vec4 normal = texelFetch(mainNormalTexture, ivec2(gl_FragCoord), i); + vec4 color = texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); // Data in the mainPositionTexture are written in view space (view plus camera rig) vec4 position = texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i); vec4 otherData = texelFetch(otherDataTexture, ivec2(gl_FragCoord), i); @@ -584,14 +588,8 @@ void main() { // transfRay.direction.y *= 1000.0/ellipsoidRadii.z; // transfRay.direction.xyz = normalize(transfRay.direction.xyz); - // intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, 1.0, - // insideATM, offset, maxLength ); - - // intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, Rt+EPSILON, - // insideATM, offset, maxLength ); - intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, - Rt - 10*EPSILON, insideATM, offset, maxLength ); + Rt - ATM_EPSILON/100.0, insideATM, offset, maxLength ); if ( intersectATM ) { // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel @@ -616,6 +614,7 @@ void main() { if (position.xyz != vec3(0.0) && (pixelDepth < offset)) { atmosphereFinalColor += vec4(HDR(color.xyz * backgroundExposure), color.a); + //discard; } else { // Following paper nomenclature double t = offset; @@ -635,16 +634,16 @@ void main() { // we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobehis offset so the // next comparison with the planet's ground make sense: pixelDepth -= offset; - - float irradianceFactor = 0.0; - - dvec4 onATMPos = dModelTransformMatrix * dvec4(x*1000.0, 1.0); - vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false); + + dvec4 onATMPos = dModelTransformMatrix * dvec4(x*1000.0, 1.0); + vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false); vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, fragWorldCoords.xyz, true); float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x; float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x; + float irradianceFactor = 0.0; + vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, s, r, mu, attenuation, vec3(fragObjectCoords.xyz), @@ -656,7 +655,7 @@ void main() { vec3 sunColor = sunColor(x, tF, v, s, r, mu, irradianceFactor); // Final Color of ATM plus terrain: - vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0); + vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0); atmosphereFinalColor += finalRadiance; } diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index fd4fd9754e..7ca6caa731 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -539,9 +539,11 @@ void ABufferRenderer::updateMSAASamplingPattern() { glBindVertexArray(0); saveTextureToMemory(GL_COLOR_ATTACHMENT0, _nAaSamples, 1, &_mSAAPattern); - // Convert back to [-1, 1] range: - for (int d = 0; d < _nAaSamples * 3; d += 3) { - _mSAAPattern[d] = 2.0f * _mSAAPattern[d] - 1.0f; + // Convert back to [-1, 1] range and then scales to the current viewport size: + for (int d = 0; d < _nAaSamples; ++d) { + _mSAAPattern[d * 3] = (2.0 * _mSAAPattern[d * 3] - 1.0) / static_cast(viewport[2]); + _mSAAPattern[(d * 3) + 1] = (2.0 * _mSAAPattern[(d * 3) + 1] - 1.0) / static_cast(viewport[3]); + _mSAAPattern[(d * 3) + 2] = 0.0; } nOneStripProgram->deactivate(); @@ -765,7 +767,7 @@ const int ABufferRenderer::nAaSamples() const { return _nAaSamples; } -const float * ABufferRenderer::mSSAPattern() const { +const double * ABufferRenderer::mSSAPattern() const { return _mSAAPattern; } @@ -995,13 +997,13 @@ void ABufferRenderer::updateRendererData() { } void ABufferRenderer::saveTextureToMemory(const GLenum color_buffer_attachment, - const int width, const int height, float ** memory) const { + const int width, const int height, double ** memory) const { if (*memory != nullptr) { delete[] * memory; } - *memory = new float[width*height * 3]; + *memory = new double[width*height * 3]; if (color_buffer_attachment != GL_DEPTH_ATTACHMENT) { glReadBuffer(color_buffer_attachment); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 3f04fa1b69..ee194710e0 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -69,7 +69,7 @@ void saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName, const int width, const int height); void saveTextureToMemory(const GLenum color_buffer_attachment, - const int width, const int height, float ** memory); + const int width, const int height, double ** memory); FramebufferRenderer::FramebufferRenderer() : _camera(nullptr) @@ -864,11 +864,11 @@ void FramebufferRenderer::updateMSAASamplingPattern() { glBindVertexArray(0); saveTextureToMemory(GL_COLOR_ATTACHMENT0, _nAaSamples, 1, &_mSAAPattern); - // Convert back to [-1, 1] range: + // Convert back to [-1, 1] range and then scale for the current viewport size: for (int d = 0; d < _nAaSamples; ++d) { - _mSAAPattern[d * 3] = (2.0f * _mSAAPattern[d * 3] - 1.0f) / static_cast(viewport[2]); - _mSAAPattern[(d * 3) + 1] = (2.0f * _mSAAPattern[(d * 3) + 1] - 1.0f) / static_cast(viewport[3]); - _mSAAPattern[(d * 3) + 2] = 0.0f; + _mSAAPattern[d * 3] = (2.0 * _mSAAPattern[d * 3] - 1.0) / static_cast(viewport[2]); + _mSAAPattern[(d * 3) + 1] = (2.0 * _mSAAPattern[(d * 3) + 1] - 1.0) / static_cast(viewport[3]); + _mSAAPattern[(d * 3) + 2] = 0.0; } nOneStripProgram->deactivate(); @@ -1224,7 +1224,7 @@ const int FramebufferRenderer::nAaSamples() const { return _nAaSamples; } -const float * FramebufferRenderer::mSSAPattern() const { +const double * FramebufferRenderer::mSSAPattern() const { return _mSAAPattern; } @@ -1277,23 +1277,27 @@ void saveTextureToPPMFile(const GLenum color_buffer_attachment, } void saveTextureToMemory(const GLenum color_buffer_attachment, - const int width, const int height, float ** memory) { + const int width, const int height, double ** memory) { if (*memory != nullptr) { delete[] *memory; } - *memory = new float[width*height * 3]; - + *memory = new double[width*height * 3]; + float *tempMemory = new float[width*height * 3]; + if (color_buffer_attachment != GL_DEPTH_ATTACHMENT) { glReadBuffer(color_buffer_attachment); - glReadPixels(0, 0, width, height, GL_RGB, GL_FLOAT, *memory); + glReadPixels(0, 0, width, height, GL_RGB, GL_FLOAT, tempMemory); } else { - glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, *memory); + glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, tempMemory); } + for (auto i = 0; i < width*height * 3; ++i) { + (*memory)[i] = static_cast(tempMemory[i]); + } }