From 587d5c8d75cc774225706af763617d5c10e0226d Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 12 May 2017 16:46:12 -0400 Subject: [PATCH] Initial merging of ATM with Globebrowsing. Still missing code. --- data/scene/atmosphereearth.scene | 13 +- data/scene/lodglobes/mars/mars.mod | 30 ++ .../openspace/rendering/framebufferrenderer.h | 3 + .../rendering/atmospheredeferredcaster.cpp | 16 +- .../rendering/atmospheredeferredcaster.h | 5 +- .../rendering/renderableplanetatmosphere.cpp | 6 +- .../atmosphere/shaders/deferred_test_fs.glsl | 249 ++++++++------- .../atmosphere/shaders/nighttexture_fs.glsl | 5 + .../atmosphere/shaders/nighttexture_vs.glsl | 13 +- .../shaders/renderableplanet_fs.glsl | 7 + .../shaders/renderableplanet_vs.glsl | 14 +- modules/atmosphere/shaders/shadow_fs.glsl | 5 + .../shaders/shadow_nighttexture_fs.glsl | 9 +- .../shaders/shadow_nighttexture_vs.glsl | 26 +- modules/atmosphere/shaders/shadow_vs.glsl | 13 +- .../globebrowsing/globes/renderableglobe.cpp | 285 +++++++++++++++++- .../globebrowsing/globes/renderableglobe.h | 53 +++- .../globebrowsing/rendering/chunkrenderer.cpp | 5 +- .../shaders/globalchunkedlodpatch_fs.glsl | 4 + .../shaders/localchunkedlodpatch_fs.glsl | 7 +- .../shaders/localchunkedlodpatch_vs.glsl | 3 + .../shaders/texturetilemapping.hglsl | 2 +- .../globebrowsing/shaders/tilefragcolor.hglsl | 1 + shaders/fragment.glsl | 3 + shaders/framebuffer/renderframebuffer.frag | 8 +- shaders/framebuffer/resolveframebuffer.frag | 2 +- src/rendering/framebufferrenderer.cpp | 160 +++++++--- 27 files changed, 772 insertions(+), 175 deletions(-) diff --git a/data/scene/atmosphereearth.scene b/data/scene/atmosphereearth.scene index bbbb601879..8f41e03f49 100644 --- a/data/scene/atmosphereearth.scene +++ b/data/scene/atmosphereearth.scene @@ -51,10 +51,12 @@ function postInitialization() openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.55) openspace.setPropertyValue("MilkyWay.renderable.segments", 50) - openspace.resetCameraDirection() + --openspace.resetCameraDirection() openspace.printInfo("Done setting default values") + --openspace.setInteractionMode('GlobeBrowsing') + if openspace.modules.isLoaded("ISWA") then openspace.iswa.addCdfFiles("${OPENSPACE_DATA}/cdflist.json"); end @@ -73,12 +75,19 @@ return { --Rotation = {0.243724, 0.002268, 0.964416, 0.102449}, Position = {-21235464763.652920, -75191278487.585068, 126294839057.346405}, Rotation = {0.224913, -0.096227, 0.939918, 0.238136}, + + -- Mars Position + Position = {113807010618.012451, -93349316388.687042, 190403814045.631592}, + Rotation = {0.527685, 0.455945, -0.495623, 0.517707}, }, Modules = { "sun", "atmosphereearth", + --"lodglobes/earth", + --"lodglobes/moon", --"moon", - "atmospheremars", + --"atmospheremars", + "lodglobes/mars", --"toyvolume", --"earth", --"stars", diff --git a/data/scene/lodglobes/mars/mars.mod b/data/scene/lodglobes/mars/mars.mod index 375954c010..08a854f60a 100644 --- a/data/scene/lodglobes/mars/mars.mod +++ b/data/scene/lodglobes/mars/mars.mod @@ -35,6 +35,36 @@ return { SegmentsPerPatch = 90, -- Allows camera to go down 10000 meters below the reference ellipsoid InteractionDepthBelowEllipsoid = 10000, -- Useful when having negative height map values + Atmosphere = { + -- Atmosphere radius in Km + AtmoshereRadius = 6410, + PlanetRadius = 6390.0, + PlanetAverageGroundReflectance = 0.1, + Rayleigh = { + Coefficients = { + -- Wavelengths are given in 10^-9m + Wavelengths = {680, 550, 440}, + -- Reflection coefficients are given in km^-1 + Scattering = {5.8e-3, 1.35e-2, 3.31e-2}, + -- In Rayleigh scattering, the coefficients of absorption and scattering are the same. + }, + -- Thichkness of atmosphere if its density were uniform, in Km + H_R = 8.0, + }, + -- Default + Mie = { + Coefficients = { + -- Reflection coefficients are given in km^-1 + Scattering = {4.0e-3, 4.0e-3, 4.0e-3}, + -- Extinction coefficients are a fraction of the Scattering coefficients + Extinction = {4.0e-3/0.9, 4.0e-3/0.9, 4.0e-3/0.9} + }, + -- Mie Height scale (atmosphere thickness for constant density) in Km + H_M = 1.2, + -- Mie Phase Function Value (G e [-1.0, 1.0]. If G = 1.0, Mie phase function = Rayleigh Phase Function) + G = 0.85, + }, + }, Layers = { ColorLayers = { { diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 921b9a9399..71c27f546c 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -99,6 +99,9 @@ private: GLuint _screenQuad; GLuint _vertexPositionBuffer; GLuint _mainColorTexture; + GLuint _mainDColorTexture; + GLuint _mainPositionTexture; + GLuint _mainNormalReflectanceTexture; GLuint _mainDepthTexture; GLuint _exitColorTexture; GLuint _mainFramebuffer; diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index a0c8eb4fd9..785d2f78f0 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -47,7 +47,7 @@ #define _USE_MATH_DEFINES #include -#define _SAVE_ATMOSPHERE_TEXTURES +//#define _SAVE_ATMOSPHERE_TEXTURES namespace { const std::string _loggerCat = "AtmosphereDeferredcaster"; @@ -94,6 +94,7 @@ AtmosphereDeferredcaster::AtmosphereDeferredcaster() , _mieExtinctionCoeff(glm::vec3(0.f)) , _rayleighScatteringCoeff(glm::vec3(0.f)) , _mieScatteringCoeff(glm::vec3(0.f)) + , _ellipsoidRadii(glm::dvec3(0.0)) , _sunRadianceIntensity(50.0f) , _hdrConstant(0.4f) {} @@ -228,6 +229,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const D SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt); glm::dvec4 sunPosObj = glm::inverse(_modelTransform) * glm::dvec4(sunPosWorld - renderData.position.dvec3(), 1.0); + program.setUniform("ellipsoidRadii", _ellipsoidRadii); + //program.setUniform("sunPositionObj", sunPosObj); program.setUniform("sunDirectionObj", glm::normalize(glm::dvec3(sunPosObj))); //program.setUniform("_performShading", _performShading); @@ -248,10 +251,10 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData & renderData, const D program.setUniform("inscatterTexture", inScatteringTableTextureUnit); // DEBUG: - glm::dvec3 objP = glm::dvec3(renderData.position[0] * pow(10, renderData.position[3]), - renderData.position[1] * pow(10, renderData.position[3]), renderData.position[2] * pow(10, renderData.position[3])); - glm::dvec4 cameraP = glm::inverse(glm::dmat4(_modelTransform)) * glm::dvec4(-objP + renderData.camera.positionVec3(), 1.0); - std::cout << "====== Distance from Planet's ground in KM: " << glm::length(glm::dvec3(cameraP / glm::dvec4(1000.0, 1000.0, 1000.0, 1.0))) - _atmospherePlanetRadius << " =======" << std::endl; + //glm::dvec3 objP = glm::dvec3(renderData.position[0] * pow(10, renderData.position[3]), + // renderData.position[1] * pow(10, renderData.position[3]), renderData.position[2] * pow(10, renderData.position[3])); + //glm::dvec4 cameraP = glm::inverse(glm::dmat4(_modelTransform)) * glm::dvec4(-objP + renderData.camera.positionVec3(), 1.0); + //std::cout << "====== Distance from Planet's ground in KM: " << glm::length(glm::dvec3(cameraP / glm::dvec4(1000.0, 1000.0, 1000.0, 1.0))) - _atmospherePlanetRadius << " =======" << std::endl; } void AtmosphereDeferredcaster::postRaycast(const RenderData & renderData, const DeferredcastData& deferredData, @@ -326,6 +329,9 @@ void AtmosphereDeferredcaster::setMieExtinctionCoefficients(const glm::vec3 & mi _mieExtinctionCoeff = mieExtCoeff; } +void AtmosphereDeferredcaster::setEllipsoidRadii(const glm::dvec3 & radii) { + _ellipsoidRadii = radii; +} void AtmosphereDeferredcaster::loadComputationPrograms() { diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.h b/modules/atmosphere/rendering/atmospheredeferredcaster.h index 5f8090ef41..af4a375a2f 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.h +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.h @@ -104,6 +104,7 @@ public: void setRayleighScatteringCoefficients(const glm::vec3 & rayScattCoeff); void setMieScatteringCoefficients(const glm::vec3 & mieScattCoeff); void setMieExtinctionCoefficients(const glm::vec3 & mieExtCoeff); + void setEllipsoidRadii(const glm::dvec3 & radii); private: void loadComputationPrograms(); @@ -124,8 +125,7 @@ private: void renderQuadForCalc(const GLuint vao, const GLsizei numberOfVertices); void saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName, - const int width, const int height) const; - + const int width, const int height) const; private: std::unique_ptr _transmittanceProgramObject; std::unique_ptr _irradianceProgramObject; @@ -165,6 +165,7 @@ private: glm::vec3 _mieExtinctionCoeff; glm::vec3 _rayleighScatteringCoeff; glm::vec3 _mieScatteringCoeff; + glm::dvec3 _ellipsoidRadii; // Atmosphere Texture Data Geometry GLuint _atmosphereFBO; diff --git a/modules/atmosphere/rendering/renderableplanetatmosphere.cpp b/modules/atmosphere/rendering/renderableplanetatmosphere.cpp index 1749c76e37..060048d461 100644 --- a/modules/atmosphere/rendering/renderableplanetatmosphere.cpp +++ b/modules/atmosphere/rendering/renderableplanetatmosphere.cpp @@ -471,6 +471,7 @@ namespace openspace { "${MODULE_ATMOSPHERE}/shaders/shadow_nighttexture_fs.glsl"); if (!_programObject) return false; + std::cout << "-- Running ShadowNightProgram --" << std::endl; } else if (_programObject == nullptr && _shadowEnabled) { // shadow program @@ -480,6 +481,7 @@ namespace openspace { "${MODULE_ATMOSPHERE}/shaders/shadow_fs.glsl"); if (!_programObject) return false; + std::cout << "-- Running ShadowProgram --" << std::endl; } else if (_programObject == nullptr && _hasNightTexture) { // Night texture program @@ -489,6 +491,7 @@ namespace openspace { "${MODULE_ATMOSPHERE}/shaders/nighttexture_fs.glsl"); if (!_programObject) return false; + std::cout << "-- Running NightTextureProgram --" << std::endl; } else if (_programObject == nullptr) { // pscstandard @@ -498,6 +501,7 @@ namespace openspace { "${MODULE_ATMOSPHERE}/shaders/renderableplanet_fs.glsl"); if (!_programObject) return false; + std::cout << "-- Running PSCStandard --" << std::endl; } using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; _programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); @@ -786,7 +790,7 @@ namespace openspace { } // render - //_geometry->render(); + _geometry->render(); // disable shader _programObject->deactivate(); diff --git a/modules/atmosphere/shaders/deferred_test_fs.glsl b/modules/atmosphere/shaders/deferred_test_fs.glsl index 7018eb6dff..81b344f077 100644 --- a/modules/atmosphere/shaders/deferred_test_fs.glsl +++ b/modules/atmosphere/shaders/deferred_test_fs.glsl @@ -33,13 +33,16 @@ //uniform sampler2D reflectanceTexture; uniform sampler2D irradianceTexture; uniform sampler3D inscatterTexture; -// uniform sampler2DMS mainDepthTexture; -// uniform sampler2DMS mainColorTexture; +//uniform sampler2DMS mainDepthTexture; +uniform sampler2DMS mainPositionTexture; +//uniform sampler2D mainPositionTexture; +uniform sampler2DMS mainNormalReflectanceTexture; +uniform sampler2DMS mainColorTexture; uniform int nAaSamples; -//layout(location = 0) out vec4 renderTarget; -out vec4 renderTarget; +layout(location = 0) out vec4 renderTarget; +//out vec4 renderTarget; in vec3 interpolatedNDCPos; @@ -65,6 +68,7 @@ uniform dvec3 dCampos; uniform dvec3 sunDirectionObj; +uniform dvec3 ellipsoidRadii; /******************************************************************************* ****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ****** @@ -218,7 +222,7 @@ bool dAtmosphereIntersection(const dvec3 planetPosition, const dRay ray, const d * This method avoids matrices multiplications * wherever is possible. */ -void dCalculateRay2(out dRay ray, out dvec4 planetPositionObjectCoords) { +void dCalculateRay2(out dRay ray, out dvec4 planetPositionObjectCoords, out dvec4 cameraPositionInObject) { // ====================================== // ======= Avoiding Some Matrices ======= @@ -251,7 +255,7 @@ void dCalculateRay2(out dRay ray, out dvec4 planetPositionObjectCoords) { planetPositionObjectCoords = dInverseTransformMatrix * dvec4(-dObjpos.xyz + dObjpos.xyz, 1.0); // Camera Position in Object Space - dvec4 cameraPositionInObject = dInverseTransformMatrix * dvec4(-dObjpos.xyz + dCampos, 1.0); + cameraPositionInObject = dInverseTransformMatrix * dvec4(-dObjpos.xyz + dCampos, 1.0); // ============================ // ====== Building Ray ======== @@ -279,7 +283,8 @@ void dCalculateRay2(out dRay ray, out dvec4 planetPositionObjectCoords) { * calculating the reflectance R[L]. */ vec3 inscatterNoTestRadiance(inout vec3 x, inout float t, const vec3 v, const vec3 s, - out float r, out float mu, out vec3 attenuation) { + out float r, out float mu, out vec3 attenuation, const vec3 fragPosObj, + const double maxLength, const double pixelDepth ) { vec3 radiance; r = length(x); @@ -317,18 +322,18 @@ vec3 inscatterNoTestRadiance(inout vec3 x, inout float t, const vec3 v, const ve bool hitGround = dAtmosphereIntersection(vec3(0.0), ray, Rg - EPSILON, insideATM, offset, maxLength); if (hitGround) - t = float(offset); - - // Calculate the zenith angles for x0 and v, s: - vec3 x0 = x + t * v; + //t = float(offset); + t = float(pixelDepth); + + vec3 x0 = x + t * v; float r0 = length(x0); float mu0 = dot(x0, v) / r0; float muSun0 = dot(x0, s) / r0; // Transmittance from point r, direction mu, distance t // By Analytical calculation - attenuation = analyticTransmittance(r, mu, t); - //return attenuation.xyz; + //attenuation = analyticTransmittance(r, mu, t); + attenuation = analyticTransmittance(r, mu, float(maxLength)); // By Texture Access //attenuation = transmittanceLUT(r, mu);//, v, x0); @@ -340,7 +345,8 @@ vec3 inscatterNoTestRadiance(inout vec3 x, inout float t, const vec3 v, const ve // remove the inScattering contribution from the main ray from the hitting point // to the end of the ray. - if (r0 > Rg + (0.01f)) { + //if (r0 > Rg + (0.01f)) { + if ( pixelDepth < maxLength ) { // 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 @@ -627,38 +633,41 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, const vec3 v, const vec3 s, * attenuationXtoX0 := transmittance T(x,x0) */ vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const float r, - const float mu, const vec3 attenuationXtoX0) + const float mu, const vec3 attenuationXtoX0, const vec4 groundColor, + const vec4 normalReflectance) { vec3 reflectedRadiance = vec3(0.0f); - float d = length(x + t * v); - float x_0 = sqrt(r * r + d * d - 2 * r * d * mu); + //float d = length(x + t * v); + //float x_0 = sqrt(r * r + d * d - 2 * r * d * mu); // Ray hits planet's surface - //if (t > 0.0f) { - if (x_0 >= Rg) { + if (t > 0.0f) { + //if (x_0 >= Rg) { // First we obtain the ray's end point on the surface vec3 x0 = x + t * v; float r0 = length(x0); // Normal of intersection point. // TODO: Change it to globebrowser - vec3 n = x0 / r0; - //vec3 n = -x0 / r0; + //vec3 n = x0 / r0; + vec3 n = normalize(normalReflectance.xyz); // Old deferred: - vec2 coords = vec2(atan(n.y, n.x), acos(n.z)) * vec2(0.5, 1.0) / M_PI + vec2(0.5, 0.0); + //vec2 coords = vec2(atan(n.y, n.x), acos(n.z)) * vec2(0.5, 1.0) / M_PI + vec2(0.5, 0.0); //vec2 coords = vec2(0.5 + (atan(n.z, n.x))/(2*M_PI), 0.5 - asin(n.y)/(M_PI)); // TODO: Chango to G-Buffer. - //vec4 reflectance = texture2D(reflectanceTexture, coords) * vec4(0.2, 0.2, 0.2, 1.0); - vec4 reflectance = vec4(0.2, 0.2, 0.2, 1.0); + //vec4 reflectance = texture2D(reflectanceTexture, coords) * vec4(0.2, 0.2, 0.2, 1.0); + vec4 reflectance = groundColor; + //vec4 reflectance = groundColor; + //reflectance.w = 1.0; // The following code is generating surface acne in ground. // It is only necessary inside atmosphere rendering. JCC // If r0 > Rg + EPS (we are not intersecting the ground), // we get a constant initial ground radiance - if (r0 > Rg + 0.01) { - reflectance = vec4(0.4, 0.4, 0.4, 0.0); - } + // if (r0 > Rg + 0.01) { + // reflectance = vec4(0.0, 0.0, 0.0, 0.0); + // } // L0 is not included in the irradiance texture. // We first calculate the light attenuation from the top of the atmosphere @@ -693,7 +702,8 @@ vec3 groundColor(const vec3 x, const float t, const vec3 v, const vec3 s, const } // Finally, we attenuate the surface Radiance from the the point x0 to the camera location. - reflectedRadiance = attenuationXtoX0 * groundRadiance; + reflectedRadiance = attenuationXtoX0 * groundRadiance; + } else { // ray looking at the sky reflectedRadiance = vec3(0.0f); } @@ -727,109 +737,128 @@ vec3 sunColor(const vec3 x, const float t, const vec3 v, const vec3 s, const flo } void main() { - // Acessing Depth Buffer. - // float geoDepth = 0.0; - // vec4 colorMean = vec4(0.0); - // for (int i = 0; i < nAaSamples; i++) { - // geoDepth += denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x); - // colorMean += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); - // } + //float geoDepth = 0.0; + vec4 meanColor = vec4(0.0); + vec4 meanNormal = vec4(0.0); + vec4 meanPosition = vec4(0.0); + for (int i = 0; i < nAaSamples; i++) { + meanNormal += texelFetch(mainNormalReflectanceTexture, ivec2(gl_FragCoord), i); + meanColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); + meanPosition += texelFetch(mainPositionTexture, ivec2(gl_FragCoord), i); + // geoDepth += denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x); + } + meanColor /= nAaSamples; + meanNormal /= nAaSamples; + meanPosition /= nAaSamples; // geoDepth /= nAaSamples; - // colorMean /= nAaSamples; + + //meanPosition = texture2D(mainPositionTexture, vec2(gl_FragCoord)); // Ray in object space dRay ray; dvec4 planetPositionObjectCoords = dvec4(0.0); - //dvec4 planetPositionObjectCoords = dInverseTransformMatrix * dvec4(-dObjpos.xyz + dObjpos.xyz, 1.0); - //dvec4 planetPositionObjectCoords = dInverseTransformMatrix * dvec4(-dObjpos.xyz + dvec3(0.0), 1.0); - dCalculateRay2(ray, planetPositionObjectCoords); - //dCalculateInterpolatedRay(ray, planetPositionObjectCoords); + dvec4 cameraPositionInObject = dvec4(0.0); + + dCalculateRay2(ray, planetPositionObjectCoords, cameraPositionInObject); bool insideATM = false; double offset = 0.0; double maxLength = 0.0; - bool intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt-10*EPSILON, - insideATM, offset, maxLength ); - //bool intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rg, - // insideATM, offset, maxLength ); - // Ellipsoid ellipsoid; - // ellipsoid.center = dvec4(0.0); - // ellipsoid.size = dvec3(6378.1366, 6356.7519, 6378.1366); - // bool intersectATM = dIntersectEllipsoid(ray, ellipsoid, offset, maxLength); + bool intersectATM = false; - // Instead of ray-ellipsoid intersection lets transform the ray to a sphere: - // dRay transfRay; - // transfRay.origin = ray.origin; - // transfRay.direction = ray.direction; + if ( ellipsoidRadii.x != 0.0 || ellipsoidRadii.y != 0.0 || ellipsoidRadii.z != 0.0) { + // Instead of ray-ellipsoid intersection lets transform the ray to a sphere: + dRay transfRay; + transfRay.origin = ray.origin; + transfRay.direction = ray.direction; - // transfRay.origin.x *= 1.0/6378.1366; - // transfRay.direction.x *= 1.0/6378.1366; - // transfRay.origin.z *= 1.0/6356.7519; - // transfRay.direction.z *= 1.0/6356.7519; - // transfRay.origin.y *= 1.0/1.0/6378.1366; - // transfRay.direction.y *= 1.0/1.0/6378.1366; - // transfRay.direction.xyz = normalize(transfRay.direction.xyz); - // bool intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, 1.0 + 15, - // insideATM, offset, maxLength ); + transfRay.origin.x *= 1000.0/ellipsoidRadii.x; + transfRay.direction.x *= 1000.0/ellipsoidRadii.x; + transfRay.origin.z *= 1000.0/ellipsoidRadii.y; + transfRay.direction.z *= 1000.0/ellipsoidRadii.y; + transfRay.origin.y *= 1000.0/ellipsoidRadii.z; + transfRay.direction.y *= 1000.0/ellipsoidRadii.z; + transfRay.direction.xyz = normalize(transfRay.direction.xyz); - //bool intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, Rt+EPSILON, - // insideATM, offset, maxLength ); + // intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, 1.0 + EPSILON, + // insideATM, offset, maxLength ); + + intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, transfRay, Rt+EPSILON, + insideATM, offset, maxLength ); + } else { + intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt-10*EPSILON, + insideATM, offset, maxLength ); + } if ( intersectATM ) { // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel // in the depth buffer is less than the distance to the atmosphere then the atmosphere // is occluded - // if (pixelDepth < offset) { - // return pixelColorFromOriginalColorBuffer; - // } - //renderTarget += vec4(1.0, 1.0, 1.0, 0.5); - // Following paper nomenclature - double t = offset; - vec3 attenuation; - - // Moving observer from camera location to top atmosphere - vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz); - float r = 0.0;//length(x); - vec3 v = vec3(ray.direction.xyz); - float mu = 0.0;//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 this offset so the - // next comparison with the planet's ground make sense: - //pixelDepth -= offset; - - vec3 inscatterColor = inscatterNoTestRadiance(x, tF, v, s, r, mu, attenuation); - vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation); - vec3 sunColor = sunColor(x, tF, v, s, r, mu); + dvec3 tmpPos = dmat3(dInverseCamRotTransform) * dvec3(dInverseScaleTransformMatrix * meanPosition); + dvec4 fragWorldCoords = dvec4(dCampos + tmpPos, 1.0); + dvec4 fragObjectCoords = dInverseTransformMatrix * dvec4(-dObjpos.xyz + fragWorldCoords.xyz, 1.0); + double pixelDepth = distance(cameraPositionInObject.xyz, fragObjectCoords.xyz); - //renderTarget = vec4(HDR(inscatterColor), 1.0); - //renderTarget = vec4(HDR(groundColor), 1.0); - //renderTarget = vec4(groundColor, 1.0); - //renderTarget = vec4(HDR(sunColor), 1.0); - //renderTarget = vec4(HDR(sunColor), 1.0); - vec4 finalRadiance = vec4(HDR(inscatterColor + sunColor), 1.0); - //vec4 finalRadiance = vec4(inscatterColor, 1.0); - //vec4 finalRadiance = vec4(HDR(groundColor), 1.0); - //vec4 finalRadiance = vec4(HDR(inscatterColor), 1.0); - //vec4 finalRadiance = vec4(HDR(sunColor), 1.0); - //vec4 finalRadiance = vec4(sunColor, 1.0); - //vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0); - //if ( finalRadiance.xyz == vec3(0.0)) - // finalRadiance.w = 0.0; - - //renderTarget = finalRadiance + colorMean; - renderTarget = finalRadiance; - //renderTarget = colorMean; - //renderTarget += vec4(0.5, 0.0, 0.0, 0.5); - //renderTarget = vec4(0.0); + if (pixelDepth < offset) { + renderTarget = meanColor; + } else { + // Following paper nomenclature + double t = offset; + vec3 attenuation; + + // Moving observer from camera location to top atmosphere + vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz); + float r = 0.0;//length(x); + vec3 v = vec3(ray.direction.xyz); + float mu = 0.0;//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 this offset so the + // next comparison with the planet's ground make sense: + pixelDepth -= offset; + + vec3 inscatterColor = inscatterNoTestRadiance(x, tF, v, s, r, mu, attenuation, + vec3(fragObjectCoords.xyz), maxLength, pixelDepth); + vec3 groundColor = groundColor(x, tF, v, s, r, mu, attenuation, meanColor, meanNormal); + vec3 sunColor = sunColor(x, tF, v, s, r, mu); + + //renderTarget = vec4(HDR(inscatterColor), 1.0); + //renderTarget = vec4(HDR(groundColor), 1.0); + //renderTarget = vec4(groundColor, 1.0); + //renderTarget = vec4(HDR(sunColor), 1.0); + //renderTarget = vec4(HDR(sunColor), 1.0); + //vec4 finalRadiance = vec4(HDR(inscatterColor + sunColor), 1.0); + //finalRadiance = mix(finalRadiance, meanColor); + //vec4 finalRadiance = vec4(inscatterColor, 1.0); + //vec4 finalRadiance = vec4(HDR(groundColor), 1.0); + //vec4 finalRadiance = vec4(HDR(inscatterColor), 1.0); + //vec4 finalRadiance = vec4(HDR(sunColor), 1.0); + //vec4 finalRadiance = vec4(sunColor, 1.0); + vec4 finalRadiance = vec4(HDR(inscatterColor + groundColor + sunColor), 1.0); + //if ( finalRadiance.xyz == vec3(0.0)) + // finalRadiance.w = 0.0; + + //renderTarget = finalRadiance + colorMean; + renderTarget = finalRadiance; + //renderTarget = vec4(normalize(meanNormal.xyz), 1.0); + dvec4 ttmp = dInverseScaleTransformMatrix * meanPosition; + dvec3 ttmp2 = dmat3(dInverseCamRotTransform) * dvec3(ttmp); + dvec4 worldCoords = dvec4(dCampos + ttmp2, 1.0); + dvec4 positionInObject = dInverseTransformMatrix * dvec4(-dObjpos.xyz + worldCoords.xyz, 1.0); + //renderTarget = vec4(positionInObject.xyz, 1.0); + //renderTarget = vec4(meanColor.xyz, 1.0); + //renderTarget = meanColor; + //renderTarget = vec4(0.5, 0.0, 0.0, 0.5); + //renderTarget = vec4(0.0); + } } else { - renderTarget = vec4(1.0, 1.0, 0.0, 0.0); + //renderTarget = vec4(1.0, 1.0, 0.0, 1.0); //renderTarget = vec4(0.0); - //renderTarget = colorMean; - } + renderTarget = meanColor; + } } diff --git a/modules/atmosphere/shaders/nighttexture_fs.glsl b/modules/atmosphere/shaders/nighttexture_fs.glsl index 22874edf3e..49eaa2663e 100644 --- a/modules/atmosphere/shaders/nighttexture_fs.glsl +++ b/modules/atmosphere/shaders/nighttexture_fs.glsl @@ -40,6 +40,7 @@ in vec2 vs_nightTex; in vec4 vs_normal; in vec4 vs_position; in vec4 test; +in vec4 vs_gPosition; #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" @@ -49,6 +50,10 @@ Fragment getFragment() { vec4 diffuse2 = texture(nightTex, vs_st); Fragment frag; + frag.gPosition = vs_gPosition; + // TODO: get the write reflectance from the texture + frag.gNormalReflectance = vec4(vs_normal.xyz, 0.5); + if (_performShading) { // directional lighting vec3 origin = vec3(0.0); diff --git a/modules/atmosphere/shaders/nighttexture_vs.glsl b/modules/atmosphere/shaders/nighttexture_vs.glsl index d22246fb3f..865c07a468 100644 --- a/modules/atmosphere/shaders/nighttexture_vs.glsl +++ b/modules/atmosphere/shaders/nighttexture_vs.glsl @@ -35,6 +35,7 @@ layout(location = 2) in vec3 in_normal; out vec2 vs_st; out vec4 vs_normal; out vec4 vs_position; +out vec4 vs_gPosition; uniform mat4 ModelTransform; uniform mat4 modelViewProjectionTransform; @@ -52,8 +53,15 @@ void main() { vs_normal = normalize(ModelTransform * vec4(in_normal,0)); // vs_normal = vec4(in_normal, 0.0); + // The tmp is now in the OS eye space (camera rig space) + // and wrtitten using PSC coords. + // position is in the same space, i.e., OS eye space but + // in meters (no PSC coords). vec4 position = vec4(tmp.xyz * pow(10, tmp. w), 1.0); + // G-Buffer + vs_gPosition = position; + if (_hasHeightMap) { float height = texture(heightTex, in_st).r; vec3 displacementDirection = abs(normalize(in_normal.xyz)); @@ -62,7 +70,10 @@ void main() { } position = modelViewProjectionTransform * position; - vs_position = z_normalization(position); + // The depth position will be handle later by the fragment shader, + // so the z coordinate here is set to 0 (zero) to avoid precision problems + vs_position = z_normalization(position); + gl_Position = vs_position; } diff --git a/modules/atmosphere/shaders/renderableplanet_fs.glsl b/modules/atmosphere/shaders/renderableplanet_fs.glsl index 9240ff32de..09eabe5fe1 100644 --- a/modules/atmosphere/shaders/renderableplanet_fs.glsl +++ b/modules/atmosphere/shaders/renderableplanet_fs.glsl @@ -38,6 +38,7 @@ uniform sampler2D texture1; in vec2 vs_st; in vec4 vs_normal; in vec4 vs_position; +in vec4 vs_gPosition; #include "fragment.glsl" #include "PowerScaling/powerScaling_fs.hglsl" @@ -47,6 +48,7 @@ Fragment getFragment() { vec4 diffuse = texture(texture1, vs_st); Fragment frag; + if (_performShading) { // directional lighting vec3 origin = vec3(0.0); @@ -78,5 +80,10 @@ Fragment getFragment() { frag.color = diffuse; frag.depth = vs_position.w; + frag.gColor = diffuse; + frag.gPosition = vs_gPosition; + // TODO: get the write reflectance from the texture + frag.gNormalReflectance = vec4(vs_normal.xyz, 0.5); + return frag; } diff --git a/modules/atmosphere/shaders/renderableplanet_vs.glsl b/modules/atmosphere/shaders/renderableplanet_vs.glsl index ccf5874ee8..dd99d0ca6c 100644 --- a/modules/atmosphere/shaders/renderableplanet_vs.glsl +++ b/modules/atmosphere/shaders/renderableplanet_vs.glsl @@ -36,6 +36,7 @@ out vec4 vs_normal; out vec4 vs_position; out vec4 vs_posWorld; out float s; +out vec4 vs_gPosition; #include "PowerScaling/powerScaling_vs.hglsl" @@ -48,19 +49,28 @@ void main() { // this is wrong for the normal. The normal transform is the transposed inverse of the model transform vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // The things is not in world coordinates, they are in - // regular view/eye coordinates. + // The tmp is now in the OS eye space (camera rig space) + // and wrtitten using PSC coords. + // position is in the same space, i.e., OS eye space but + // in meters (no PSC coords). vec4 position = pscTransform(tmp, ModelTransform); + // G-Buffer + vs_gPosition = position; + vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0); vs_posWorld = conv; + // OS Eye space and PSC coords vs_position = tmp; // Now is transforming from view position to SGCT projection // coordinates. position = ViewProjection * position; + + // The depth position will be handle later by the fragment shader, + // so the z coordinate here is set to 0 (zero) to avoid precision problems gl_Position = z_normalization(position); } diff --git a/modules/atmosphere/shaders/shadow_fs.glsl b/modules/atmosphere/shaders/shadow_fs.glsl index 536b6d6718..0c6a760aaf 100644 --- a/modules/atmosphere/shaders/shadow_fs.glsl +++ b/modules/atmosphere/shaders/shadow_fs.glsl @@ -50,6 +50,7 @@ in vec2 vs_st; in vec4 vs_normal; in vec4 vs_position; in vec4 vs_posWorld; +in vec4 vs_gPosition; #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" @@ -94,6 +95,10 @@ Fragment getFragment() { vec4 diffuse = texture(texture1, vs_st); Fragment frag; + frag.gPosition = vs_gPosition; + // TODO: get the write reflectance from the texture + frag.gNormalReflectance = vec4(vs_normal.xyz, 0.5); + if (_performShading) { // directional lighting vec3 origin = vec3(0.0); diff --git a/modules/atmosphere/shaders/shadow_nighttexture_fs.glsl b/modules/atmosphere/shaders/shadow_nighttexture_fs.glsl index b8d5b32819..5f8e9f7337 100644 --- a/modules/atmosphere/shaders/shadow_nighttexture_fs.glsl +++ b/modules/atmosphere/shaders/shadow_nighttexture_fs.glsl @@ -52,6 +52,7 @@ in vec2 vs_nightTex; in vec4 vs_normal; in vec4 vs_position; in vec4 vs_posWorld; +in vec4 vs_gPosition; #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" @@ -96,7 +97,8 @@ Fragment getFragment() { vec4 diffuse = texture(texture1, vs_st); vec4 diffuse2 = texture(nightTex, vs_st); - Fragment frag; + Fragment frag; + if (_performShading) { // directional lighting vec3 origin = vec3(0.0); @@ -126,6 +128,11 @@ Fragment getFragment() { frag.color = diffuse; frag.depth = depth; + frag.gColor = diffuse; + frag.gPosition = vs_gPosition; + // TODO: get the write reflectance from the texture + frag.gNormalReflectance = vec4(vs_normal.xyz, 0.5); + return frag; } diff --git a/modules/atmosphere/shaders/shadow_nighttexture_vs.glsl b/modules/atmosphere/shaders/shadow_nighttexture_vs.glsl index cb2dc8c1b1..4187f48f3e 100644 --- a/modules/atmosphere/shaders/shadow_nighttexture_vs.glsl +++ b/modules/atmosphere/shaders/shadow_nighttexture_vs.glsl @@ -32,12 +32,16 @@ layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; //layout(location = 3) in vec2 in_nightTex; +uniform sampler2D heightTex; +uniform bool _hasHeightMap; +uniform float _heightExaggeration; out vec2 vs_st; out vec4 vs_normal; out vec4 vs_position; out vec4 vs_posWorld; out float s; +out vec4 vs_gPosition; #include "PowerScaling/powerScaling_vs.hglsl" @@ -51,18 +55,36 @@ void main() // this is wrong for the normal. The normal transform is the transposed inverse of the model transform vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // The things is not in world coordinates, they are in - // regular view/eye coordinates. + // The tmp is now in the OS eye space (camera rig space) + // and wrtitten using PSC coords. + // position is in the same space, i.e., OS eye space but + // in meters (no PSC coords). vec4 position = pscTransform(tmp, ModelTransform); + vs_gPosition = position; + + if (_hasHeightMap) { + float height = texture(heightTex, in_st).r; + vec3 displacementDirection = abs(normalize(in_normal.xyz)); + float displacementFactor = height * _heightExaggeration; + position.xyz = position.xyz + displacementDirection * displacementFactor; + } + + // G-Buffer + //vs_gPosition = position; vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0); vs_posWorld = conv; + // OS Eye space and PSC coords vs_position = tmp; + // Now is transforming from view position to SGCT projection // coordinates. position = ViewProjection * position; + + // The depth position will be handle later by the fragment shader, + // so the z coordinate here is set to 0 (zero) to avoid precision problems gl_Position = z_normalization(position); } diff --git a/modules/atmosphere/shaders/shadow_vs.glsl b/modules/atmosphere/shaders/shadow_vs.glsl index e8dd42f3fb..26b0d7d3c9 100644 --- a/modules/atmosphere/shaders/shadow_vs.glsl +++ b/modules/atmosphere/shaders/shadow_vs.glsl @@ -40,6 +40,7 @@ out vec4 vs_normal; out vec4 vs_position; out vec4 vs_posWorld; out float s; +out vec4 vs_gPosition; #include "PowerScaling/powerScaling_vs.hglsl" @@ -53,10 +54,15 @@ void main() // this is wrong for the normal. The normal transform is the transposed inverse of the model transform vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // The things is not in world coordinates, they are in - // regular view/eye coordinates. + // The tmp is now in the OS eye space (camera rig space) + // and wrtitten using PSC coords. + // position is in the same space, i.e., OS eye space but + // in meters (no PSC coords). vec4 position = pscTransform(tmp, ModelTransform); + // G-Buffer + vs_gPosition = position; + vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0); @@ -74,5 +80,8 @@ void main() // Now is transforming from view position to SGCT projection // coordinates. position = ViewProjection * position; + + // The depth position will be handle later by the fragment shader, + // so the z coordinate here is set to 0 (zero) to avoid precision problems gl_Position = z_normalization(position); } diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 6b43aca744..a315e395aa 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -28,6 +28,14 @@ #include #include +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED +#include +#include +#include +#include +#include +#endif + namespace { const char* keyFrame = "Frame"; const char* keyRadii = "Radii"; @@ -35,6 +43,17 @@ namespace { const char* keyCameraMinHeight = "CameraMinHeight"; const char* keySegmentsPerPatch = "SegmentsPerPatch"; const char* keyLayers = "Layers"; +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + const std::string keyAtmosphere = "Atmosphere"; + const std::string keyAtmosphereRadius = "AtmoshereRadius"; + const std::string keyPlanetRadius = "PlanetRadius"; + const std::string keyAverageGroundReflectance = "PlanetAverageGroundReflectance"; + const std::string keyRayleigh = "Rayleigh"; + const std::string keyRayleighHeightScale = "H_R"; + const std::string keyMie = "Mie"; + const std::string keyMieHeightScale = "H_M"; + const std::string keyMiePhaseConstant = "G"; +#endif } namespace openspace { @@ -69,6 +88,36 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) }) , _debugPropertyOwner("Debug") , _texturePropertyOwner("Textures") +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + , _atmosphereProperties({ + FloatProperty("atmmosphereHeight", "Atmosphere Height (KM)", 60.0f, 0.1f, 1000.0f), + FloatProperty("averageGroundReflectance", "Average Ground Reflectance (%)", 0.1f, 0.0f, 1.0f), + FloatProperty("rayleighHeightScale", "Rayleigh Height Scale (KM)", 8.0f, 0.1f, 20.0f), + FloatProperty("rayleighScatteringCoeffX", "Rayleigh Scattering Coeff X (x10e-3)", 1.0f, 0.01f, 100.0f), + FloatProperty("rayleighScatteringCoeffY", "Rayleigh Scattering Coeff Y (x10e-3)", 1.0f, 0.01f, 100.0f), + FloatProperty("rayleighScatteringCoeffZ", "Rayleigh Scattering Coeff Z (x10e-3)", 1.0f, 0.01f, 100.0f), + FloatProperty("mieHeightScale", "Mie Height Scale (KM)", 1.2f, 0.1f, 20.0f), + FloatProperty("mieScatteringCoefficient", "Mie Scattering Coefficient (x10e-3)", 4.0f, 0.01f, 1000.0f), + FloatProperty("mieScatteringExtinctionPropCoefficient", + "Mie Scattering/Extinction Proportion Coefficient (%)", 0.9f, 0.01f, 1.0f), + FloatProperty("mieAsymmetricFactorG", "Mie Asymmetric Factor G", 0.85f, -1.0f, 1.0f), + FloatProperty("sunIntensity", "Sun Intensity", 50.0f, 0.1f, 1000.0f), + FloatProperty("hdrExposition", "HDR", 0.4f, 0.01f, 5.0f) + }) + , _atmospherePropertyOwner("Atmosphere") + , _atmosphereRadius(0.f) + , _atmospherePlanetRadius(0.f) + , _planetAverageGroundReflectance(0.f) + , _rayleighHeightScale(0.f) + , _mieHeightScale(0.f) + , _miePhaseConstant(0.f) + , _mieExtinctionCoeff(glm::vec3(0.f)) + , _rayleighScatteringCoeff(glm::vec3(0.f)) + , _mieScatteringCoeff(glm::vec3(0.f)) + , _sunRadianceIntensity(50.0f) + , _hdrConstant(0.4f) + , _atmosphereEnabled(false) +#endif { setName("RenderableGlobe"); @@ -138,13 +187,197 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) addPropertySubOwner(_debugPropertyOwner); addPropertySubOwner(_layerManager.get()); + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + //================================================================ + //========== Reads Atmosphere Entries from mod file ============== + //================================================================ + bool errorReadingAtmosphereData = false; + ghoul::Dictionary atmosphereDictionary; + bool success = dictionary.getValue(keyAtmosphere, atmosphereDictionary); + if (success) { + if (!atmosphereDictionary.getValue(keyAtmosphereRadius, _atmosphereRadius)) { + errorReadingAtmosphereData = true; + //LWARNING("No Atmosphere Radius value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!atmosphereDictionary.getValue(keyPlanetRadius, _atmospherePlanetRadius)) { + errorReadingAtmosphereData = true; + //LWARNING("No Planet Radius value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!atmosphereDictionary.getValue(keyAverageGroundReflectance, _planetAverageGroundReflectance)) { + errorReadingAtmosphereData = true; + //LWARNING("No Average Atmosphere Ground Reflectance value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + ghoul::Dictionary rayleighDictionary; + success = atmosphereDictionary.getValue(keyRayleigh, rayleighDictionary); + + if (success) { + // Not using right now. + glm::vec3 rayleighWavelengths; + success = rayleighDictionary.getValue("Coefficients.Wavelengths", rayleighWavelengths); + + if (!rayleighDictionary.getValue("Coefficients.Scattering", _rayleighScatteringCoeff)) { + errorReadingAtmosphereData = true; + //LWARNING("No Rayleigh Scattering parameters expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!rayleighDictionary.getValue(keyRayleighHeightScale, _rayleighHeightScale)) { + errorReadingAtmosphereData = true; + //LWARNING("No Rayleigh Height Scale value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + } + else { + errorReadingAtmosphereData = true; + //LWARNING("No Rayleigh parameters expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + ghoul::Dictionary mieDictionary; + success = atmosphereDictionary.getValue(keyMie, mieDictionary); + if (success) { + if (!mieDictionary.getValue(keyMieHeightScale, _mieHeightScale)) { + errorReadingAtmosphereData = true; + //LWARNING("No Mie Height Scale value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!mieDictionary.getValue("Coefficients.Scattering", _mieScatteringCoeff)) { + errorReadingAtmosphereData = true; + //LWARNING("No Mie Scattering parameters expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!mieDictionary.getValue("Coefficients.Extinction", _mieExtinctionCoeff)) { + errorReadingAtmosphereData = true; + //LWARNING("No Mie Extinction parameters expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!mieDictionary.getValue(keyMiePhaseConstant, _miePhaseConstant)) { + errorReadingAtmosphereData = true; + //LWARNING("No Mie Phase Constant value expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + } + else { + errorReadingAtmosphereData = true; + //LWARNING("No Mie parameters expecified for Atmosphere Effects of " + // << name << " planet.\nDisabling atmosphere effects for this planet."); + } + + if (!errorReadingAtmosphereData) { + _atmosphereEnabled = true; + + //======================================================== + //============== Atmosphere Properties =================== + //======================================================== + + _atmosphereProperties.atmosphereHeightP.set(_atmosphereRadius - _atmospherePlanetRadius); + _atmosphereProperties.atmosphereHeightP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.atmosphereHeightP); + + _atmosphereProperties.groundAverageReflectanceP.set(_planetAverageGroundReflectance); + _atmosphereProperties.groundAverageReflectanceP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.groundAverageReflectanceP); + + _atmosphereProperties.rayleighHeightScaleP.set(_rayleighHeightScale); + _atmosphereProperties.rayleighHeightScaleP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.rayleighHeightScaleP); + + _atmosphereProperties.rayleighScatteringCoeffXP.set(_rayleighScatteringCoeff.x * 1000.0f); + _atmosphereProperties.rayleighScatteringCoeffXP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.rayleighScatteringCoeffXP); + + _atmosphereProperties.rayleighScatteringCoeffYP.set(_rayleighScatteringCoeff.y * 1000.0f); + _atmosphereProperties.rayleighScatteringCoeffYP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.rayleighScatteringCoeffYP); + + _atmosphereProperties.rayleighScatteringCoeffZP.set(_rayleighScatteringCoeff.z * 1000.0f); + _atmosphereProperties.rayleighScatteringCoeffZP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.rayleighScatteringCoeffZP); + + _atmosphereProperties.mieHeightScaleP.set(_mieHeightScale); + _atmosphereProperties.mieHeightScaleP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.mieHeightScaleP); + + _atmosphereProperties.mieScatteringCoefficientP.set(_mieScatteringCoeff.r * 1000.0f); + _atmosphereProperties.mieScatteringCoefficientP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.mieScatteringCoefficientP); + + _atmosphereProperties.mieScatteringExtinctionPropCoefficientP.set(_mieScatteringCoeff.r / _mieExtinctionCoeff.r); + _atmosphereProperties.mieScatteringExtinctionPropCoefficientP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.mieScatteringExtinctionPropCoefficientP); + + _atmosphereProperties.mieAsymmetricFactorGP.set(_miePhaseConstant); + _atmosphereProperties.mieAsymmetricFactorGP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.mieAsymmetricFactorGP); + + _atmosphereProperties.sunIntensityP.set(_sunRadianceIntensity); + _atmosphereProperties.sunIntensityP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.sunIntensityP); + + _atmosphereProperties.hdrExpositionP.set(_hdrConstant); + _atmosphereProperties.hdrExpositionP.onChange(std::bind(&RenderableGlobe::updateAtmosphereParameters, this)); + _atmospherePropertyOwner.addProperty(_atmosphereProperties.hdrExpositionP); + + addPropertySubOwner(_atmospherePropertyOwner); + } + } +#endif } bool RenderableGlobe::initialize() { +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + _deferredcaster = std::make_unique(); + if (_deferredcaster) { + _deferredcaster->setAtmosphereRadius(_atmosphereRadius); + _deferredcaster->setPlanetRadius(_atmospherePlanetRadius); + _deferredcaster->setPlanetAverageGroundReflectance(_planetAverageGroundReflectance); + _deferredcaster->setRayleighHeightScale(_rayleighHeightScale); + _deferredcaster->setMieHeightScale(_mieHeightScale); + _deferredcaster->setMiePhaseConstant(_miePhaseConstant); + _deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity); + _deferredcaster->setHDRConstant(_hdrConstant); + _deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff); + _deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff); + _deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff); + _deferredcaster->setEllipsoidRadii(_ellipsoid.radii()); + _deferredcaster->initialize(); + } + + OsEng.renderEngine().deferredcasterManager().attachDeferredcaster(*_deferredcaster.get()); + + std::function onChange = [&](bool enabled) { + if (enabled) { + OsEng.renderEngine().deferredcasterManager().attachDeferredcaster(*_deferredcaster.get()); + } + else { + OsEng.renderEngine().deferredcasterManager().detachDeferredcaster(*_deferredcaster.get()); + } + }; + + onEnabledChange(onChange); +#endif + return _distanceSwitch.initialize(); } bool RenderableGlobe::deinitialize() { +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + if (_deferredcaster) { + OsEng.renderEngine().deferredcasterManager().detachDeferredcaster(*_deferredcaster.get()); + _deferredcaster = nullptr; + } +#endif + return _distanceSwitch.deinitialize(); } @@ -152,7 +385,7 @@ bool RenderableGlobe::isReady() const { return true; } -void RenderableGlobe::render(const RenderData& data) { +void RenderableGlobe::render(const RenderData& data, RendererTasks& tasks) { bool statsEnabled = _debugProperties.collectStats.value(); _chunkedLodGlobe->stats.setEnabled(statsEnabled); @@ -177,6 +410,11 @@ void RenderableGlobe::render(const RenderData& data) { if (_savedCamera != nullptr) { DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera); } + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + DeferredcasterTask task{ _deferredcaster.get(), data }; + tasks.deferredcasterTasks.push_back(task); +#endif } void RenderableGlobe::update(const UpdateData& data) { @@ -199,6 +437,13 @@ void RenderableGlobe::update(const UpdateData& data) { } _layerManager->update(); _chunkedLodGlobe->update(data); + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + if (_deferredcaster) { + _deferredcaster->setTime(data.time); + _deferredcaster->setModelTransform(_cachedModelTransform); + } +#endif } glm::dvec3 RenderableGlobe::projectOnEllipsoid(glm::dvec3 position) { @@ -252,5 +497,43 @@ void RenderableGlobe::setSaveCamera(std::shared_ptr camera) { _savedCamera = camera; } +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED +void RenderableGlobe::updateAtmosphereParameters() { + bool executeComputation = true; + if (_sunRadianceIntensity != _atmosphereProperties.sunIntensityP.value() || + _hdrConstant != _atmosphereProperties.hdrExpositionP.value()) + executeComputation = false; + _atmosphereRadius = _atmospherePlanetRadius + _atmosphereProperties.atmosphereHeightP.value(); + _planetAverageGroundReflectance = _atmosphereProperties.groundAverageReflectanceP.value(); + _rayleighHeightScale = _atmosphereProperties.rayleighHeightScaleP.value(); + _rayleighScatteringCoeff = glm::vec3(_atmosphereProperties.rayleighScatteringCoeffXP.value() * 0.001f, + _atmosphereProperties.rayleighScatteringCoeffYP.value() * 0.001f, + _atmosphereProperties.rayleighScatteringCoeffZP.value() * 0.001f); + _mieHeightScale = _atmosphereProperties.mieHeightScaleP.value(); + _mieScatteringCoeff = glm::vec3(_atmosphereProperties.mieScatteringCoefficientP.value() * 0.001f); + _mieExtinctionCoeff = _mieScatteringCoeff * (1.0f / static_cast(_atmosphereProperties.mieScatteringExtinctionPropCoefficientP.value())); + _miePhaseConstant = _atmosphereProperties.mieAsymmetricFactorGP.value(); + _sunRadianceIntensity = _atmosphereProperties.sunIntensityP.value(); + _hdrConstant = _atmosphereProperties.hdrExpositionP.value(); + + if (_deferredcaster) { + _deferredcaster->setAtmosphereRadius(_atmosphereRadius); + _deferredcaster->setPlanetRadius(_atmospherePlanetRadius); + _deferredcaster->setPlanetAverageGroundReflectance(_planetAverageGroundReflectance); + _deferredcaster->setRayleighHeightScale(_rayleighHeightScale); + _deferredcaster->setMieHeightScale(_mieHeightScale); + _deferredcaster->setMiePhaseConstant(_miePhaseConstant); + _deferredcaster->setSunRadianceIntensity(_sunRadianceIntensity); + _deferredcaster->setHDRConstant(_hdrConstant); + _deferredcaster->setRayleighScatteringCoefficients(_rayleighScatteringCoeff); + _deferredcaster->setMieScatteringCoefficients(_mieScatteringCoeff); + _deferredcaster->setMieExtinctionCoefficients(_mieExtinctionCoeff); + + if (executeComputation) + _deferredcaster->preCalculateAtmosphereParam(); + } +} +#endif + } // namespace globebrowsing } // namespace openspace diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index b90e01eec2..4bbb848949 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -34,6 +34,11 @@ #include namespace openspace { + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + class AtmosphereDeferredcaster; +#endif + namespace globebrowsing { class ChunkedLodGlobe; @@ -76,6 +81,25 @@ public: properties::FloatProperty lodScaleFactor; properties::FloatProperty cameraMinHeight; }; + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + struct AtmosphereProperties { + properties::FloatProperty atmosphereHeightP; + properties::FloatProperty groundAverageReflectanceP; + properties::FloatProperty rayleighHeightScaleP; + properties::FloatProperty rayleighScatteringCoeffXP; + properties::FloatProperty rayleighScatteringCoeffYP; + properties::FloatProperty rayleighScatteringCoeffZP; + properties::FloatProperty mieHeightScaleP; + properties::FloatProperty mieScatteringCoefficientP; + properties::FloatProperty mieScatteringExtinctionPropCoefficientP; + properties::FloatProperty mieAsymmetricFactorGP; + properties::FloatProperty sunIntensityP; + properties::FloatProperty hdrExpositionP; + }; + + const AtmosphereProperties& atmosphereProperties() const; +#endif RenderableGlobe(const ghoul::Dictionary& dictionary); ~RenderableGlobe() = default; @@ -84,7 +108,7 @@ public: bool deinitialize() override; bool isReady() const override; - void render(const RenderData& data) override; + void render(const RenderData& data, RendererTasks& tasks) override; void update(const UpdateData& data) override; // Getters that perform calculations @@ -125,6 +149,33 @@ private: GeneralProperties _generalProperties; properties::PropertyOwner _debugPropertyOwner; properties::PropertyOwner _texturePropertyOwner; + +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + // Atmosphere Data + bool _atmosphereEnabled; + float _atmosphereRadius; + float _atmospherePlanetRadius; + float _planetAverageGroundReflectance; + float _rayleighHeightScale; + float _mieHeightScale; + float _miePhaseConstant; + float _sunRadianceIntensity; + float _hdrConstant; + glm::vec3 _mieExtinctionCoeff; + glm::vec3 _rayleighScatteringCoeff; + glm::vec3 _mieScatteringCoeff; + + AtmosphereProperties _atmosphereProperties; + properties::PropertyOwner _atmospherePropertyOwner; + + // Deferred ATM Rendering + std::unique_ptr _deferredcaster; +#endif + +private: +#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED + void updateAtmosphereParameters(); +#endif }; } // namespace globebrowsing diff --git a/modules/globebrowsing/rendering/chunkrenderer.cpp b/modules/globebrowsing/rendering/chunkrenderer.cpp index 717c0c4038..edf13db8f1 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.cpp +++ b/modules/globebrowsing/rendering/chunkrenderer.cpp @@ -161,11 +161,12 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da } const Ellipsoid& ellipsoid = chunk.owner().ellipsoid(); - + if (_layerManager->hasAnyBlendingLayersEnabled()) { // Calculations are done in the reference frame of the globe. Hence, the // camera position needs to be transformed with the inverse model matrix glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform(); + // Send the matrix inverse (already calculated) to the fragment for the global and local shader (JCC) glm::dvec3 cameraPosition = glm::dvec3( inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1)); float distanceScaleFactor = chunk.owner().generalProperties().lodScaleFactor * @@ -190,6 +191,7 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da "modelViewProjectionTransform", modelViewProjectionTransform); programObject->setUniform("minLatLon", glm::vec2(swCorner.toLonLatVec2())); programObject->setUniform("lonLatScalingFactor", glm::vec2(patchSize.toLonLatVec2())); + // Ellipsoid Radius (Model Space) programObject->setUniform("radiiSquared", glm::vec3(ellipsoid.radiiSquared())); if (_layerManager->layerGroup( @@ -246,6 +248,7 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat } // Calculate other uniform variables needed for rendering + // Send the matrix inverse to the fragment for the global and local shader (JCC) dmat4 modelTransform = chunk.owner().modelTransform(); dmat4 viewTransform = data.camera.combinedViewMatrix(); dmat4 modelViewTransform = viewTransform * modelTransform; diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 0bdf633ec6..8c1626ed85 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -33,6 +33,10 @@ Fragment getFragment() { frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02); #endif // SHOW_CHUNK_EDGES + // frag.gColor = frag.color; + // frag.gNormal = normal; + // frag.gPosition = p; + frag.depth = fs_position.w; return frag; } diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 4601915b0c..e5e40149a4 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -27,12 +27,17 @@ Fragment getFragment() { Fragment frag; - frag.color = getTileFragColor(); + // Final Color of a Fragment + frag.color = getTileFragColor(); #if SHOW_CHUNK_EDGES frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.005); #endif // SHOW_CHUNK_EDGES + // frag.gColor = frag.color; + // frag.gNormal = normal; + // frag.gPosition = p; + frag.depth = fs_position.w; return frag; } diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 8665e88030..8759bbdc17 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -85,6 +85,9 @@ void main() { vec4 positionClippingSpace = projectionTransform * vec4(p, 1); + // p is in SGCT View space. + //p_obj = Model <- InverseCameraCombined <- p + // Write output fs_uv = in_uv; fs_position = z_normalization(positionClippingSpace); diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index ed1fe063d0..d513bb919b 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -344,7 +344,7 @@ vec4 calculateGrayScaleOverlay( return color; } - +// Get the Reflectance from Here (JCC) vec4 calculateWater( const vec4 currentColor, const vec2 uv, diff --git a/modules/globebrowsing/shaders/tilefragcolor.hglsl b/modules/globebrowsing/shaders/tilefragcolor.hglsl index 2b3252becd..2324643096 100644 --- a/modules/globebrowsing/shaders/tilefragcolor.hglsl +++ b/modules/globebrowsing/shaders/tilefragcolor.hglsl @@ -146,6 +146,7 @@ vec4 getTileFragColor(){ #endif // USE_COLORTEXTURE #if USE_WATERMASK + // Change to get water reflectance (JCC) (alpha channel) color = calculateWater( color, fs_uv, diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl index 1d122a49b9..d0f5f3fca3 100644 --- a/shaders/fragment.glsl +++ b/shaders/fragment.glsl @@ -30,6 +30,9 @@ struct Fragment { vec4 color; + vec4 gColor; + vec4 gPosition; + vec4 gNormalReflectance; float depth; uint blend; bool forceFboRendering; diff --git a/shaders/framebuffer/renderframebuffer.frag b/shaders/framebuffer/renderframebuffer.frag index 0f671765ea..8e42ead1d6 100644 --- a/shaders/framebuffer/renderframebuffer.frag +++ b/shaders/framebuffer/renderframebuffer.frag @@ -25,10 +25,16 @@ #include "floatoperations.glsl" #include <#{fragmentPath}> -out vec4 _out_color_; +layout(location = 0) out vec4 _out_color_; +layout(location = 1) out vec4 gColor; +layout(location = 2) out vec4 gPosition; +layout(location = 3) out vec4 gNormalReflectance; void main() { Fragment f = getFragment(); _out_color_ = f.color; + gPosition = f.gPosition; + gNormalReflectance = f.gNormalReflectance; + gColor = f.gColor; gl_FragDepth = normalizeFloat(f.depth); } diff --git a/shaders/framebuffer/resolveframebuffer.frag b/shaders/framebuffer/resolveframebuffer.frag index 7f32534df1..94ee6ebaab 100644 --- a/shaders/framebuffer/resolveframebuffer.frag +++ b/shaders/framebuffer/resolveframebuffer.frag @@ -39,5 +39,5 @@ void main() { color /= nAaSamples; color.rgb *= blackoutFactor; - finalColor = vec4(color.rgb, 1.0); + finalColor = vec4(color.rgb, 1.0); } diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index b76afa324a..1b769b91f1 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -102,6 +102,9 @@ void FramebufferRenderer::initialize() { // Deferred framebuffer glGenTextures(1, &_deferredColorTexture); + glGenTextures(1, &_mainDColorTexture); + glGenTextures(1, &_mainPositionTexture); + glGenTextures(1, &_mainNormalReflectanceTexture); glGenFramebuffers(1, &_deferredFramebuffer); updateResolution(); @@ -111,6 +114,10 @@ void FramebufferRenderer::initialize() { glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0); + // DEBUG: deferred g-buffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, _mainDColorTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D_MULTISAMPLE, _mainNormalReflectanceTexture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -128,7 +135,7 @@ void FramebufferRenderer::initialize() { } glBindFramebuffer(GL_FRAMEBUFFER, _deferredFramebuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _deferredColorTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _deferredColorTexture, 0); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { @@ -158,9 +165,16 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_mainColorTexture); glDeleteTextures(1, &_mainDepthTexture); + + // DEBUG: deferred g-buffer + glDeleteTextures(1, &_deferredColorTexture); + glDeleteTextures(1, &_mainDColorTexture); + glDeleteTextures(1, &_mainPositionTexture); + glDeleteTextures(1, &_mainNormalReflectanceTexture); + glDeleteTextures(1, &_exitColorTexture); glDeleteTextures(1, &_exitDepthTexture); - glDeleteTextures(1, &_deferredColorTexture); + glDeleteBuffers(1, &_vertexPositionBuffer); glDeleteVertexArrays(1, &_screenQuad); @@ -258,6 +272,47 @@ void FramebufferRenderer::updateResolution() { GLsizei(_resolution.y), true); + // DEBUG: deferred g-buffer + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _deferredColorTexture); + + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + _nAaSamples, + GL_RGBA, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDColorTexture); + + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + _nAaSamples, + GL_RGBA, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture); + + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + _nAaSamples, + GL_RGB32F, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainNormalReflectanceTexture); + + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + _nAaSamples, + GL_RGBA32F, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, @@ -298,21 +353,6 @@ void FramebufferRenderer::updateResolution() { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, _deferredColorTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA32F, - GLsizei(_resolution.x), - GLsizei(_resolution.y), - 0, - GL_RGBA, - GL_UNSIGNED_SHORT, - nullptr); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - _dirtyResolution = false; } @@ -454,6 +494,9 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); + // DEBUG: deferred g-buffer + GLenum textureBuffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; + glDrawBuffers(4, textureBuffers); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); data.renderBinMask = static_cast(Renderable::RenderBin::Background); @@ -544,40 +587,72 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure } } - for (const DeferredcasterTask& deferredcasterTask : tasks.deferredcasterTasks) { - // TODO - Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster; - + // DEBUG: g-buffer + if (tasks.deferredcasterTasks.size()) { + glBindFramebuffer(GL_FRAMEBUFFER, _deferredFramebuffer); + GLenum dBuffer[1] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, dBuffer); + glClear(GL_COLOR_BUFFER_BIT); + } else { glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); - //glBindFramebuffer(GL_FRAMEBUFFER, _deferredFramebuffer); - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDrawBuffers(4, textureBuffers); + //GLenum dBuffer[1] = { GL_COLOR_ATTACHMENT0 }; + //glDrawBuffers(1, dBuffer); + } + + for (const DeferredcasterTask& deferredcasterTask : tasks.deferredcasterTasks) { + + Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster; ghoul::opengl::ProgramObject* deferredcastProgram = nullptr; - if (deferredcastProgram == _deferredcastPrograms[deferredcaster].get()) { - deferredcastProgram->activate(); - } else { + if (deferredcastProgram != _deferredcastPrograms[deferredcaster].get()) { deferredcastProgram = _deferredcastPrograms[deferredcaster].get(); - deferredcastProgram->activate(); } + deferredcastProgram->activate(); + if (deferredcastProgram) { + // DEBUG: adding G-Buffer + ghoul::opengl::TextureUnit mainDColorTextureUnit; + mainDColorTextureUnit.activate(); + //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDColorTexture); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + deferredcastProgram->setUniform("mainColorTexture", mainDColorTextureUnit); + + ghoul::opengl::TextureUnit mainPositionTextureUnit; + mainPositionTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainPositionTexture); + deferredcastProgram->setUniform("mainPositionTexture", mainPositionTextureUnit); + + ghoul::opengl::TextureUnit mainNormalReflectanceTextureUnit; + mainNormalReflectanceTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainNormalReflectanceTexture); + deferredcastProgram->setUniform("mainNormalReflectanceTexture", mainNormalReflectanceTextureUnit); + + // ghoul::opengl::TextureUnit mainDepthTextureUnit; + // mainDepthTextureUnit.activate(); + // glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + // deferredcastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); + + + deferredcastProgram->setUniform("nAaSamples", _nAaSamples); + +// deferredcastProgram->setUniform("windowSize", glm::vec2(_resolution)); + deferredcaster->preRaycast(deferredcasterTask.renderData, _deferredcastData[deferredcaster], *deferredcastProgram); -// ghoul::opengl::TextureUnit mainDepthTextureUnit; -// mainDepthTextureUnit.activate(); -// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); -// deferredcastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); - -// ghoul::opengl::TextureUnit mainColorTextureUnit; -// mainColorTextureUnit.activate(); -// glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); -// deferredcastProgram->setUniform("mainColorTexture", mainColorTextureUnit); - - deferredcastProgram->setUniform("nAaSamples", _nAaSamples); -// deferredcastProgram->setUniform("windowSize", glm::vec2(_resolution)); + // DEBUG: Temporary until fix problem in architecture. + ghoul::opengl::TextureUnit dummyTextureUnit; + dummyTextureUnit.activate(); + ghoul::opengl::TextureUnit dummyTextureUnit1; + dummyTextureUnit1.activate(); + ghoul::opengl::TextureUnit dummyTextureUnit2; + dummyTextureUnit2.activate(); + ghoul::opengl::TextureUnit dummyTextureUnit3; + dummyTextureUnit3.activate(); glDisable(GL_DEPTH_TEST); glDepthMask(false); @@ -604,8 +679,13 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure ghoul::opengl::TextureUnit mainColorTextureUnit; mainColorTextureUnit.activate(); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + // DEBUG: g-buffer + if (tasks.deferredcasterTasks.size()) { + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _deferredColorTexture); + } else { + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + } _resolveProgram->setUniform("mainColorTexture", mainColorTextureUnit); _resolveProgram->setUniform("blackoutFactor", blackoutFactor); _resolveProgram->setUniform("nAaSamples", _nAaSamples);