From 3fa5ed39d5efd681259cf12882a8227b05cb3827 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 16 May 2016 15:41:04 -0400 Subject: [PATCH 01/17] Planet Shadows --- data/scene/default-moon.scene | 80 +++++++ data/scene/earth/earth.mod | 50 +++-- data/scene/moon/moon.data | 5 + data/scene/moon/moon.mod | 63 ++++++ modules/base/rendering/renderableplanet.cpp | 204 +++++++++++++++++- modules/base/rendering/renderableplanet.h | 20 ++ .../base/shaders/shadow_nighttexture_fs.glsl | 131 +++++++++++ .../base/shaders/shadow_nighttexture_vs.glsl | 68 ++++++ openspace.cfg | 3 +- 9 files changed, 586 insertions(+), 38 deletions(-) create mode 100644 data/scene/default-moon.scene create mode 100644 data/scene/moon/moon.data create mode 100644 data/scene/moon/moon.mod create mode 100644 modules/base/shaders/shadow_nighttexture_fs.glsl create mode 100644 modules/base/shaders/shadow_nighttexture_vs.glsl diff --git a/data/scene/default-moon.scene b/data/scene/default-moon.scene new file mode 100644 index 0000000000..dd6926d533 --- /dev/null +++ b/data/scene/default-moon.scene @@ -0,0 +1,80 @@ +function preInitialization() + --[[ + The scripts in this function are executed after the scene is loaded but before the + scene elements have been initialized, thus they should be used to set the time at + which the scene should start and other settings that might determine initialization + critical objects. + ]]-- + + --YYYY-MM-DDTHH:MN:SS + --openspace.time.setTime(openspace.time.currentWallTime()) + --[[ + -- March 9, 2016 total eclipse times from land + -- Palembang, South Sumatra, Indonesia + -- Partial solar eclipse begins: 6:20 a.m. local Western Indonesian Time + -- Total solar eclipse begins: 7:20 a.m. local time + -- Maximum eclipse: 7:21 a.m. local time + -- Total solar eclipse ends: 7:22 a.m. local time + -- Partial solar eclipse ends: 8:31 a.m. local time + + -- 6:20 -> 23:20 day before in UTC + ]]-- + openspace.time.setTime("2016-03-08T23:00:00") + openspace.time.setDeltaTime(500.0) + dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) +end + +function postInitialization() + --[[ + The scripts in this function are executed after all objects in the scene have been + created and initialized, but before the first render call. This is the place to set + graphical settings for the renderables. + ]]-- + openspace.printInfo("Setting default values") + openspace.setPropertyValue("Sun.renderable.enabled", false) + openspace.setPropertyValue("SunMarker.renderable.enabled", false) + openspace.setPropertyValue("EarthMarker.renderable.enabled", false) + --openspace.setPropertyValue("Constellation Bounds.renderable.enabled", false) + openspace.setPropertyValue("PlutoTrail.renderable.enabled", false) + openspace.setPropertyValue("PlutoTexture.renderable.enabled", false) + + openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.55) + openspace.setPropertyValue("MilkyWay.renderable.segments", 50) + + openspace.printInfo("Done setting default values") +end + +return { + ScenePath = ".", + CommonFolder = "common", + Camera = { + Focus = "Earth", + Position = {1, 0, 0, 5}, + }, + Modules = { + "sun", + "mercury", + "venus", + "earth", + "moon", + "mars", + "jupiter", + "saturn", + "uranus", + "neptune", + "stars", + -- "stars-denver", + "milkyway", + -- "milkyway-eso", + --"constellationbounds", + -- "fieldlines", + --"io", + --"europa", + --"ganymede", + --"callisto", + --"gridGalactic", + --"gridEcliptic", + --"gridEquatorial", + } +} + diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index a853ebe9c9..6e14e9b9d2 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -4,21 +4,15 @@ return { Name = "EarthBarycenter", Parent = "SolarSystemBarycenter", Static = true, - --[[ Ephemeris = { - Type = "Kepler", - Inclination = 0.00041, - AscendingNode = 349.2, - Perihelion = 102.8517, - SemiMajorAxis = 1.00002, - DailyMotion = 0.9855796, - Eccentricity = 0.0166967, - MeanLongitude = 328.40353 - } - --]] - Ephemeris = { - Type = "Static" - } + Type = "Spice", + Body = "EARTH BARYCENTER", + Reference = "ECLIPJ2000", + Observer = "SUN", + Kernels = { + "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + } + }, }, -- Earth module { @@ -27,16 +21,28 @@ return { Renderable = { Type = "RenderablePlanet", Frame = "IAU_EARTH", - Body = "EARTH", + Body = "EARTH", Geometry = { Type = "SimpleSphere", Radius = { 6.371, 6 }, Segments = 100 }, + Shadow_Group = { + Source1 = { + Name = "Sun", + Radius = {696.3, 6} + }, + --Source2 = { Name = "Monolith", Radius = {0.01, 6} }, + Caster1 = { + Name = "Moon", + Radius = {1.737, 6} + }, + --Caster2 = { Name = "Independency Day Ship", Radius = {0.0, 0.0} } + }, Textures = { Type = "simple", Color = "textures/earth_bluemarble.jpg", - Night = "textures/earth_night.jpg", + Night = "textures/earth_night.jpg", -- Depth = "textures/earth_depth.png" }, Atmosphere = { @@ -45,15 +51,7 @@ return { MieColor = {1.0, 1.0, 1.0} } }, - Ephemeris = { - Type = "Spice", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, + GuiName = "/Solar/Planets/Earth" }, -- EarthTrail module @@ -82,7 +80,7 @@ return { Billboard = true, Texture = "textures/marker.png" }, - Ephemeris = { + Ephemeris = { Type = "Static", Position = {0, 0, 0, 5} } diff --git a/data/scene/moon/moon.data b/data/scene/moon/moon.data new file mode 100644 index 0000000000..f8c7094165 --- /dev/null +++ b/data/scene/moon/moon.data @@ -0,0 +1,5 @@ +return { + FileRequest = { + { Identifier = "moon_textures", Destination = "textures", Version = 1 } + }, +} \ No newline at end of file diff --git a/data/scene/moon/moon.mod b/data/scene/moon/moon.mod new file mode 100644 index 0000000000..aca8459945 --- /dev/null +++ b/data/scene/moon/moon.mod @@ -0,0 +1,63 @@ +return { + -- Moon module + { + Name = "Moon", + Parent = "EarthBarycenter", + Renderable = { + Type = "RenderablePlanet", + Frame = "IAU_MOON", + Body = "MOON", + Geometry = { + Type = "SimpleSphere", + Radius = { 1.737, 6}, + Segments = 100 + }, + Textures = { + Type = "simple", + Color = "textures/Moon16K.dds", + --Color = "textures/moonmap4k.jpg", + }, + Atmosphere = { + Type = "Nishita", -- for example, values missing etc etc + MieFactor = 1.0, + MieColor = {1.0, 1.0, 1.0} + } + }, + Ephemeris = { + Type = "Spice", + Body = "MOON", + Reference = "ECLIPJ2000", + Observer = "EARTH BARYCENTER", + Kernels = { + "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + } + }, + Rotation = { + Type = "Spice", + Frame = "IAU_MOON", + Reference = "ECLIPJ2000" + }, + GuiName = "/Solar/Planets/MOON" + }, + -- MoonTrail module + { + Name = "MoonTrail", + Parent = "EarthBarycenter", + Renderable = { + Type = "RenderableTrail", + Body = "MOON", + Frame = "GALACTIC", + Observer = "EARTH BARYCENTER", + RGB = { 0.5, 0.3, 0.3 }, + TropicalOrbitPeriod = 60, + EarthOrbitRatio = 0.01, + DayLength = 1.0, + Textures = { + Type = "simple", + Color = "${COMMON_MODULE}/textures/glare_blue.png", + -- need to add different texture + }, + }, + GuiName = "/Solar/MoonTrail" + } +} diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 95753a70d2..21d6622977 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -48,7 +48,11 @@ namespace { const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; + const std::string keyRadius = "Radius"; const std::string keyShading = "PerformShading"; + const std::string keyShadowGroup = "Shadow_Group"; + const std::string keyShadowSource = "Source"; + const std::string keyShadowCaster = "Caster"; const std::string keyBody = "Body"; } @@ -65,8 +69,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _performShading("performShading", "Perform Shading", true) , _rotation("rotation", "Rotation", 0, 0, 360) , _alpha(1.f) + , _planetRadius(0.f) , _nightTexturePath("") - , _hasNightTexture(false) + , _hasNightTexture(false) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -84,6 +89,13 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) geometryDictionary.setValue(SceneGraphNode::KeyName, name); //geometryDictionary.setValue(constants::scenegraph::keyPathModule, path); _geometry = planetgeometry::PlanetGeometry::createFromDictionary(geometryDictionary); + + glm::vec2 planetRadiusVec; + success = geometryDictionary.getValue(keyRadius, planetRadiusVec); + if (success) + _planetRadius = planetRadiusVec[0] * glm::pow(10, planetRadiusVec[1]); + else + LWARNING("No Radius value expecified for " << name << " planet."); } dictionary.getValue(keyFrame, _frame); @@ -120,6 +132,79 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) addProperty(_performShading); // Mainly for debugging purposes @AA addProperty(_rotation); + + + // Shadow data: + ghoul::Dictionary shadowDictionary; + success = dictionary.getValue(keyShadowGroup, shadowDictionary); + if (success) { + std::vector< std::pair > sourceArray; + unsigned int sourceCounter = 1; + while (success) { + std::string sourceName; + std::stringstream ss; + ss << keyShadowSource << sourceCounter << ".Name"; + success = shadowDictionary.getValue(ss.str(), sourceName); + if (success) { + glm::vec2 sourceRadius; + ss.str(std::string()); + ss << keyShadowSource << sourceCounter << ".Radius"; + success = shadowDictionary.getValue(ss.str(), sourceRadius); + if (success) { + sourceArray.push_back(std::pair< std::string, float>(sourceName, sourceRadius[0] * glm::pow(10, sourceRadius[1]))); + } + else { + // TODO: handle not success + ; + } + } + else { + // TODO: handle not success + ; + } + + sourceCounter++; + } + + success = true; + + std::vector< std::pair > casterArray; + unsigned int casterCounter = 1; + while (success) { + std::string casterName; + std::stringstream ss; + ss << keyShadowCaster << casterCounter << ".Name"; + success = shadowDictionary.getValue(ss.str(), casterName); + if (success) { + glm::vec2 casterRadius; + ss.str(std::string()); + ss << keyShadowCaster << casterCounter << ".Radius"; + success = shadowDictionary.getValue(ss.str(), casterRadius); + if (success) { + casterArray.push_back(std::pair< std::string, float>(casterName, casterRadius[0] * glm::pow(10, casterRadius[1]))); + } + else { + // TODO: handle not success + ; + } + } + else { + // TODO: handle not success + ; + } + + casterCounter++; + } + + for ( const auto & source : sourceArray ) + for (const auto & caster : casterArray) { + ShadowConf sc; + sc.source = source; + sc.caster = caster; + _shadowConfArray.push_back(sc); + } + } + } RenderablePlanet::~RenderablePlanet() { @@ -127,13 +212,32 @@ RenderablePlanet::~RenderablePlanet() { bool RenderablePlanet::initialize() { RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject == nullptr && _hasNightTexture) { + + if (_programObject == nullptr && !_shadowConfArray.empty() && _hasNightTexture) { + // shadow program + _programObject = renderEngine.buildRenderProgram( + "shadowNightProgram", + "${MODULE_BASE}/shaders/shadow_nighttexture_vs.glsl", + "${MODULE_BASE}/shaders/shadow_nighttexture_fs.glsl"); + if (!_programObject) + return false; + } + else if (_programObject == nullptr && !_shadowConfArray.empty()) { + // shadow program + _programObject = renderEngine.buildRenderProgram( + "shadowProgram", + "${MODULE_BASE}/shaders/shadow_vs.glsl", + "${MODULE_BASE}/shaders/shadow_fs.glsl"); + if (!_programObject) + return false; + } + else if (_programObject == nullptr && _hasNightTexture) { // Night texture program _programObject = renderEngine.buildRenderProgram( "nightTextureProgram", "${MODULE_BASE}/shaders/nighttexture_vs.glsl", "${MODULE_BASE}/shaders/nighttexture_fs.glsl"); - if (!_programObject) + if (!_programObject) return false; } else if (_programObject == nullptr) { @@ -142,8 +246,8 @@ bool RenderablePlanet::initialize() { "pscstandard", "${MODULE_BASE}/shaders/pscstandard_vs.glsl", "${MODULE_BASE}/shaders/pscstandard_fs.glsl"); - if (!_programObject) return false; - + if (!_programObject) + return false; } using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; _programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); @@ -199,18 +303,28 @@ void RenderablePlanet::render(const RenderData& data) } } transform = transform * rot * roty * rotProp; - - //glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix(); - //glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz; - + // setup the data to the shader double lt; glm::dvec3 p = SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); + p *= 1000.0; // from Km to m psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - // setup the data to the shader -// _programObject->setUniform("camdir", camSpaceEye); + //_programObject->setUniform("light_dir", sun_pos.vec4()); + + glm::dvec3 pt = + SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, _time, lt); + psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(pt.x, pt.y, pt.z); + glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); + + // This is camera position vector (camera direction) in world coordinates. + //_programObject->setUniform("cam_dir", cam_dir); + + //glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix(); + //glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz; + //_programObject->setUniform("camdir", camSpaceEye); + _programObject->setUniform("transparency", _alpha); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); @@ -235,6 +349,74 @@ void RenderablePlanet::render(const RenderData& data) glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + // Shadow calculations.. + if (!_shadowConfArray.empty()) { + std::vector shadowDataArray; + shadowDataArray.reserve(_shadowConfArray.size()); + + for (const auto & shadowConf : _shadowConfArray) { + // TO REMEMBER: all distances and lengths in world coordinates are in meters!!! We need to move this to view space... + // Getting source and caster: + glm::dvec3 sourcePos = SpiceManager::ref().targetPosition(shadowConf.source.first, "SUN", "GALACTIC", {}, _time, lt); + sourcePos *= 1000.0; // converting to meters + glm::dvec3 casterPos = SpiceManager::ref().targetPosition(shadowConf.caster.first, "SUN", "GALACTIC", {}, _time, lt); + casterPos *= 1000.0; // converting to meters + psc caster_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(casterPos.x, casterPos.y, casterPos.z); + + + // First we determine if the caster is shadowing the current planet (all calculations in World Coordinates): + glm::vec3 planetCasterVec = (caster_pos - data.position).vec3(); + glm::vec3 sourceCasterVec = glm::vec3(casterPos - sourcePos); + float sc_length = glm::length(sourceCasterVec); + glm::vec3 planetCaster_proj = (glm::dot(planetCasterVec, sourceCasterVec) / (sc_length*sc_length)) * sourceCasterVec; + float d_test = glm::length(planetCasterVec - planetCaster_proj); + float xp_test = shadowConf.caster.second * sc_length / (shadowConf.source.second + shadowConf.caster.second); + float rp_test = shadowConf.caster.second * (glm::length(planetCaster_proj) + xp_test) / xp_test; + + ShadowRenderingStruct shadowData; + shadowData.isShadowing = false; + if ((d_test - rp_test) < _planetRadius) { + // The current caster is shadowing the current planet + shadowData.isShadowing = true; + shadowData.rs = shadowConf.source.second; + shadowData.rc = shadowConf.caster.second; + shadowData.sourceCasterVec = sourceCasterVec; + shadowData.xp = xp_test; + shadowData.xu = shadowData.rc * sc_length / (shadowData.rs - shadowData.rc); + shadowData.casterPositionVec = glm::vec3(casterPos); + } + shadowDataArray.push_back(shadowData); + } + + const std::string uniformVarName("shadowDataArray["); + unsigned int counter = 0; + for (const auto & sd : shadowDataArray) { + std::stringstream ss; + ss << uniformVarName << counter << "].isShadowing"; + _programObject->setUniform(ss.str(), sd.isShadowing); + if (sd.isShadowing) { + ss.str(std::string()); + ss << uniformVarName << counter << "].xp"; + _programObject->setUniform(ss.str(), sd.xp); + ss.str(std::string()); + ss << uniformVarName << counter << "].xu"; + _programObject->setUniform(ss.str(), sd.xu); + /*ss.str(std::string()); + ss << uniformVarName << counter << "].rs"; + _programObject->setUniform(ss.str(), sd.rs);*/ + ss.str(std::string()); + ss << uniformVarName << counter << "].rc"; + _programObject->setUniform(ss.str(), sd.rc); + ss.str(std::string()); + ss << uniformVarName << counter << "].sourceCasterVec"; + _programObject->setUniform(ss.str(), sd.sourceCasterVec); + ss.str(std::string()); + ss << uniformVarName << counter << "].casterPositionVec"; + _programObject->setUniform(ss.str(), sd.casterPositionVec); + } + counter++; + } + } // render _geometry->render(); diff --git a/modules/base/rendering/renderableplanet.h b/modules/base/rendering/renderableplanet.h index 69447e1d3d..8154c168bf 100644 --- a/modules/base/rendering/renderableplanet.h +++ b/modules/base/rendering/renderableplanet.h @@ -31,6 +31,9 @@ #include #include +#include +#include + // ghoul includes namespace ghoul { namespace opengl { @@ -46,6 +49,21 @@ class PlanetGeometry; } class RenderablePlanet : public Renderable { +public: + // Shadow structure + typedef struct { + std::pair source; + std::pair caster; + } ShadowConf; + + struct ShadowRenderingStruct { + float xu, xp; + float rs, rc; + glm::vec3 sourceCasterVec; + glm::vec3 casterPositionVec; + bool isShadowing; + }; + public: RenderablePlanet(const ghoul::Dictionary& dictionary); ~RenderablePlanet(); @@ -69,6 +87,8 @@ private: properties::BoolProperty _performShading; properties::IntProperty _rotation; float _alpha; + std::vector< ShadowConf > _shadowConfArray; + float _planetRadius; glm::dmat3 _stateMatrix; std::string _nightTexturePath; diff --git a/modules/base/shaders/shadow_nighttexture_fs.glsl b/modules/base/shaders/shadow_nighttexture_fs.glsl new file mode 100644 index 0000000000..ed5a2d1389 --- /dev/null +++ b/modules/base/shaders/shadow_nighttexture_fs.glsl @@ -0,0 +1,131 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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. * + ****************************************************************************************/ + +const uint numberOfShadows = 1; + +struct ShadowRenderingStruct { + float xu, xp; + float rs, rc; + vec3 sourceCasterVec; + vec3 casterPositionVec; + bool isShadowing; +}; + +uniform ShadowRenderingStruct shadowDataArray[numberOfShadows]; + +uniform vec4 campos; +uniform vec4 objpos; + +uniform vec3 sun_pos; + +uniform bool _performShading = true; +uniform float transparency; +uniform int shadows; + +uniform float time; +uniform sampler2D texture1; +uniform sampler2D nightTex; + +in vec2 vs_st; +in vec2 vs_nightTex; +in vec4 vs_normal; +in vec4 vs_position; +in vec4 vs_posWorld; + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +vec4 butterworthFunc(const float d, const float r, const float n) { + return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); +} + +vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) { + if (shadowInfoArray[0].isShadowing) { + vec3 pc = shadowInfoArray[0].casterPositionVec - position; + vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader + vec3 pc_proj = dot(pc, sc_norm) * sc_norm; + vec3 d = pc - pc_proj; + + float length_d = length(d); + float length_pc_proj = length(pc_proj); + + float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp; + + //float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu; + float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; + + if ( length_d < r_u_pi ) { // umbra + return vec4(0.0, 0.0, 0.0, 1.0); + //return vec4(1.0, 0.0, 0.0, 1.0); + //return butterworthFunc(length_d, r_u_pi, 4.0); + } + else if ( length_d < r_p_pi ) {// penumbra + return vec4(0.5, 0.5, 0.5, 1.0); + //return vec4(0.0, 1.0, 0.0, 1.0); + //return vec4(vec3(length_d/r_p_pi), 1.0); + } + } + + return vec4(1.0); +} + +Fragment getFragment() { + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse = texture(texture1, vs_st); + vec4 diffuse2 = texture(nightTex, vs_st); + + Fragment frag; + if (_performShading) { + // directional lighting + vec3 origin = vec3(0.0); + vec4 spec = vec4(0.0); + + vec3 n = normalize(vs_normal.xyz); + //vec3 e = normalize(camdir); + vec3 l_pos = vec3(sun_pos); // sun. + vec3 l_dir = normalize(l_pos-objpos.xyz); + float intensity = min(max(5*dot(n,l_dir), 0.0), 1); + float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1); + + float shine = 0.0001; + + vec4 specular = vec4(0.5); + vec4 ambient = vec4(0.0,0.0,0.0,transparency); + + vec4 daytex = max(intensity * diffuse, ambient); + vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); + + diffuse = (daytex*2 + mixtex)/3; + + diffuse *= calcShadow(shadowDataArray, vs_posWorld.xyz); + } + + diffuse[3] = transparency; + frag.color = diffuse; + frag.depth = depth; + + return frag; +} + diff --git a/modules/base/shaders/shadow_nighttexture_vs.glsl b/modules/base/shaders/shadow_nighttexture_vs.glsl new file mode 100644 index 0000000000..82c8f5545c --- /dev/null +++ b/modules/base/shaders/shadow_nighttexture_vs.glsl @@ -0,0 +1,68 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; +//layout(location = 3) in vec2 in_nightTex; + + +out vec2 vs_st; +out vec4 vs_normal; +out vec4 vs_position; +out vec4 vs_posWorld; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + // set variables + vs_st = in_st; + vs_position = in_position; + vec4 tmp = in_position; + + // 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. + vec4 position = pscTransform(tmp, ModelTransform); + + 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; + + vs_position = tmp; + // Now is transforming from view position to SGCT projection + // coordinates. + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/openspace.cfg b/openspace.cfg index a2420ef11d..ad62fcae98 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -7,7 +7,8 @@ return { -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace - Scene = "${SCENE}/newhorizons.scene", + --Scene = "${SCENE}/newhorizons.scene", + Scene = "${SCENE}/default-moon.scene", Paths = { SGCT = "${BASE_PATH}/config/sgct", From 36ebe69f60d7b4b25aa2656b94c9b8657737cea3 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 16 May 2016 16:41:09 -0400 Subject: [PATCH 02/17] Changed default moon scene for a total lunar eclipse. --- data/scene/default-moon.scene | 15 ++- data/scene/moon/moon.mod | 10 ++ modules/base/rendering/renderableplanet.cpp | 83 +++++++------ modules/base/shaders/shadow_fs.glsl | 129 ++++++++++++++++++++ modules/base/shaders/shadow_vs.glsl | 68 +++++++++++ 5 files changed, 262 insertions(+), 43 deletions(-) create mode 100644 modules/base/shaders/shadow_fs.glsl create mode 100644 modules/base/shaders/shadow_vs.glsl diff --git a/data/scene/default-moon.scene b/data/scene/default-moon.scene index dd6926d533..4cc8a52f47 100644 --- a/data/scene/default-moon.scene +++ b/data/scene/default-moon.scene @@ -19,8 +19,16 @@ function preInitialization() -- 6:20 -> 23:20 day before in UTC ]]-- - openspace.time.setTime("2016-03-08T23:00:00") - openspace.time.setDeltaTime(500.0) + --openspace.time.setTime("2016-03-08T22:45:00") + + + -- Total Lunar Eclipse Jan 31, 2018 at 10:51:13 UTC + -- Regions seeing, at least, some parts of the eclipse: North/East Europe, + -- Asia, Australia, North/East Africa, North America, North/East South America, + -- Pacific, Atlantic, Indian Ocean, Arctic, Antarctica. + openspace.time.setTime("2018-01-31T10:30:00") + + openspace.time.setDeltaTime(200.0) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end @@ -48,7 +56,8 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - Focus = "Earth", + --Focus = "Earth", + Focus = "Moon", Position = {1, 0, 0, 5}, }, Modules = { diff --git a/data/scene/moon/moon.mod b/data/scene/moon/moon.mod index aca8459945..84d994736c 100644 --- a/data/scene/moon/moon.mod +++ b/data/scene/moon/moon.mod @@ -12,6 +12,16 @@ return { Radius = { 1.737, 6}, Segments = 100 }, + Shadow_Group = { + Source1 = { + Name = "Sun", + Radius = {696.3, 6} + }, + Caster1 = { + Name = "Earth", + Radius = {6.371, 6} + }, + }, Textures = { Type = "simple", Color = "textures/Moon16K.dds", diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 21d6622977..63210aedb0 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -137,6 +137,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) // Shadow data: ghoul::Dictionary shadowDictionary; success = dictionary.getValue(keyShadowGroup, shadowDictionary); + bool disableShadows = false; if (success) { std::vector< std::pair > sourceArray; unsigned int sourceCounter = 1; @@ -151,58 +152,60 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) ss << keyShadowSource << sourceCounter << ".Radius"; success = shadowDictionary.getValue(ss.str(), sourceRadius); if (success) { - sourceArray.push_back(std::pair< std::string, float>(sourceName, sourceRadius[0] * glm::pow(10, sourceRadius[1]))); + sourceArray.push_back(std::pair< std::string, float>( + sourceName, sourceRadius[0] * glm::pow(10, sourceRadius[1]))); } else { - // TODO: handle not success - ; + LWARNING("No Radius value expecified for Shadow Source Name " + << sourceName << " from " << name + << " planet.\nDisabling shadows for this planet."); + disableShadows = true; + break; } } - else { - // TODO: handle not success - ; - } - sourceCounter++; } - success = true; - - std::vector< std::pair > casterArray; - unsigned int casterCounter = 1; - while (success) { - std::string casterName; - std::stringstream ss; - ss << keyShadowCaster << casterCounter << ".Name"; - success = shadowDictionary.getValue(ss.str(), casterName); - if (success) { - glm::vec2 casterRadius; - ss.str(std::string()); - ss << keyShadowCaster << casterCounter << ".Radius"; - success = shadowDictionary.getValue(ss.str(), casterRadius); + if (!disableShadows && !sourceArray.empty()) { + success = true; + std::vector< std::pair > casterArray; + unsigned int casterCounter = 1; + while (success) { + std::string casterName; + std::stringstream ss; + ss << keyShadowCaster << casterCounter << ".Name"; + success = shadowDictionary.getValue(ss.str(), casterName); if (success) { - casterArray.push_back(std::pair< std::string, float>(casterName, casterRadius[0] * glm::pow(10, casterRadius[1]))); + glm::vec2 casterRadius; + ss.str(std::string()); + ss << keyShadowCaster << casterCounter << ".Radius"; + success = shadowDictionary.getValue(ss.str(), casterRadius); + if (success) { + casterArray.push_back(std::pair< std::string, float>( + casterName, casterRadius[0] * glm::pow(10, casterRadius[1]))); + } + else { + LWARNING("No Radius value expecified for Shadow Caster Name " + << casterName << " from " << name + << " planet.\nDisabling shadows for this planet."); + disableShadows = true; + break; + } } - else { - // TODO: handle not success - ; - } - } - else { - // TODO: handle not success - ; + + casterCounter++; } - casterCounter++; + if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) { + for (const auto & source : sourceArray) + for (const auto & caster : casterArray) { + ShadowConf sc; + sc.source = source; + sc.caster = caster; + _shadowConfArray.push_back(sc); + } + } } - - for ( const auto & source : sourceArray ) - for (const auto & caster : casterArray) { - ShadowConf sc; - sc.source = source; - sc.caster = caster; - _shadowConfArray.push_back(sc); - } } } diff --git a/modules/base/shaders/shadow_fs.glsl b/modules/base/shaders/shadow_fs.glsl new file mode 100644 index 0000000000..58c76ca1a9 --- /dev/null +++ b/modules/base/shaders/shadow_fs.glsl @@ -0,0 +1,129 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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. * + ****************************************************************************************/ + +const uint numberOfShadows = 1; + +struct ShadowRenderingStruct { + float xu, xp; + float rs, rc; + vec3 sourceCasterVec; + vec3 casterPositionVec; + bool isShadowing; +}; + +uniform ShadowRenderingStruct shadowDataArray[numberOfShadows]; + +uniform vec4 campos; +uniform vec4 objpos; + +uniform vec3 sun_pos; + +uniform bool _performShading = true; +uniform float transparency; +uniform int shadows; + +uniform float time; +uniform sampler2D texture1; + +in vec2 vs_st; +in vec4 vs_normal; +in vec4 vs_position; +in vec4 vs_posWorld; + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +vec4 butterworthFunc(const float d, const float r, const float n) { + return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); +} + +vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) { + if (shadowInfoArray[0].isShadowing) { + vec3 pc = shadowInfoArray[0].casterPositionVec - position; + vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader + vec3 pc_proj = dot(pc, sc_norm) * sc_norm; + vec3 d = pc - pc_proj; + + float length_d = length(d); + float length_pc_proj = length(pc_proj); + + float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp; + + //float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu; + float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; + + if ( length_d < r_u_pi ) { // umbra + return vec4(0.0, 0.0, 0.0, 1.0); + //return vec4(1.0, 0.0, 0.0, 1.0); + //return butterworthFunc(length_d, r_u_pi, 4.0); + } + else if ( length_d < r_p_pi ) {// penumbra + return vec4(0.5, 0.5, 0.5, 1.0); + //return vec4(0.0, 1.0, 0.0, 1.0); + //return vec4(vec3(length_d/r_p_pi), 1.0); + } + } + + return vec4(1.0); +} + +Fragment getFragment() { + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse = texture(texture1, vs_st); + + Fragment frag; + if (_performShading) { + // directional lighting + vec3 origin = vec3(0.0); + vec4 spec = vec4(0.0); + + vec3 n = normalize(vs_normal.xyz); + //vec3 e = normalize(camdir); + vec3 l_pos = vec3(sun_pos); // sun. + vec3 l_dir = normalize(l_pos-objpos.xyz); + float intensity = min(max(5*dot(n,l_dir), 0.0), 1); + float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1); + + float shine = 0.0001; + + vec4 specular = vec4(0.5); + vec4 ambient = vec4(0.0,0.0,0.0,transparency); + + vec4 daytex = max(intensity * diffuse, ambient); + //vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); + + //diffuse = (daytex*2 + mixtex)/3; + diffuse = daytex; + + diffuse *= calcShadow(shadowDataArray, vs_posWorld.xyz); + } + + diffuse[3] = transparency; + frag.color = diffuse; + frag.depth = depth; + + return frag; +} + diff --git a/modules/base/shaders/shadow_vs.glsl b/modules/base/shaders/shadow_vs.glsl new file mode 100644 index 0000000000..82c8f5545c --- /dev/null +++ b/modules/base/shaders/shadow_vs.glsl @@ -0,0 +1,68 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; +//layout(location = 3) in vec2 in_nightTex; + + +out vec2 vs_st; +out vec4 vs_normal; +out vec4 vs_position; +out vec4 vs_posWorld; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + // set variables + vs_st = in_st; + vs_position = in_position; + vec4 tmp = in_position; + + // 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. + vec4 position = pscTransform(tmp, ModelTransform); + + 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; + + vs_position = tmp; + // Now is transforming from view position to SGCT projection + // coordinates. + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file From 2f4f50b7966de996ad437dd4ebb6c216fd4f61c2 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 6 Jun 2016 17:30:57 -0400 Subject: [PATCH 03/17] Using the correct boolean test for shadows. --- modules/base/rendering/renderableplanet.cpp | 6 ++++-- modules/base/rendering/renderableplanet.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index c2e36dcf51..0d41611585 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -76,6 +76,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _planetRadius(0.f) , _hasNightTexture(false) , _hasHeightTexture(false) + , _shadowEnabled(false) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -222,6 +223,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) sc.caster = caster; _shadowConfArray.push_back(sc); } + _shadowEnabled = true; } } } @@ -234,7 +236,7 @@ RenderablePlanet::~RenderablePlanet() { bool RenderablePlanet::initialize() { RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject == nullptr && !_shadowConfArray.empty() && _hasNightTexture) { + if (_programObject == nullptr && _shadowEnabled && _hasNightTexture) { // shadow program _programObject = renderEngine.buildRenderProgram( "shadowNightProgram", @@ -243,7 +245,7 @@ bool RenderablePlanet::initialize() { if (!_programObject) return false; } - else if (_programObject == nullptr && !_shadowConfArray.empty()) { + else if (_programObject == nullptr && _shadowEnabled) { // shadow program _programObject = renderEngine.buildRenderProgram( "shadowProgram", diff --git a/modules/base/rendering/renderableplanet.h b/modules/base/rendering/renderableplanet.h index 2743fc423b..c93094fee1 100644 --- a/modules/base/rendering/renderableplanet.h +++ b/modules/base/rendering/renderableplanet.h @@ -102,6 +102,7 @@ private: std::string _target; bool _hasNightTexture; bool _hasHeightTexture; + bool _shadowEnabled; double _time; }; From de6446282f9619d9ae3aa93dfe83e1fda1ae0da7 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 6 Jun 2016 18:23:06 -0400 Subject: [PATCH 04/17] Fixed small bug in shadows. --- data/scene/default-moon.scene | 10 +++++----- data/scene/earth/earth.mod | 2 ++ modules/base/rendering/renderableplanet.cpp | 13 +++++-------- modules/base/shaders/shadow_fs.glsl | 8 ++++---- modules/base/shaders/shadow_nighttexture_fs.glsl | 8 ++++---- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/data/scene/default-moon.scene b/data/scene/default-moon.scene index 4cc8a52f47..28aedfbbe9 100644 --- a/data/scene/default-moon.scene +++ b/data/scene/default-moon.scene @@ -19,16 +19,16 @@ function preInitialization() -- 6:20 -> 23:20 day before in UTC ]]-- - --openspace.time.setTime("2016-03-08T22:45:00") + openspace.time.setTime("2016-03-08T22:45:00") -- Total Lunar Eclipse Jan 31, 2018 at 10:51:13 UTC -- Regions seeing, at least, some parts of the eclipse: North/East Europe, -- Asia, Australia, North/East Africa, North America, North/East South America, -- Pacific, Atlantic, Indian Ocean, Arctic, Antarctica. - openspace.time.setTime("2018-01-31T10:30:00") + --openspace.time.setTime("2018-01-31T10:30:00") - openspace.time.setDeltaTime(200.0) + --openspace.time.setDeltaTime(200.0) dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) end @@ -56,8 +56,8 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - --Focus = "Earth", - Focus = "Moon", + Focus = "Earth", + --Focus = "Moon", Position = {1, 0, 0, 5}, }, Modules = { diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index e6cf169af9..725f9bd516 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -30,11 +30,13 @@ return { Shadow_Group = { Source1 = { Name = "Sun", + -- All radius in meters Radius = {696.3, 6} }, --Source2 = { Name = "Monolith", Radius = {0.01, 6} }, Caster1 = { Name = "Moon", + -- All radius in meters Radius = {1.737, 6} }, --Caster2 = { Name = "Independency Day Ship", Radius = {0.0, 0.0} } diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 0d41611585..2246a7f38c 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -330,13 +330,6 @@ void RenderablePlanet::render(const RenderData& data) // setup the data to the shader double lt; - glm::dvec3 p = - SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); - p *= 1000.0; // from Km to m - psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - - //_programObject->setUniform("light_dir", sun_pos.vec4()); - glm::dvec3 pt = SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, _time, lt); psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(pt.x, pt.y, pt.z); @@ -409,9 +402,13 @@ void RenderablePlanet::render(const RenderData& data) float xp_test = shadowConf.caster.second * sc_length / (shadowConf.source.second + shadowConf.caster.second); float rp_test = shadowConf.caster.second * (glm::length(planetCaster_proj) + xp_test) / xp_test; + float casterDistSun = glm::length(casterPos); + float planetDistSun = glm::length(data.position.vec3()); + ShadowRenderingStruct shadowData; shadowData.isShadowing = false; - if ((d_test - rp_test) < _planetRadius) { + if (((d_test - rp_test) < _planetRadius) && + (casterDistSun < planetDistSun) ) { // The current caster is shadowing the current planet shadowData.isShadowing = true; shadowData.rs = shadowConf.source.second; diff --git a/modules/base/shaders/shadow_fs.glsl b/modules/base/shaders/shadow_fs.glsl index 58c76ca1a9..056d8c6c00 100644 --- a/modules/base/shaders/shadow_fs.glsl +++ b/modules/base/shaders/shadow_fs.glsl @@ -74,14 +74,14 @@ vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], co float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; if ( length_d < r_u_pi ) { // umbra - return vec4(0.0, 0.0, 0.0, 1.0); + //return vec4(0.0, 0.0, 0.0, 1.0); //return vec4(1.0, 0.0, 0.0, 1.0); - //return butterworthFunc(length_d, r_u_pi, 4.0); + return butterworthFunc(length_d, r_u_pi, 4.0); } else if ( length_d < r_p_pi ) {// penumbra - return vec4(0.5, 0.5, 0.5, 1.0); + //return vec4(0.5, 0.5, 0.5, 1.0); //return vec4(0.0, 1.0, 0.0, 1.0); - //return vec4(vec3(length_d/r_p_pi), 1.0); + return vec4(vec3(length_d/r_p_pi), 1.0); } } diff --git a/modules/base/shaders/shadow_nighttexture_fs.glsl b/modules/base/shaders/shadow_nighttexture_fs.glsl index ed5a2d1389..2400d5a4be 100644 --- a/modules/base/shaders/shadow_nighttexture_fs.glsl +++ b/modules/base/shaders/shadow_nighttexture_fs.glsl @@ -76,14 +76,14 @@ vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], co float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; if ( length_d < r_u_pi ) { // umbra - return vec4(0.0, 0.0, 0.0, 1.0); + //return vec4(0.0, 0.0, 0.0, 1.0); //return vec4(1.0, 0.0, 0.0, 1.0); - //return butterworthFunc(length_d, r_u_pi, 4.0); + return butterworthFunc(length_d, r_u_pi, 4.0); } else if ( length_d < r_p_pi ) {// penumbra - return vec4(0.5, 0.5, 0.5, 1.0); + //return vec4(0.5, 0.5, 0.5, 1.0); //return vec4(0.0, 1.0, 0.0, 1.0); - //return vec4(vec3(length_d/r_p_pi), 1.0); + return vec4(vec3(length_d/r_p_pi), 1.0); } } From 388bb154615cb7a885b0b8afa9a90b09aa2d8828 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 7 Jun 2016 10:35:18 -0400 Subject: [PATCH 05/17] Initial implementation of Atmosphere Effects. Use framebuffer to render it. --- .gitignore | 3 + data/scene/default-moon.scene | 2 +- data/scene/earth/earth.mod | 59 +- data/scene/mars/mars.mod | 5 - data/scene/mercury/mercury.mod | 5 - data/scene/moon/moon.mod | 5 - data/scene/neptune/neptune.mod | 5 - data/scene/saturn/saturn.mod | 5 - data/scene/uranus/uranus.mod | 5 - data/scene/venus/venus.mod | 5 - modules/base/rendering/renderableplanet.cpp | 1808 ++++++++++++++++- modules/base/rendering/renderableplanet.h | 108 + modules/base/shaders/atmosphere_common.glsl | 85 + modules/base/shaders/atmosphere_fs.glsl | 437 ++++ modules/base/shaders/atmosphere_vs.glsl | 76 + modules/base/shaders/deltaE_calc_fs.glsl | 48 + modules/base/shaders/deltaE_calc_vs.glsl | 31 + modules/base/shaders/deltaJ_calc_fs.glsl | 192 ++ modules/base/shaders/deltaJ_calc_gs.glsl | 41 + modules/base/shaders/deltaJ_calc_vs.glsl | 31 + modules/base/shaders/deltaS_calc_fs.glsl | 51 + modules/base/shaders/deltaS_calc_gs.glsl | 41 + modules/base/shaders/deltaS_calc_vs.glsl | 31 + modules/base/shaders/deltaS_sup_calc_fs.glsl | 54 + modules/base/shaders/deltaS_sup_calc_gs.glsl | 41 + modules/base/shaders/deltaS_sup_calc_vs.glsl | 31 + modules/base/shaders/hdr.glsl | 35 + .../base/shaders/inScattering_calc_fs.glsl | 154 ++ .../base/shaders/inScattering_calc_gs.glsl | 41 + .../base/shaders/inScattering_calc_vs.glsl | 31 + .../shaders/inScattering_sup_calc_fs.glsl | 155 ++ .../shaders/inScattering_sup_calc_gs.glsl | 41 + .../shaders/inScattering_sup_calc_vs.glsl | 31 + modules/base/shaders/irradiance_calc_fs.glsl | 57 + modules/base/shaders/irradiance_calc_vs.glsl | 31 + .../base/shaders/irradiance_sup_calc_fs.glsl | 101 + .../base/shaders/irradiance_sup_calc_vs.glsl | 31 + .../base/shaders/transmittance_calc_fs.glsl | 109 + .../base/shaders/transmittance_calc_vs.glsl | 31 + openspace.cfg | 2 +- 40 files changed, 3993 insertions(+), 62 deletions(-) create mode 100644 modules/base/shaders/atmosphere_common.glsl create mode 100644 modules/base/shaders/atmosphere_fs.glsl create mode 100644 modules/base/shaders/atmosphere_vs.glsl create mode 100644 modules/base/shaders/deltaE_calc_fs.glsl create mode 100644 modules/base/shaders/deltaE_calc_vs.glsl create mode 100644 modules/base/shaders/deltaJ_calc_fs.glsl create mode 100644 modules/base/shaders/deltaJ_calc_gs.glsl create mode 100644 modules/base/shaders/deltaJ_calc_vs.glsl create mode 100644 modules/base/shaders/deltaS_calc_fs.glsl create mode 100644 modules/base/shaders/deltaS_calc_gs.glsl create mode 100644 modules/base/shaders/deltaS_calc_vs.glsl create mode 100644 modules/base/shaders/deltaS_sup_calc_fs.glsl create mode 100644 modules/base/shaders/deltaS_sup_calc_gs.glsl create mode 100644 modules/base/shaders/deltaS_sup_calc_vs.glsl create mode 100644 modules/base/shaders/hdr.glsl create mode 100644 modules/base/shaders/inScattering_calc_fs.glsl create mode 100644 modules/base/shaders/inScattering_calc_gs.glsl create mode 100644 modules/base/shaders/inScattering_calc_vs.glsl create mode 100644 modules/base/shaders/inScattering_sup_calc_fs.glsl create mode 100644 modules/base/shaders/inScattering_sup_calc_gs.glsl create mode 100644 modules/base/shaders/inScattering_sup_calc_vs.glsl create mode 100644 modules/base/shaders/irradiance_calc_fs.glsl create mode 100644 modules/base/shaders/irradiance_calc_vs.glsl create mode 100644 modules/base/shaders/irradiance_sup_calc_fs.glsl create mode 100644 modules/base/shaders/irradiance_sup_calc_vs.glsl create mode 100644 modules/base/shaders/transmittance_calc_fs.glsl create mode 100644 modules/base/shaders/transmittance_calc_vs.glsl diff --git a/.gitignore b/.gitignore index 5ce4c00222..de6e60dba5 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,9 @@ data/scene/earth/textures/earth_bluemarble.jpg data/scene/earth/textures/earth_bluemarble_height.jpg data/scene/earth/textures/earth_night.jpg data/scene/earth/textures/marker.png +data/scene/earth/textures/earth_clouds.jpg +data/scene/earth/textures/earth_reflectance.png +data/scene/moon/textures/Moon16k.dds data/scene/newhorizons/jupiter/europa/textures/europa.jpg data/scene/newhorizons/jupiter/ganymede/textures/ganymede.jpg data/scene/newhorizons/jupiter/io/textures/io.jpg diff --git a/data/scene/default-moon.scene b/data/scene/default-moon.scene index 28aedfbbe9..009490a770 100644 --- a/data/scene/default-moon.scene +++ b/data/scene/default-moon.scene @@ -67,7 +67,7 @@ return { "earth", "moon", "mars", - "jupiter", + --"jupiter", "saturn", "uranus", "neptune", diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index 725f9bd516..0ccb3af464 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -44,13 +44,62 @@ return { Textures = { Type = "simple", Color = "textures/earth_bluemarble.jpg", - Night = "textures/earth_night.jpg", - Height = "textures/earth_bluemarble_height.jpg" + Night = "textures/earth_night.jpg", + --Height = "textures/earth_bluemarble_height.jpg", + -- Depth = "textures/earth_depth.png", + Reflectance = "textures/earth_reflectance.png", + Clouds = "textures/earth_clouds.jpg" }, Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} + -- Atmosphere radius in Km + AtmoshereRadius = 6420, + --AtmoshereRadius = 6390, + --PlanetRadius = 6371, + PlanetRadius = 6360, + 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 = {4e-3, 4e-3, 4e-3}, + --Scattering = {2e-5, 2e-5, 2e-5}, + -- Extinction coefficients are a fraction of the Scattering coefficients + Extinction = {4e-3/0.9, 4e-3/0.9, 4e-3/0.9} + -- 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 = 1.0, + }, + -- Clear Sky + -- Mie = { + -- Coefficients = { + -- Scattering = {20e-3, 20e-3, 20e-3}, + -- Extinction = 1.0/0.9, + -- } + -- H_M = 1.2, + -- G = 0.76, + -- }, + -- Cloudy + -- Mie = { + -- Coefficients = { + -- Scattering = {3e-3, 3e-3, 3e-3}, + -- Extinction = 1.0/0.9, + -- } + -- H_M = 3.0, + -- G = 0.65, + -- }, } }, diff --git a/data/scene/mars/mars.mod b/data/scene/mars/mars.mod index 003c604e57..aa3cf872ca 100644 --- a/data/scene/mars/mars.mod +++ b/data/scene/mars/mars.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/mars.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/mercury/mercury.mod b/data/scene/mercury/mercury.mod index 5f2ec68a6c..13125f34d4 100644 --- a/data/scene/mercury/mercury.mod +++ b/data/scene/mercury/mercury.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/mercury.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/moon/moon.mod b/data/scene/moon/moon.mod index 84d994736c..bd941e815a 100644 --- a/data/scene/moon/moon.mod +++ b/data/scene/moon/moon.mod @@ -27,11 +27,6 @@ return { Color = "textures/Moon16K.dds", --Color = "textures/moonmap4k.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/neptune/neptune.mod b/data/scene/neptune/neptune.mod index a0a55c47f3..23e0e41dbf 100644 --- a/data/scene/neptune/neptune.mod +++ b/data/scene/neptune/neptune.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/neptune.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/saturn/saturn.mod b/data/scene/saturn/saturn.mod index be6e518e22..2629741b5b 100644 --- a/data/scene/saturn/saturn.mod +++ b/data/scene/saturn/saturn.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/saturn.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/uranus/uranus.mod b/data/scene/uranus/uranus.mod index 473fe725b7..a76326349e 100644 --- a/data/scene/uranus/uranus.mod +++ b/data/scene/uranus/uranus.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/uranus.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/data/scene/venus/venus.mod b/data/scene/venus/venus.mod index 753e164b55..c1d809cf83 100644 --- a/data/scene/venus/venus.mod +++ b/data/scene/venus/venus.mod @@ -25,11 +25,6 @@ return { Type = "simple", Color = "textures/venus.jpg", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - } }, Ephemeris = { Type = "Spice", diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 2246a7f38c..c7f0cecbb1 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -40,21 +40,33 @@ #include #include +#include +#include + #define _USE_MATH_DEFINES #include + namespace { const std::string _loggerCat = "RenderablePlanet"; - const std::string keyFrame = "Frame"; - const std::string keyGeometry = "Geometry"; - const std::string keyRadius = "Radius"; - const std::string keyShading = "PerformShading"; - const std::string keyShadowGroup = "Shadow_Group"; - const std::string keyShadowSource = "Source"; - const std::string keyShadowCaster = "Caster"; - -const std::string keyBody = "Body"; + const std::string keyFrame = "Frame"; + const std::string keyGeometry = "Geometry"; + const std::string keyRadius = "Radius"; + const std::string keyShading = "PerformShading"; + const std::string keyShadowGroup = "Shadow_Group"; + const std::string keyShadowSource = "Source"; + const std::string keyShadowCaster = "Caster"; + 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"; + const std::string keyBody = "Body"; } namespace openspace { @@ -64,18 +76,58 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _colorTexturePath("colorTexture", "Color Texture") , _nightTexturePath("nightTexture", "Night Texture") , _heightMapTexturePath("heightMap", "Heightmap Texture") + , _cloudsTexturePath("clouds", "Clouds Texture") + , _reflectanceTexturePath("reflectance", "Reflectance Texture") , _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 10.f) , _programObject(nullptr) + , _transmittanceProgramObject(nullptr) + , _irradianceProgramObject(nullptr) + , _irradianceSupTermsProgramObject(nullptr) + , _inScatteringProgramObject(nullptr) + , _inScatteringSupTermsProgramObject(nullptr) + , _deltaEProgramObject(nullptr) + , _deltaSProgramObject(nullptr) + , _deltaSSupTermsProgramObject(nullptr) + , _deltaJProgramObject(nullptr) + , _atmosphereProgramObject(nullptr) , _texture(nullptr) , _nightTexture(nullptr) + , _reflectanceTexture(nullptr) , _heightMapTexture(nullptr) + , _cloudsTexture(nullptr) , _geometry(nullptr) , _performShading("performShading", "Perform Shading", true) , _rotation("rotation", "Rotation", 0, 0, 360) , _alpha(1.f) , _planetRadius(0.f) + , _transmittanceTableTexture(0) + , _irradianceTableTexture(0) + , _inScatteringTableTexture(0) + , _deltaETableTexture(0) + , _deltaSRayleighTableTexture(0) + , _deltaSMieTableTexture(0) + , _deltaJTableTexture(0) + , _dummyTexture(0) + , _dummy3DTexture(0) + , _atmosphereTexture(0) + , _atmosphereFBO(0) + , _atmosphereRenderVAO(0) + , _atmosphereRenderVBO(0) + , _atmosphereCalculated(false) + , _atmosphereEnabled(false) + , _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)) , _hasNightTexture(false) , _hasHeightTexture(false) + , _hasReflectanceTexture(false) + , _hasCloudsTexture(false) , _shadowEnabled(false) { std::string name; @@ -122,6 +174,14 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) _nightTexturePath = absPath(nightTexturePath); } + std::string reflectanceTexturePath = ""; + dictionary.getValue("Textures.Reflectance", reflectanceTexturePath); + + if (reflectanceTexturePath != "") { + _hasReflectanceTexture = true; + _reflectanceTexturePath = absPath(reflectanceTexturePath); + } + std::string heightMapTexturePath = ""; dictionary.getValue("Textures.Height", heightMapTexturePath); if (heightMapTexturePath != "") { @@ -129,6 +189,13 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) _heightMapTexturePath = absPath(heightMapTexturePath); } + std::string cloudsTexturePath = ""; + dictionary.getValue("Textures.Clouds", cloudsTexturePath); + if (cloudsTexturePath != "") { + _hasCloudsTexture = true; + _cloudsTexturePath = absPath(cloudsTexturePath); + } + addPropertySubOwner(_geometry); addProperty(_colorTexturePath); @@ -140,6 +207,12 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) addProperty(_heightMapTexturePath); _heightMapTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this)); + addProperty(_reflectanceTexturePath); + _reflectanceTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this)); + + addProperty(_cloudsTexturePath); + _cloudsTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this)); + addProperty(_heightExaggeration); if (dictionary.hasKeyAndValue(keyShading)) { @@ -172,7 +245,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) success = shadowDictionary.getValue(ss.str(), sourceRadius); if (success) { sourceArray.push_back(std::pair< std::string, float>( - sourceName, sourceRadius[0] * glm::pow(10, sourceRadius[1]))); + sourceName, sourceRadius[0] * pow(10.f, sourceRadius[1]))); } else { LWARNING("No Radius value expecified for Shadow Source Name " @@ -201,7 +274,7 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) success = shadowDictionary.getValue(ss.str(), casterRadius); if (success) { casterArray.push_back(std::pair< std::string, float>( - casterName, casterRadius[0] * glm::pow(10, casterRadius[1]))); + casterName, casterRadius[0] * pow(10.f, casterRadius[1]))); } else { LWARNING("No Radius value expecified for Shadow Caster Name " @@ -228,6 +301,106 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) } } + // Atmosphere data: + bool errorReadingAtmosphereData = false; + ghoul::Dictionary atmosphereDictionary; + 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; + + //// DEBUG: + //std::stringstream ss; + //ss << "\n\nAtmosphere Values:\n" + // << "Radius: " << _atmosphereRadius << std::endl + // << "Planet Radius: " << _atmospherePlanetRadius << std::endl + // << "Average Reflection: " << _planetAverageGroundReflectance << std::endl + // << "Rayleigh HR: " << _rayleighHeightScale << std::endl + // << "Mie HR: " << _mieHeightScale << std::endl + // << "Mie G phase constant: " << _miePhaseConstant << std::endl + // << "Mie Extinction coeff: " << _mieExtinctionCoeff << std::endl + // << "Rayleigh Scattering coeff: " << _rayleighScatteringCoeff << std::endl + // << "Mie Scattering coeff: " << _mieScatteringCoeff << std::endl; + //std::cout << ss.str() << std::endl; + } + } } RenderablePlanet::~RenderablePlanet() { @@ -236,7 +409,23 @@ RenderablePlanet::~RenderablePlanet() { bool RenderablePlanet::initialize() { RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject == nullptr && _shadowEnabled && _hasNightTexture) { + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Checking System State. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + if (_programObject == nullptr && _atmosphereEnabled && _shadowEnabled && _hasNightTexture) { + // shadow program + _programObject = renderEngine.buildRenderProgram( + "atmosphereAndShadowProgram", + "${MODULE_BASE}/shaders/atmosphere_vs.glsl", + "${MODULE_BASE}/shaders/atmosphere_fs.glsl"); + if (!_programObject) + return false; + } else if (_programObject == nullptr && _shadowEnabled && _hasNightTexture) { // shadow program _programObject = renderEngine.buildRenderProgram( "shadowNightProgram", @@ -276,8 +465,52 @@ bool RenderablePlanet::initialize() { _programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _programObject->setIgnoreUniformLocationError(IgnoreError::Yes); + /*_atmosphereProgramObject = renderEngine.buildRenderProgram( + "atmosphereDeferredProgram", + "${MODULE_BASE}/shaders/atmosphere_deferred_vs.glsl", + "${MODULE_BASE}/shaders/atmosphere_deferred_fs.glsl"); + if (!_atmosphereProgramObject) + return false;*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after load shading programs. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + loadTexture(); - _geometry->initialize(this); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error loading textures. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + _geometry->initialize(this); + + _programObject->deactivate(); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Shader Programs Creation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //Atmosphere precomputation and tables + if (_atmosphereEnabled && !_atmosphereCalculated) { + _atmosphereCalculated = true; + + preCalculateAtmosphereParam(); + + //createAtmosphereFBO(); + + createRenderQuad(&_atmosphereRenderVAO, &_atmosphereRenderVBO, 6); + } + + count = 0; return isReady(); } @@ -294,9 +527,68 @@ bool RenderablePlanet::deinitialize() { _programObject = nullptr; } - _geometry = nullptr; - _texture = nullptr; - _nightTexture = nullptr; + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + if (_deltaEProgramObject) { + renderEngine.removeRenderProgram(_deltaEProgramObject); + _deltaEProgramObject = nullptr; + } + + if (_deltaSProgramObject) { + renderEngine.removeRenderProgram(_deltaSProgramObject); + _deltaSProgramObject = nullptr; + } + + if (_deltaSSupTermsProgramObject) { + renderEngine.removeRenderProgram(_deltaSSupTermsProgramObject); + _deltaSSupTermsProgramObject = nullptr; + } + + if (_deltaJProgramObject) { + renderEngine.removeRenderProgram(_deltaJProgramObject); + _deltaJProgramObject = nullptr; + } + + _geometry = nullptr; + _texture = nullptr; + _nightTexture = nullptr; + _reflectanceTexture = nullptr; + _cloudsTexture = nullptr; + + glDeleteTextures(1, &_transmittanceTableTexture); + glDeleteTextures(1, &_irradianceTableTexture); + glDeleteTextures(1, &_inScatteringTableTexture); + glDeleteTextures(1, &_deltaETableTexture); + glDeleteTextures(1, &_deltaSRayleighTableTexture); + glDeleteTextures(1, &_deltaSMieTableTexture); + glDeleteTextures(1, &_deltaJTableTexture); + glDeleteTextures(1, &_atmosphereTexture); + + glDeleteFramebuffers(1, &_atmosphereFBO); + return true; } @@ -330,9 +622,14 @@ void RenderablePlanet::render(const RenderData& data) // setup the data to the shader double lt; - glm::dvec3 pt = - SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, _time, lt); - psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(pt.x, pt.y, pt.z); + glm::dvec3 sunPosFromPlanet = + SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); + sunPosFromPlanet *= 1000.0; // from Km to m + psc sun_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(sunPosFromPlanet.x, sunPosFromPlanet.y, sunPosFromPlanet.z); + + glm::dvec3 planetPosFromSun = + SpiceManager::ref().targetPosition(_target, "SUN", "GALACTIC", {}, _time, lt); + psc tmppos = PowerScaledCoordinate::CreatePowerScaledCoordinate(planetPosFromSun.x, planetPosFromSun.y, planetPosFromSun.z); glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3()); // This is camera position vector (camera direction) in world coordinates. @@ -345,6 +642,22 @@ void RenderablePlanet::render(const RenderData& data) _programObject->setUniform("transparency", _alpha); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", transform); + + // Normal Transformation + glm::mat4 translateObjTrans = glm::translate(glm::mat4(1.0), data.position.vec3()); + glm::mat4 translateCamTrans = glm::translate(glm::mat4(1.0), -data.camera.position().vec3()); + float scaleFactor = data.camera.scaling().x * powf(10.0, data.camera.scaling().y); + glm::mat4 scaleCamTrans = glm::scale(glm::mat4(1.0), glm::vec3(scaleFactor)); + + // Is it wright not considering the camera rotation matrix here? + /*glm::mat4 ModelViewTrans = data.camera.viewMatrix() * scaleCamTrans * + data.camera.viewRotationMatrix() * translateCamTrans * translateObjTrans * transform;*/ + glm::mat4 ModelViewTrans = data.camera.viewMatrix() * scaleCamTrans * + translateCamTrans * translateObjTrans * transform; + if (_atmosphereEnabled) + _programObject->setUniform("NormalTransform", + glm::transpose(glm::inverse(ModelViewTrans))); + setPscUniforms(*_programObject.get(), data.camera, data.position); _programObject->setUniform("_performShading", _performShading); @@ -378,6 +691,7 @@ void RenderablePlanet::render(const RenderData& data) glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + // TODO: Move Calculations to VIEW SPACE (precision problems avoidance...) // Shadow calculations.. if (!_shadowConfArray.empty()) { std::vector shadowDataArray; @@ -407,6 +721,7 @@ void RenderablePlanet::render(const RenderData& data) ShadowRenderingStruct shadowData; shadowData.isShadowing = false; + if (((d_test - rp_test) < _planetRadius) && (casterDistSun < planetDistSun) ) { // The current caster is shadowing the current planet @@ -450,14 +765,316 @@ void RenderablePlanet::render(const RenderData& data) counter++; } } + + // Atmosphere Data + if (_atmosphereEnabled) { + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errorString = gluErrorString(err); + std::stringstream ss; + ss << "Error setting up atmosphere framebuffer. OpenGL error: " + << err << " - " << errorString << std::endl; + LERROR(ss.str()); + } + + // Object Space (in Km) + glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3() / 1000.0f); + glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * data.camera.viewRotationMatrix() * + translateCamTrans * obj2World * transform; + + glm::mat4 completeInverse = glm::inverse(M); + + _programObject->setUniform("completeInverse", completeInverse); + _programObject->setUniform("projInverse", glm::inverse(data.camera.projectionMatrix())); + + // This is camera position and planet position vector in object coordinates, in Km. + glm::mat4 world2Obj = glm::inverse(obj2World * transform); + glm::vec4 cameraPosObj = world2Obj * glm::vec4(data.camera.position().vec3() / 1000.0f, 1.0); + glm::vec4 planetPositionObj = world2Obj * glm::vec4(data.position.vec3() / 1000.0f, 1.0); + _programObject->setUniform("cameraPosObj", cameraPosObj); + _programObject->setUniform("planetPositionObj", planetPositionObj); + + // I know it is (0,0,0). It is here just for sake of sanity. :-p + glm::dvec3 sunPosWorld = + SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt); + glm::vec4 sunPosObj = world2Obj * glm::vec4(sunPosWorld.x, sunPosWorld.y, sunPosWorld.z, 1.0); + _programObject->setUniform("sunPositionObj", glm::vec3(sunPosObj)); + + _transmittanceTableTextureUnit.activate(); + _programObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + + _irradianceTableTextureUnit.activate(); + _programObject->setUniform("irradianceTexture", _irradianceTableTextureUnit); + + _inScatteringTableTextureUnit.activate(); + _programObject->setUniform("inscatterTexture", _inScatteringTableTextureUnit); + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); + _programObject->setUniform("screenX", (float)m_viewport[0]); + _programObject->setUniform("screenY", (float)m_viewport[1]); + _programObject->setUniform("screenWIDTH", (float)m_viewport[2]); + _programObject->setUniform("screenHEIGHT", (float)m_viewport[3]); + + + _programObject->setUniform("Rg", _atmospherePlanetRadius); + _programObject->setUniform("Rt", _atmosphereRadius); + _programObject->setUniform("AVERAGE_GROUND_REFLECTANCE", _planetAverageGroundReflectance); + _programObject->setUniform("HR", _rayleighHeightScale); + _programObject->setUniform("betaR", _rayleighScatteringCoeff); + _programObject->setUniform("HM", _mieHeightScale); + _programObject->setUniform("betaMSca", _mieScatteringCoeff); + _programObject->setUniform("betaMEx", _mieExtinctionCoeff); + _programObject->setUniform("mieG", _miePhaseConstant); + + + ghoul::opengl::TextureUnit reflectanceUnit; + if (_hasReflectanceTexture) { + reflectanceUnit.activate(); + _reflectanceTexture->bind(); + _programObject->setUniform("reflectanceTexture", reflectanceUnit); + } + + ghoul::opengl::TextureUnit cloudsUnit; + if (_hasCloudsTexture) { + cloudsUnit.activate(); + _cloudsTexture->bind(); + _programObject->setUniform("cloudsTexture", cloudsUnit); + } + + // HDR + _programObject->setUniform("exposure", 0.4f); + + /*std::stringstream ss; + ss << "atmosphere-" << count++ << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT0, ss.str(), m_viewport[2], m_viewport[3]);*/ + } + + + + // render _geometry->render(); // disable shader _programObject->deactivate(); + + + + // + // + //// Render Atmosphere to a texture: + //if (_atmosphereEnabled) { + + // /*std::cout << "\nTestes..." << std::endl; + // glm::dvec3 sunPosSun = SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt); + // glm::dvec3 earthPosSun = SpiceManager::ref().targetPosition("EARTH", "SUN", "GALACTIC", {}, _time, lt); + // std::cout << "\n\nSun in Sun: " << sunPosSun.x << ", " << sunPosSun.y << ", " << sunPosSun.z << std::endl; + // std::cout << "\n\nEarth in Sun: " << earthPosSun.x << ", " << earthPosSun.y << ", " << earthPosSun.z << std::endl; + // std::cout << "\n\nCam Position in Sun: " << data.camera.position().vec3().x << ", " << data.camera.position().vec3().y << ", " << data.camera.position().vec3().z << std::endl; + // std::cout << "\n\nCam Position from Earth in Sun: " << cam_dir.x << ", " << cam_dir.y << ", " << cam_dir.z << std::endl; + // + // glm::dmat3 sun2earthMat = SpiceManager::ref().frameTransformationMatrix("GALACTIC", "IAU_EARTH", _time); + // glm::dvec3 sunPosEarth = sun2earthMat * sunPosSun; + // glm::dvec3 earthPosEarth = sun2earthMat * earthPosSun; + // glm::dvec3 camDirEarth = sun2earthMat * cam_dir; + // glm::dvec3 camPosEarth = sun2earthMat * data.camera.position().vec3(); + // std::cout << "\n\nSun in Earth: " << sunPosEarth.x << ", " << sunPosEarth.y << ", " << sunPosEarth.z << std::endl; + // std::cout << "\n\nEarth in Earth: " << earthPosEarth.x << ", " << earthPosEarth.y << ", " << earthPosEarth.z << std::endl; + // std::cout << "\n\nCam Position in Earth: " << camPosEarth.x << ", " << camPosEarth.y << ", " << camPosEarth.z << std::endl; + // std::cout << "\n\nCam Position from Earth in Earth: " << camDirEarth.x << ", " << camDirEarth.y << ", " << camDirEarth.z << std::endl; + + // glm::dvec3 sunPosView = glm::dvec3(data.camera.viewMatrix() * glm::dvec4(sunPosSun.x, sunPosSun.y, sunPosSun.z, 1.0)); + // glm::dvec3 earthPosView = glm::dvec3(data.camera.viewMatrix() * glm::dvec4(earthPosSun.x, earthPosSun.y, earthPosSun.z, 1.0)); + // glm::dvec3 camDirView = glm::dvec3(data.camera.viewMatrix() * glm::dvec4(cam_dir.x, cam_dir.y, cam_dir.z, 0.0)); + // glm::dvec3 camPosView = glm::dvec3(data.camera.viewMatrix() * glm::dvec4(data.camera.position().vec3().x, data.camera.position().vec3().y, data.camera.position().vec3().z, 1.0)); + // std::cout << "\n\nSun in View: " << sunPosView.x << ", " << sunPosView.y << ", " << sunPosView.z << std::endl; + // std::cout << "\n\nEarth in View: " << earthPosView.x << ", " << earthPosView.y << ", " << earthPosView.z << std::endl; + // std::cout << "\n\nCam Position in View: " << camPosView.x << ", " << camPosView.y << ", " << camPosView.z << std::endl; + // std::cout << "\n\nCam Position from Earth in View: " << camDirView.x << ", " << camDirView.y << ", " << camDirView.z << std::endl;*/ + + + // GLint defaultFBO; + // glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + // GLint m_viewport[4]; + // glGetIntegerv(GL_VIEWPORT, m_viewport); + + // glBindFramebuffer(GL_FRAMEBUFFER, _atmosphereFBO); + // glReadBuffer(GL_COLOR_ATTACHMENT1); + // GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; + // glDrawBuffers(2, drawBuffers); + + // if (!glIsTexture(_dummyTexture)) { + // _dummyTextureUnit.activate(); + // glGenTextures(1, &_dummyTexture); + // //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _dummyTexture); + // glBindTexture(GL_TEXTURE_2D, _dummyTexture); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_viewport[2], + // m_viewport[3], 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + // /*glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGBA, + // m_viewport[2], m_viewport[3], true);*/ + // } + + // glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + // glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _atmosphereTexture, 0); + // //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _dummyTexture, 0); + // //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, _atmosphereTexture, 0); + // if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + // LERROR("Atmosphere Framework not built."); + // GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER); + // switch (fbErr) { + // case GL_FRAMEBUFFER_UNDEFINED: + // LERROR("Indefined framebuffer."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + // LERROR("Incomplete, missing attachement."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + // LERROR("Framebuffer doesn't have at least one image attached to it."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + // LERROR("Returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for any color attachment point(s) named by GL_DRAW_BUFFERi."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + // LERROR("Returned if GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER."); + // break; + // case GL_FRAMEBUFFER_UNSUPPORTED: + // LERROR("Returned if the combination of internal formats of the attached images violates an implementation - dependent set of restrictions."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + // LERROR("Returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or , if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES."); + // LERROR("Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same for all attached textures; or , if the attached images are a mix of renderbuffers and textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures."); + // break; + // case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + // LERROR("Returned if any framebuffer attachment is layered, and any populated attachment is not layered, or if all populated color attachments are not from textures of the same target."); + // break; + // } + // } + + // GLenum err; + // while ((err = glGetError()) != GL_NO_ERROR) { + // const GLubyte * errorString = gluErrorString(err); + // std::stringstream ss; + // ss << "Error setting up atmosphere framebuffer. OpenGL error: " + // << err << " - " << errorString << std::endl; + // LERROR(ss.str()); + // } + + // glClearColor(1.0, 0.0, 0.0, 1.0); + // glClear(GL_COLOR_BUFFER_BIT); + // + // _atmosphereProgramObject->activate(); + // //glm::vec2 camScaling = data.camera.scaling(); + // ///*glm::mat4 invScaling = glm::scale(glm::mat4(1.0), glm::vec3(1.0 / (camScaling.x * pow(10.0, camScaling.y)))); + // //glm::mat4 invCamRot = glm::inverse(data.camera.viewRotationMatrix()); + // //glm::mat4 invTrans = glm::translate(glm::mat4(1.0), glm::vec3(-data.camera.position().vec4()));*/ + + // //glm::mat4 camScaleTrans = glm::scale(glm::mat4(1.0), glm::vec3(camScaling.x * pow(10.0, camScaling.y))); + // //glm::mat4 camRotationTrans = glm::mat4(glm::mat3(data.camera.viewRotationMatrix())); + // //glm::mat4 camTranslationTrans = glm::translate(glm::mat4(1.0), glm::vec3(-data.camera.position().vec4())); + + // //glm::mat4 completeInverse = glm::inverse(data.camera.viewProjectionMatrix() * camScaleTrans * + // // camRotationTrans * camTranslationTrans); + + + // // Object Space (in Km) + // glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3() / 1000.0f); + // glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * data.camera.viewRotationMatrix() * + // translateCamTrans * obj2World * transform; + + // // World Space + // /*glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * data.camera.viewRotationMatrix() * + // translateCamTrans;*/ + + // //glm::mat4 completeInverse = glm::inverse(data.camera.projectionMatrix() * M); + // glm::mat4 completeInverse = glm::inverse(M); + + // //glm::mat4 completeInverse = glm::inverse(data.camera.projectionMatrix() * ModelViewTrans); + + // _atmosphereProgramObject->setUniform("completeInverse", completeInverse); + // _atmosphereProgramObject->setUniform("projInverse", glm::inverse(data.camera.projectionMatrix())); + // + // //// This is camera position and planet position vector in world coordinates, in Km. + // //glm::vec4 cameraPosWorld = glm::vec4(data.camera.position().vec3() / 1000.0f, 1.0); + // //glm::vec4 planetPositionWorld = glm::vec4(data.position.vec3() / 1000.0f, 1.0); + // //_atmosphereProgramObject->setUniform("cameraPosWorld", cameraPosWorld); + // //_atmosphereProgramObject->setUniform("planetPosition", planetPositionWorld); + // //// I know it is (0,0,0). It is here just for sake of sanity. :-p + // //glm::dvec3 sunPosWorld = + // // SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt); + // //_atmosphereProgramObject->setUniform("sunPositionWorld", sunPosWorld); + + // // This is camera position and planet position vector in object coordinates, in Km. + // glm::mat4 world2Obj = glm::inverse(obj2World * transform); + // glm::vec4 cameraPosObj = world2Obj * glm::vec4(data.camera.position().vec3() / 1000.0f, 1.0); + // glm::vec4 planetPositionObj = world2Obj * glm::vec4(data.position.vec3() / 1000.0f, 1.0); + // _atmosphereProgramObject->setUniform("cameraPosObj", cameraPosObj); + // _atmosphereProgramObject->setUniform("planetPositionObj", planetPositionObj); + // + // // I know it is (0,0,0). It is here just for sake of sanity. :-p + // glm::dvec3 sunPosWorld = + // SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt); + // glm::vec4 sunPosObj = world2Obj * glm::vec4(sunPosWorld.x, sunPosWorld.y, sunPosWorld.z, 1.0); + // _atmosphereProgramObject->setUniform("sunPositionObj", glm::vec3(sunPosObj)); + + // //// DEBUG: + // //std::cout << "\n\nSun in Obj Space: " << sunPosObj.x << ", " << sunPosObj.y << ", " << sunPosObj.z << std::endl; + // //std::cout << "\n\nEarth in Obj Space: " << planetPositionObj.x << ", " << planetPositionObj.y << ", " << planetPositionObj.z << std::endl; + // //std::cout << "\n\nCam in Obj Space: " << cameraPosObj.x << ", " << cameraPosObj.y << ", " << cameraPosObj.z << std::endl; + // + // _transmittanceTableTextureUnit.activate(); + // //glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture); + // _atmosphereProgramObject->setUniform("transmittanceSampler", _transmittanceTableTextureUnit); + + // _irradianceTableTextureUnit.activate(); + // //glBindTexture(GL_TEXTURE_2D, _irradianceTableTexture); + // _atmosphereProgramObject->setUniform("irradianceSampler", _irradianceTableTextureUnit); + + // _inScatteringTableTextureUnit.activate(); + // //glBindTexture(GL_TEXTURE_3D, _inScatteringTableTexture); + // _atmosphereProgramObject->setUniform("inscatterSampler", _inScatteringTableTextureUnit); + // + // if (_hasReflectanceTexture) { + // ghoul::opengl::TextureUnit reflectanceUnit; + // reflectanceUnit.activate(); + // _reflectanceTexture->bind(); + // _atmosphereProgramObject->setUniform("reflectanceSampler", reflectanceUnit); + // } + + // // HDR + // _atmosphereProgramObject->setUniform("exposure", 0.4f); + + // setPscUniforms(*_atmosphereProgramObject.get(), data.camera, data.position); + + // // check OpenGL error + // while ((err = glGetError()) != GL_NO_ERROR) { + // const GLubyte * errorString = gluErrorString(err); + // std::cout << "\n\nBefore Rendering Planet. OpenGL error: " + // << err << " - " << errorString << std::endl; + // } + + // renderQuadForCalc(_atmosphereRenderVAO, 6); + + // std::stringstream ss; + // ss << "atmosphere-" << count++ << ".ppm"; + // saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, ss.str(), m_viewport[2], m_viewport[3]); + + // _atmosphereProgramObject->deactivate(); + + // glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + // glViewport(m_viewport[0], m_viewport[1], + // m_viewport[2], m_viewport[3]); + //} } -void RenderablePlanet::update(const UpdateData& data){ +void RenderablePlanet::update(const UpdateData& data) { // set spice-orientation in accordance to timestamp _stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, "GALACTIC", data.time); _time = data.time; @@ -477,6 +1094,15 @@ void RenderablePlanet::loadTexture() { _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after reading memory 1. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + if (_hasNightTexture) { _nightTexture = nullptr; if (_nightTexturePath.value() != "") { @@ -490,6 +1116,33 @@ void RenderablePlanet::loadTexture() { } } + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after reading memory 2. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + if (_hasReflectanceTexture) { + _reflectanceTexture = nullptr; + if (_reflectanceTexturePath.value() != "") { + _reflectanceTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_reflectanceTexturePath))); + if (_reflectanceTexture) { + LDEBUG("Loaded texture from '" << _reflectanceTexturePath << "'"); + _reflectanceTexture->uploadTexture(); + _reflectanceTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + //_reflectanceTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + } + } + } + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after reading memory 3. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + if (_hasHeightTexture) { _heightMapTexture = nullptr; if (_heightMapTexturePath.value() != "") { @@ -502,6 +1155,1121 @@ void RenderablePlanet::loadTexture() { } } } + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after reading memory 4. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + if (_hasCloudsTexture) { + _cloudsTexture = nullptr; + if (_cloudsTexturePath.value() != "") { + _cloudsTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_cloudsTexturePath))); + if (_cloudsTexture) { + LDEBUG("Loaded texture from '" << _cloudsTexturePath << "'"); + _cloudsTexture->uploadTexture(); + _cloudsTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + //_cloudsTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + } + } + } + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error after reading memory 5. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } +} + +void RenderablePlanet::loadComputationPrograms() { + + RenderEngine& renderEngine = OsEng.renderEngine(); + + //============== Transmittance ================= + if (_transmittanceProgramObject == nullptr) { + _transmittanceProgramObject = renderEngine.buildRenderProgram( + "transmittanceCalcProgram", + "${MODULE_BASE}/shaders/transmittance_calc_vs.glsl", + "${MODULE_BASE}/shaders/transmittance_calc_fs.glsl"); + if (!_transmittanceProgramObject) { + return; + } + } + using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; + _transmittanceProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _transmittanceProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + //============== Irradiance ================= + if (_irradianceProgramObject == nullptr) { + _irradianceProgramObject = renderEngine.buildRenderProgram( + "irradianceCalcProgram", + "${MODULE_BASE}/shaders/irradiance_calc_vs.glsl", + "${MODULE_BASE}/shaders/irradiance_calc_fs.glsl"); + if (!_irradianceProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + return; + } + } + _irradianceProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _irradianceProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + if (_irradianceSupTermsProgramObject == nullptr) { + _irradianceSupTermsProgramObject = renderEngine.buildRenderProgram( + "irradianceSupTermsCalcProgram", + "${MODULE_BASE}/shaders/irradiance_sup_calc_vs.glsl", + "${MODULE_BASE}/shaders/irradiance_sup_calc_fs.glsl"); + if (!_irradianceSupTermsProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + return; + } + } + _irradianceSupTermsProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _irradianceSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + //============== InScattering ================= + if (_inScatteringProgramObject == nullptr) { + _inScatteringProgramObject = renderEngine.buildRenderProgram( + "inScatteringCalcProgram", + "${MODULE_BASE}/shaders/inScattering_calc_vs.glsl", + "${MODULE_BASE}/shaders/inScattering_calc_fs.glsl", + "${MODULE_BASE}/shaders/inScattering_calc_gs.glsl"); + if (!_inScatteringProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + return; + } + } + _inScatteringProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _inScatteringProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + if (_inScatteringSupTermsProgramObject == nullptr) { + _inScatteringSupTermsProgramObject = renderEngine.buildRenderProgram( + "inScatteringSupTermsCalcProgram", + "${MODULE_BASE}/shaders/inScattering_sup_calc_vs.glsl", + "${MODULE_BASE}/shaders/inScattering_sup_calc_fs.glsl", + "${MODULE_BASE}/shaders/inScattering_sup_calc_gs.glsl"); + if (!_inScatteringSupTermsProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + return; + } + } + _inScatteringSupTermsProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _inScatteringSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + //============== Delta E ================= + if (_deltaEProgramObject == nullptr) { + _deltaEProgramObject = renderEngine.buildRenderProgram( + "deltaECalcProgram", + "${MODULE_BASE}/shaders/deltaE_calc_vs.glsl", + "${MODULE_BASE}/shaders/deltaE_calc_fs.glsl"); + if (!_deltaEProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + return; + } + } + _deltaEProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _deltaEProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + //============== Delta S ================= + if (_deltaSProgramObject == nullptr) { + _deltaSProgramObject = renderEngine.buildRenderProgram( + "deltaSCalcProgram", + "${MODULE_BASE}/shaders/deltaS_calc_vs.glsl", + "${MODULE_BASE}/shaders/deltaS_calc_fs.glsl", + "${MODULE_BASE}/shaders/deltaS_calc_gs.glsl"); + if (!_deltaSProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + if (_deltaEProgramObject) { + renderEngine.removeRenderProgram(_deltaEProgramObject); + _deltaEProgramObject = nullptr; + } + + return; + } + } + _deltaSProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _deltaSProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + if (_deltaSSupTermsProgramObject == nullptr) { + _deltaSSupTermsProgramObject = renderEngine.buildRenderProgram( + "deltaSSUPTermsCalcProgram", + "${MODULE_BASE}/shaders/deltaS_sup_calc_vs.glsl", + "${MODULE_BASE}/shaders/deltaS_sup_calc_fs.glsl", + "${MODULE_BASE}/shaders/deltaS_sup_calc_gs.glsl"); + if (!_deltaSSupTermsProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + if (_deltaEProgramObject) { + renderEngine.removeRenderProgram(_deltaEProgramObject); + _deltaEProgramObject = nullptr; + } + + if (_deltaSProgramObject) { + renderEngine.removeRenderProgram(_deltaSProgramObject); + _deltaSProgramObject = nullptr; + } + + return; + } + } + _deltaSSupTermsProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _deltaSSupTermsProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); + + //============== Delta J (Radiance Scattered) ================= + if (_deltaJProgramObject == nullptr) { + // shadow program + _deltaJProgramObject = renderEngine.buildRenderProgram( + "deltaJCalcProgram", + "${MODULE_BASE}/shaders/deltaJ_calc_vs.glsl", + "${MODULE_BASE}/shaders/deltaJ_calc_fs.glsl", + "${MODULE_BASE}/shaders/deltaJ_calc_gs.glsl"); + if (!_deltaJProgramObject) { + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + if (_deltaEProgramObject) { + renderEngine.removeRenderProgram(_deltaEProgramObject); + _deltaEProgramObject = nullptr; + } + + if (_deltaSProgramObject) { + renderEngine.removeRenderProgram(_deltaSProgramObject); + _deltaSProgramObject = nullptr; + } + + if (_deltaSSupTermsProgramObject) { + renderEngine.removeRenderProgram(_deltaSSupTermsProgramObject); + _deltaSSupTermsProgramObject = nullptr; + } + + return; + } + + } + _deltaJProgramObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + _deltaJProgramObject->setIgnoreUniformLocationError(IgnoreError::Yes); +} + +void RenderablePlanet::unloadComputationPrograms() { + + RenderEngine& renderEngine = OsEng.renderEngine(); + + if (_transmittanceProgramObject) { + renderEngine.removeRenderProgram(_transmittanceProgramObject); + _transmittanceProgramObject = nullptr; + } + + if (_irradianceProgramObject) { + renderEngine.removeRenderProgram(_irradianceProgramObject); + _irradianceProgramObject = nullptr; + } + + if (_irradianceSupTermsProgramObject) { + renderEngine.removeRenderProgram(_irradianceSupTermsProgramObject); + _irradianceSupTermsProgramObject = nullptr; + } + + if (_inScatteringProgramObject) { + renderEngine.removeRenderProgram(_inScatteringProgramObject); + _inScatteringProgramObject = nullptr; + } + + if (_inScatteringSupTermsProgramObject) { + renderEngine.removeRenderProgram(_inScatteringSupTermsProgramObject); + _inScatteringSupTermsProgramObject = nullptr; + } + + if (_deltaEProgramObject) { + renderEngine.removeRenderProgram(_deltaEProgramObject); + _deltaEProgramObject = nullptr; + } + + if (_deltaSProgramObject) { + renderEngine.removeRenderProgram(_deltaSProgramObject); + _deltaSProgramObject = nullptr; + } + + if (_deltaSSupTermsProgramObject) { + renderEngine.removeRenderProgram(_deltaSSupTermsProgramObject); + _deltaSSupTermsProgramObject = nullptr; + } + + if (_deltaJProgramObject) { + renderEngine.removeRenderProgram(_deltaJProgramObject); + _deltaJProgramObject = nullptr; + } +} + +void RenderablePlanet::createComputationTextures() { + // TODO: Change precision of textures: GL_RGB16F to GL_RGB32F + //========== Create Tables (textures) ============== + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error before creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + _dummyTextureUnit.activate(); + glGenTextures(1, &_dummyTexture); + glBindTexture(GL_TEXTURE_2D, _dummyTexture); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, TRANSMITTANCE_TABLE_WIDTH, + TRANSMITTANCE_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr); + + //GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 1 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + ghoul::opengl::TextureUnit _dummy3DTextureUnit; + _dummy3DTextureUnit.activate(); + glGenTextures(1, &_dummy3DTexture); + glBindTexture(GL_TEXTURE_3D, _dummy3DTexture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F, MU_S_SAMPLES * NU_SAMPLES, + MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 2 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== Transmittance ================= + _transmittanceTableTextureUnit.activate(); + glGenTextures(1, &_transmittanceTableTexture); + glBindTexture(GL_TEXTURE_2D, _transmittanceTableTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, TRANSMITTANCE_TABLE_WIDTH, + TRANSMITTANCE_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 3 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== Irradiance ================= + _irradianceTableTextureUnit.activate(); + glGenTextures(1, &_irradianceTableTexture); + glBindTexture(GL_TEXTURE_2D, _irradianceTableTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, IRRADIANCE_TABLE_WIDTH, + IRRADIANCE_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 4 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== InScattering ================= + _inScatteringTableTextureUnit.activate(); + glGenTextures(1, &_inScatteringTableTexture); + glBindTexture(GL_TEXTURE_3D, _inScatteringTableTexture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F_ARB, MU_S_SAMPLES * NU_SAMPLES, + MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 5 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== Delta E ================= + _deltaETableTextureUnit.activate(); + glGenTextures(1, &_deltaETableTexture); + glBindTexture(GL_TEXTURE_2D, _deltaETableTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, DELTA_E_TABLE_WIDTH, + DELTA_E_TABLE_HEIGHT, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 6 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== Delta S ================= + _deltaSRayleighTableTextureUnit.activate(); + glGenTextures(1, &_deltaSRayleighTableTexture); + glBindTexture(GL_TEXTURE_3D, _deltaSRayleighTableTexture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F, MU_S_SAMPLES * NU_SAMPLES, + MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 7 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + _deltaSMieTableTextureUnit.activate(); + glGenTextures(1, &_deltaSMieTableTexture); + glBindTexture(GL_TEXTURE_3D, _deltaSMieTableTexture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F, MU_S_SAMPLES * NU_SAMPLES, + MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 8 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //============== Delta J (Radiance Scattered) ================= + _deltaJTableTextureUnit.activate(); + glGenTextures(1, &_deltaJTableTexture); + glBindTexture(GL_TEXTURE_3D, _deltaJTableTexture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F, MU_S_SAMPLES * NU_SAMPLES, + MU_SAMPLES, R_SAMPLES, 0, GL_RGB, GL_FLOAT, nullptr); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error 9 creating OpenGL textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } +} + +void RenderablePlanet::deleteComputationTextures() { + // Cleaning up + glDeleteTextures(1, &_dummyTexture); + glDeleteTextures(1, &_dummy3DTexture); + glDeleteTextures(1, &_transmittanceTableTexture); + glDeleteTextures(1, &_irradianceTableTexture); + glDeleteTextures(1, &_inScatteringTableTexture); + glDeleteTextures(1, &_deltaETableTexture); + glDeleteTextures(1, &_deltaSRayleighTableTexture); + glDeleteTextures(1, &_deltaSMieTableTexture); + glDeleteTextures(1, &_deltaJTableTexture); +} + +void RenderablePlanet::deleteUnusedComputationTextures() { + glDeleteTextures(1, &_dummyTexture); + glDeleteTextures(1, &_dummy3DTexture); + glDeleteTextures(1, &_deltaETableTexture); + glDeleteTextures(1, &_deltaSRayleighTableTexture); + glDeleteTextures(1, &_deltaSMieTableTexture); + glDeleteTextures(1, &_deltaJTableTexture); +} + +void RenderablePlanet::loadAtmosphereDataIntoShaderProgram(std::unique_ptr & shaderProg) { + shaderProg->setUniform("Rg", _atmospherePlanetRadius); + shaderProg->setUniform("Rt", _atmosphereRadius); + shaderProg->setUniform("AVERAGE_GROUND_REFLECTANCE", _planetAverageGroundReflectance); + shaderProg->setUniform("HR", _rayleighHeightScale); + shaderProg->setUniform("betaR", _rayleighScatteringCoeff); + shaderProg->setUniform("HM", _mieHeightScale); + shaderProg->setUniform("betaMSca", _mieScatteringCoeff); + shaderProg->setUniform("betaMEx", _mieExtinctionCoeff); + shaderProg->setUniform("mieG", _miePhaseConstant); +} + + +void RenderablePlanet::executeCalculations(const GLuint vao, const GLenum drawBuffers[2], const GLsizei vertexSize) { + // =========================================================== + // See Precomputed Atmosphere Scattering from Bruneton et al. paper, algorithm 4.1: + // =========================================================== + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _transmittanceTableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, TRANSMITTANCE_TABLE_WIDTH, TRANSMITTANCE_TABLE_HEIGHT); + _transmittanceProgramObject->activate(); + loadAtmosphereDataIntoShaderProgram(_transmittanceProgramObject); + renderQuadForCalc(vao, vertexSize); + /*saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("transmittance_texture.ppm"), + TRANSMITTANCE_TABLE_WIDTH, TRANSMITTANCE_TABLE_HEIGHT);*/ + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 1. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 2 in algorithm 4.1 + glBindTexture(GL_TEXTURE_2D, _dummyTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT, 0, + GL_RGB, GL_FLOAT, nullptr); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _deltaETableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT); + _irradianceProgramObject->activate(); + _irradianceProgramObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_irradianceProgramObject); + renderQuadForCalc(vao, vertexSize); + /*saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("deltaE_table_texture.ppm"), + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 2. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 3 in algorithm 4.1 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummy3DTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _deltaSRayleighTableTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, _deltaSMieTableTexture, 0); + GLenum colorBuffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, colorBuffers); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + _inScatteringProgramObject->activate(); + _inScatteringProgramObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_inScatteringProgramObject); + for (int layer = 0; layer < R_SAMPLES; ++layer) { + step3DTexture(_inScatteringProgramObject, layer); + renderQuadForCalc(vao, vertexSize); + } + /*saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("deltaS_rayleigh_texture.ppm"), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + saveTextureToPPMFile(GL_COLOR_ATTACHMENT2, std::string("deltaS_mie_texture.ppm"), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);*/ + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, 0, 0); + glDrawBuffers(2, drawBuffers); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 3. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 4 in algorithm 4.1 + glBindTexture(GL_TEXTURE_2D, _dummyTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT, 0, + GL_RGB, GL_FLOAT, nullptr); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _irradianceTableTexture, 0); + glDrawBuffers(2, drawBuffers); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT); + _deltaEProgramObject->activate(); + _deltaEProgramObject->setUniform("line", 4); + _deltaEProgramObject->setUniform("deltaETexture", _deltaETableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_deltaEProgramObject); + renderQuadForCalc(vao, vertexSize); + /*saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("irradiance_texture.ppm"), + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 4. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 5 in algorithm 4.1 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummy3DTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _inScatteringTableTexture, 0); + glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + _deltaSProgramObject->activate(); + _deltaSProgramObject->setUniform("deltaSRTexture", _deltaSRayleighTableTextureUnit); + _deltaSProgramObject->setUniform("deltaSMTexture", _deltaSMieTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_deltaSProgramObject); + for (int layer = 0; layer < R_SAMPLES; ++layer) { + step3DTexture(_deltaSProgramObject, layer, false); + renderQuadForCalc(vao, vertexSize); + } + /*saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, std::string("S_texture.ppm"), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 5. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // loop in line 6 in algorithm 4.1 + for (int scatteringOrder = 2; scatteringOrder <= 4; ++scatteringOrder) { + + // line 7 in algorithm 4.1 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummy3DTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _deltaJTableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + _deltaJProgramObject->activate(); + if (scatteringOrder == 2) + _deltaJProgramObject->setUniform("first", 1.0f); + else + _deltaJProgramObject->setUniform("first", 0.0f); + _deltaJProgramObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + _deltaJProgramObject->setUniform("deltaETexture", _deltaETableTextureUnit); + _deltaJProgramObject->setUniform("deltaSRTexture", _deltaSRayleighTableTextureUnit); + _deltaJProgramObject->setUniform("deltaSMTexture", _deltaSMieTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_deltaJProgramObject); + for (int layer = 0; layer < R_SAMPLES; ++layer) { + step3DTexture(_deltaJProgramObject, layer); + renderQuadForCalc(vao, vertexSize); + } + /*std::stringstream sst; + sst << "deltaJ_texture-scattering_order-" << scatteringOrder << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, sst.str(), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 6. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 8 in algorithm 4.1 + glBindTexture(GL_TEXTURE_2D, _dummyTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT, 0, + GL_RGB, GL_FLOAT, nullptr); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _deltaETableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT); + _irradianceSupTermsProgramObject->activate(); + if (scatteringOrder == 2) + _irradianceSupTermsProgramObject->setUniform("first", 1.0f); + else + _irradianceSupTermsProgramObject->setUniform("first", 0.0f); + _irradianceSupTermsProgramObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + _irradianceSupTermsProgramObject->setUniform("deltaSRTexture", _deltaSRayleighTableTextureUnit); + _irradianceSupTermsProgramObject->setUniform("deltaSMTexture", _deltaSMieTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_irradianceSupTermsProgramObject); + renderQuadForCalc(vao, vertexSize); + /*sst.str(std::string()); + sst << "deltaE_texture-scattering_order-" << scatteringOrder << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, sst.str(), + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 7. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 9 in algorithm 4.1 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummy3DTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _deltaSRayleighTableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + _inScatteringSupTermsProgramObject->activate(); + if (scatteringOrder == 2) + _inScatteringSupTermsProgramObject->setUniform("first", 1.0f); + else + _inScatteringSupTermsProgramObject->setUniform("first", 0.0f); + _inScatteringSupTermsProgramObject->setUniform("transmittanceTexture", _transmittanceTableTextureUnit); + _inScatteringSupTermsProgramObject->setUniform("deltaJTexture", _deltaJTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_inScatteringSupTermsProgramObject); + for (int layer = 0; layer < R_SAMPLES; ++layer) { + step3DTexture(_inScatteringSupTermsProgramObject, layer); + renderQuadForCalc(vao, vertexSize); + } + /*sst.str(std::string()); + sst << "deltaS_texture-scattering_order-" << scatteringOrder << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, sst.str(), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 8. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + glEnable(GL_BLEND); + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE); + + // line 10 in algorithm 4.1 + glBindTexture(GL_TEXTURE_2D, _dummyTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT, 0, + GL_RGB, GL_FLOAT, nullptr); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _irradianceTableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT); + _deltaEProgramObject->activate(); + _deltaEProgramObject->setUniform("line", 10); + _deltaEProgramObject->setUniform("deltaETexture", _deltaETableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_deltaEProgramObject); + renderQuadForCalc(vao, vertexSize); + /*sst.str(std::string()); + sst << "irradianceTable_order-" << scatteringOrder << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, sst.str(), + DELTA_E_TABLE_WIDTH, DELTA_E_TABLE_HEIGHT);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 9. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // line 11 in algorithm 4.1 + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummy3DTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _inScatteringTableTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Computation Framework not built."); + glViewport(0, 0, MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES); + _deltaSSupTermsProgramObject->activate(); + _deltaSSupTermsProgramObject->setUniform("deltaSTexture", _deltaSRayleighTableTextureUnit); + loadAtmosphereDataIntoShaderProgram(_deltaSSupTermsProgramObject); + for (int layer = 0; layer < R_SAMPLES; ++layer) { + step3DTexture(_deltaSSupTermsProgramObject, layer, false); + renderQuadForCalc(vao, vertexSize); + } + /*sst.str(std::string()); + sst << "inscatteringTable_order-" << scatteringOrder << ".ppm"; + saveTextureToPPMFile(GL_COLOR_ATTACHMENT1, sst.str(), + MU_S_SAMPLES * NU_SAMPLES, MU_SAMPLES);*/ + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error executing computation 10. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + glDisable(GL_BLEND); + } + +} + +void RenderablePlanet::preCalculateAtmosphereParam() { + + //========================================================== + //========= Load Shader Programs for Calculations ========== + //========================================================== + loadComputationPrograms(); + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error loading shader programs for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + //========================================================== + //============ Create Textures for Calculations ============ + //========================================================== + createComputationTextures(); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error creating textures for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // Preparing FBO... + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + GLuint calcFBO; + glGenFramebuffers(1, &calcFBO); + glBindFramebuffer(GL_FRAMEBUFFER, calcFBO); + glReadBuffer(GL_COLOR_ATTACHMENT1); + //glDrawBuffer(GL_COLOR_ATTACHMENT1); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; + glDrawBuffers(2, drawBuffers); + + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errString = gluErrorString(err); + std::stringstream ss; + ss << "Error creating FrameBuffer Object for Atmosphere computation. OpenGL error: " << errString << std::endl; + LERROR(ss.str()); + } + + // Prepare for rendering/calculations + GLuint calcVAO; + GLuint calcVBO; + createRenderQuad(&calcVAO, &calcVBO, 1.0f); + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); + + // Execute Calculations... + LDEBUG("Starting precalculations for scattering effects..."); + + //========================================================== + //=================== Execute Calculations ================= + //========================================================== + executeCalculations(calcVAO, drawBuffers, 6); + + deleteUnusedComputationTextures(); + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(m_viewport[0], m_viewport[1], + m_viewport[2], m_viewport[3]); + glDeleteBuffers(1, &calcVBO); + glDeleteVertexArrays(1, &calcVAO); + glDeleteFramebuffers(1, &calcFBO); + + LDEBUG("Ended precalculations for scattering effects..."); +} + +void RenderablePlanet::createAtmosphereFBO() { + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); + + /*GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); */ + + _atmosphereTextureUnit.activate(); + glGenTextures(1, &_atmosphereTexture); + glBindTexture(GL_TEXTURE_2D, _atmosphereTexture); + //glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _atmosphereTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_viewport[2], + m_viewport[2], 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + /*glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 8, GL_RGBA, + m_viewport[2], m_viewport[3], true);*/ + glGenFramebuffers(1, &_atmosphereFBO); + /*glBindFramebuffer(GL_FRAMEBUFFER, _atmosphereFBO); + glReadBuffer(GL_COLOR_ATTACHMENT1); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; + glDrawBuffers(2, drawBuffers); + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + std::stringstream ss; + ss << "Error creating atmosphere framebuffer. OpenGL error: " << err << std::endl; + LERROR(ss.str()); + } + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _dummyTexture, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, _atmosphereTexture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + LERROR("Atmosphere Framework not built."); + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(m_viewport[0], m_viewport[1], + m_viewport[2], m_viewport[3]);*/ + +} + +void RenderablePlanet::createRenderQuad(GLuint * vao, GLuint * vbo, const GLfloat size) { + + glGenVertexArrays(1, vao); + glGenBuffers(1, vbo); + glBindVertexArray(*vao); + glBindBuffer(GL_ARRAY_BUFFER, *vbo); + + const GLfloat vertex_data[] = { + // x y z w + -size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + -size, size, 0.0f, 1.0f, + -size, -size, 0.0f, 1.0f, + size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f + }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, reinterpret_cast(0)); + glEnableVertexAttribArray(0); + + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + std::stringstream ss; + ss << "Error creating vertexbuffer for computation. OpenGL error: " << err << std::endl; + LERROR(ss.str()); + } +} + +void RenderablePlanet::renderQuadForCalc(const GLuint vao, const GLsizei size) +{ + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, size); + glBindVertexArray(0); +} + +void RenderablePlanet::step3DTexture(std::unique_ptr & shaderProg, + const int layer, const bool doCalc) +{ + // See OpenGL redbook 8th Edition page 556 for Layered Rendering + //if (doCalc) + { + + float earth2 = _atmospherePlanetRadius * _atmospherePlanetRadius; + float atm2 = _atmosphereRadius * _atmosphereRadius; + float diff = atm2 - earth2; + float r = static_cast(layer) / static_cast(R_SAMPLES - 1); + float r2 = r * r; + float c = 0.0; + if (layer == 0) + c = 0.01f; + else if (layer == (R_SAMPLES - 1)) + c = -0.001f; + else + c = 0.0; + r = sqrtf(earth2 + r2 * diff) + c; + float dmin = _atmosphereRadius - r; + float dmax = sqrtf(r * r - earth2) + sqrtf(diff); + float dminp = r - _atmospherePlanetRadius; + float dmaxp = sqrtf(r * r - earth2); + + shaderProg->setUniform("r", r); + shaderProg->setUniform("dhdH", dmin, dmax, dminp, dmaxp); + } + + shaderProg->setUniform("layer", static_cast(layer)); +} + +void RenderablePlanet::saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName, + const int width, const int height) const { + std::fstream ppmFile; + + ppmFile.open(fileName.c_str(), std::fstream::out); + if (ppmFile.is_open()) { + unsigned char * pixels = new unsigned char[width*height * 3]; + for (int t = 0; t < width*height * 3; ++t) + pixels[t] = 255; + + + // check OpenGL error + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + const GLubyte * errorString = gluErrorString(err); + + std::cout << "\n\nBefore Reading Texture from card. OpenGL error: " + << err << " - " << errorString << std::endl; + } + + glReadBuffer(color_buffer_attachment); + glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + ppmFile << "P3" << std::endl; + ppmFile << width << " " << height << std::endl; + ppmFile << "255" << std::endl; + + std::cout << "\n\nFILE\n\n"; + int k = 0; + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + ppmFile << (unsigned int)pixels[k] << " " << (unsigned int)pixels[k + 1] << " " << (unsigned int)pixels[k + 2] << " "; + k += 3; + } + ppmFile << std::endl; + } + delete[] pixels; + + ppmFile.close(); + } } } // namespace openspace diff --git a/modules/base/rendering/renderableplanet.h b/modules/base/rendering/renderableplanet.h index c93094fee1..5fba652942 100644 --- a/modules/base/rendering/renderableplanet.h +++ b/modules/base/rendering/renderableplanet.h @@ -31,6 +31,8 @@ #include #include +#include + #include #include @@ -63,7 +65,39 @@ public: glm::vec3 casterPositionVec; bool isShadowing; }; + + // See: Precomputed Atmospheric Scattering from Bruneton et al. + // for explanation of the following parameters. + const unsigned int TRANSMITTANCE_TABLE_WIDTH = 256; + const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 64; + + const unsigned int IRRADIANCE_TABLE_WIDTH = 64; + const unsigned int IRRADIANCE_TABLE_HEIGHT = 16; + + const unsigned int DELTA_E_TABLE_WIDTH = 64; + const unsigned int DELTA_E_TABLE_HEIGHT = 16; + + + /*const unsigned int TRANSMITTANCE_TABLE_WIDTH = 512; + const unsigned int TRANSMITTANCE_TABLE_HEIGHT = 128; + + const unsigned int IRRADIANCE_TABLE_WIDTH = 128; + const unsigned int IRRADIANCE_TABLE_HEIGHT = 32; + + const unsigned int DELTA_E_TABLE_WIDTH = 128; + const unsigned int DELTA_E_TABLE_HEIGHT = 32;*/ + + const unsigned int R_SAMPLES = 32; + const unsigned int MU_SAMPLES = 128; + const unsigned int MU_S_SAMPLES = 32; + const unsigned int NU_SAMPLES = 8; + + /*const unsigned int R_SAMPLES = 64; + const unsigned int MU_SAMPLES = 256; + const unsigned int MU_S_SAMPLES = 64; + const unsigned int NU_SAMPLES = 16;*/ + public: RenderablePlanet(const ghoul::Dictionary& dictionary); ~RenderablePlanet(); @@ -78,15 +112,69 @@ public: protected: void loadTexture(); +private: + void loadComputationPrograms(); + void unloadComputationPrograms(); + void createComputationTextures(); + void deleteComputationTextures(); + void deleteUnusedComputationTextures(); + void loadAtmosphereDataIntoShaderProgram(std::unique_ptr & shaderProg); + void executeCalculations(const GLuint vao, const GLenum drawBuffers[2], const GLsizei vertexSize); + void preCalculateAtmosphereParam(); + void createAtmosphereFBO(); + void createRenderQuad(GLuint * vao, GLuint * vbo, const GLfloat size); + void renderQuadForCalc(const GLuint vao, const GLsizei size); + void step3DTexture(std::unique_ptr & shaderProg, + const int layer, const bool doCalc = true); + void saveTextureToPPMFile(const GLenum color_buffer_attachment, const std::string & fileName, + const int width, const int height) const; + private: properties::StringProperty _colorTexturePath; properties::StringProperty _nightTexturePath; properties::StringProperty _heightMapTexturePath; + properties::StringProperty _cloudsTexturePath; + properties::StringProperty _reflectanceTexturePath; std::unique_ptr _programObject; + std::unique_ptr _transmittanceProgramObject; + std::unique_ptr _irradianceProgramObject; + std::unique_ptr _irradianceSupTermsProgramObject; + std::unique_ptr _inScatteringProgramObject; + std::unique_ptr _inScatteringSupTermsProgramObject; + std::unique_ptr _deltaEProgramObject; + std::unique_ptr _deltaSProgramObject; + std::unique_ptr _deltaSSupTermsProgramObject; + std::unique_ptr _deltaJProgramObject; + std::unique_ptr _atmosphereProgramObject; + ghoul::opengl::TextureUnit _dummyTextureUnit; + ghoul::opengl::TextureUnit _dummy3DTextureUnit; + ghoul::opengl::TextureUnit _transmittanceTableTextureUnit; + ghoul::opengl::TextureUnit _irradianceTableTextureUnit; + ghoul::opengl::TextureUnit _inScatteringTableTextureUnit; + ghoul::opengl::TextureUnit _deltaETableTextureUnit; + ghoul::opengl::TextureUnit _deltaSRayleighTableTextureUnit; + ghoul::opengl::TextureUnit _deltaSMieTableTextureUnit; + ghoul::opengl::TextureUnit _deltaJTableTextureUnit; + ghoul::opengl::TextureUnit _atmosphereTextureUnit; std::unique_ptr _texture; std::unique_ptr _nightTexture; + std::unique_ptr _reflectanceTexture; std::unique_ptr _heightMapTexture; + std::unique_ptr _cloudsTexture; + GLuint _transmittanceTableTexture; + GLuint _irradianceTableTexture; + GLuint _inScatteringTableTexture; + GLuint _deltaETableTexture; + GLuint _deltaSRayleighTableTexture; + GLuint _deltaSMieTableTexture; + GLuint _deltaJTableTexture; + GLuint _dummyTexture; + GLuint _dummy3DTexture; + GLuint _atmosphereTexture; + GLuint _atmosphereFBO; + GLuint _atmosphereRenderVAO; + GLuint _atmosphereRenderVBO; properties::FloatProperty _heightExaggeration; @@ -101,9 +189,29 @@ private: std::string _frame; std::string _target; bool _hasNightTexture; + bool _hasReflectanceTexture; bool _hasHeightTexture; + bool _hasCloudsTexture; bool _shadowEnabled; double _time; + + // Atmosphere Data + bool _atmosphereCalculated; + bool _atmosphereEnabled; + float _atmosphereRadius; + float _atmospherePlanetRadius; + float _planetAverageGroundReflectance; + float _rayleighHeightScale; + float _mieHeightScale; + float _miePhaseConstant; + glm::vec3 _mieExtinctionCoeff; + glm::vec3 _rayleighScatteringCoeff; + glm::vec3 _mieScatteringCoeff; + + + bool tempPic; + + unsigned int count; }; } // namespace openspace diff --git a/modules/base/shaders/atmosphere_common.glsl b/modules/base/shaders/atmosphere_common.glsl new file mode 100644 index 0000000000..c8c11238bd --- /dev/null +++ b/modules/base/shaders/atmosphere_common.glsl @@ -0,0 +1,85 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +// Atmosphere Rendering Parameters +uniform float Rg; +uniform float Rt; +uniform float AVERAGE_GROUND_REFLECTANCE; +uniform float HR; +uniform vec3 betaR; +uniform float HM; +uniform vec3 betaMSca; +uniform vec3 betaMEx; +uniform float mieG; + +const float ATM_EPSILON = 1.0; +// const float RL = Rt + 1.0; + +// const float Rg = 6360.0; +// const float Rt = 6420.0; +// const float RL = 6421.0; +// const float ATM_EPSILON = 1.0; + +// const float AVERAGE_GROUND_REFLECTANCE = 0.1; + +// // Rayleigh +// const float HR = 8.0; +// const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2); + +// // Mie +// // DEFAULT +// const float HM = 1.2; +// const vec3 betaMSca = vec3(4e-3); +// //const vec3 betaMSca = vec3(2e-5); +// const vec3 betaMEx = betaMSca / 0.9; +// const float mieG = 1.0; + +// Integration steps +const int TRANSMITTANCE_STEPS = 500; +const int INSCATTER_INTEGRAL_SAMPLES = 50; +const int IRRADIANCE_INTEGRAL_SAMPLES = 32; +const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16; + +// The next values crash NVIDIA driver for Quadro K620 -- JCC +// const int TRANSMITTANCE_INTEGRAL_SAMPLES = 1000; +// const int INSCATTER_INTEGRAL_SAMPLES = 100; +// const int IRRADIANCE_INTEGRAL_SAMPLES = 64; +// const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 32; + +const float M_PI = 3.141592657; + +const int TRANSMITTANCE_W = 256; +const int TRANSMITTANCE_H = 64; + +const int SKY_W = 64; +const int SKY_H = 16; + +const int OTHER_TEXTURES_W = 64; +const int OTHER_TEXTURES_H = 16; + + +const int RES_R = 32; +const int RES_MU = 128; +const int RES_MU_S = 32; +const int RES_NU = 8; \ No newline at end of file diff --git a/modules/base/shaders/atmosphere_fs.glsl b/modules/base/shaders/atmosphere_fs.glsl new file mode 100644 index 0000000000..be2c97ab5f --- /dev/null +++ b/modules/base/shaders/atmosphere_fs.glsl @@ -0,0 +1,437 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#define EPSILON 0.0001f + +// Sun Irradiance +const float ISun = 50.0; +const uint numberOfShadows = 1; + +struct ShadowRenderingStruct { + float xu, xp; + float rs, rc; + vec3 sourceCasterVec; + vec3 casterPositionVec; + bool isShadowing; +}; + +uniform ShadowRenderingStruct shadowDataArray[numberOfShadows]; + +uniform mat4 completeInverse; +uniform mat4 projInverse; + +uniform vec4 campos; +uniform vec4 objpos; +uniform vec3 sun_pos; + +uniform vec4 cameraPosObj; +uniform vec4 planetPositionObj; +uniform vec3 sunPositionObj; + +uniform bool _performShading = true; +uniform float transparency; +uniform int shadows; + +uniform float screenX; +uniform float screenY; +uniform float screenWIDTH; +uniform float screenHEIGHT; + +uniform float time; +uniform sampler2D texture1; +uniform sampler2D nightTex; +uniform sampler2D cloudsTexture; + +uniform sampler2D reflectanceTexture; +uniform sampler2D transmittanceTexture; +uniform sampler2D irradianceTexture; +uniform sampler3D inscatterTexture; + +// TODO: Remove from there! +// the transmittance sampler is in scatteringinclude.glsl + +//layout(origin_upper_left) in vec4 gl_FragCoord; + +in vec2 vs_st; +in vec2 vs_nightTex; +in vec4 vs_normal; +in vec4 vs_position; +in vec4 vs_posWorld; + +#include "hdr.glsl" +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" +#include "atmosphere_common.glsl" + +vec4 butterworthFunc(const float d, const float r, const float n) { + return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0); +} + +/******************************************************************************* + ****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ****** + *******************************************************************************/ + +/* Calculates the intersection of the view ray direction with the atmosphere and + * returns the first intersection (0.0 when inside atmosphere): offset + * and the second intersection: maxLength + */ + +bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const float sphereRadius, + out float offset, out float maxLength) { + offset = 0.0f; + maxLength = 0.0f; + + vec3 l = planetPos.xyz - cameraPosObj.xyz; + float s = dot(l, rayDirection); + float l2 = dot(l, l); + + // sphereRadius in Km + float r = sphereRadius - EPSILON; // EPSILON to avoid surface acne + float r2 = r * r; + + if (l2 <= r2) { + // ray origin inside sphere + float m2 = l2 - (s*s); + float q = sqrt(r2 - m2); + maxLength = s + q; + + return true; + } + else if (s >= 0.0) { + // ray outside sphere + float m2 = l2 - (s*s); + if (m2 <= r2) { + // ray hits atmosphere + float q = sqrt(r2 - m2); + offset = s-q; + maxLength = (s+q)-offset; + + return true; + } + } + + return false; +} + +// Rayleigh phase function +float phaseFunctionR(float mu) { + return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); +} + +// Mie phase function +float phaseFunctionM(float mu) { + return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG); +} + +float opticalDepth(float H, float r, float mu, float d) { + float a = sqrt((0.5/H)*r); + vec2 a01 = a*vec2(mu, mu + d / r); + vec2 a01s = sign(a01); + vec2 a01sq = a01*a01; + float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0; + vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu))); + return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0))); +} + +vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) +{ + float H = sqrt(Rt * Rt - Rg * Rg); + float rho = sqrt(r * r - Rg * Rg); + float rmu = r * mu; + float delta = rmu * rmu - r * r + Rg * Rg; + vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); + float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); + float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); + float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); + float uNu = floor(lerp); + lerp = lerp - uNu; + return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + + texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; +} + +vec3 analyticTransmittance(float r, float mu, float d) { + return exp(- betaR * opticalDepth(HR, r, mu, d) - betaMEx * opticalDepth(HM, r, mu, d)); +} + +vec3 getMie(vec4 rayMie) { + return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaR.r / betaR); +} + +vec2 getTransmittanceUV(float r, float mu) { + float uR, uMu; + uR = sqrt((r - Rg) / (Rt - Rg)); + uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + return vec2(uMu, uR); +} + +vec3 transmittanceFromTexture(float r, float mu) { + vec2 uv = getTransmittanceUV(r, mu); + return texture(transmittanceTexture, uv).rgb; +} + +vec3 transmittanceWithShadow(float r, float mu) { + return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu); +} + +vec3 transmittance(float r, float mu, vec3 v, vec3 x0) { + vec3 result; + float r1 = length(x0); + float mu1 = dot(x0, v) / r; + if (mu > 0.0) { + result = min(transmittanceFromTexture(r, mu) / + transmittanceFromTexture(r1, mu1), 1.0); + } else { + result = min(transmittanceFromTexture(r1, -mu1) / + transmittanceFromTexture(r, -mu), 1.0); + } + return result; +} + +vec2 getIrradianceUV(float r, float muS) { + float uR = (r - Rg) / (Rt - Rg); + float uMuS = (muS + 0.2) / (1.0 + 0.2); + return vec2(uMuS, uR); +} + +vec3 irradiance(sampler2D sampler, float r, float muS) { + vec2 uv = getIrradianceUV(r, muS); + return texture(sampler, uv).rgb; +} + +/* + * Calculates the light scattering in the view direction comming from other + * light rays scattered in the atmosphere. + * The view direction here is the ray: x + tv, s is the sun direction, + * r and mu the position and zenith cossine angle as in the paper. + */ +vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s, + out float r, out float mu, out vec3 attenuation) { + vec3 result; + r = length(x); + mu = dot(x, v) / r; + float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt); + if (d > 0.0) { + x += d * v; + t -= d; + mu = (r * mu + d) / Rt; + r = Rt; + } + // Intersects atmosphere? + if (r <= Rt) { + float nu = dot(v, s); + float muS = dot(x, s) / r; + float phaseR = phaseFunctionR(nu); + float phaseM = phaseFunctionM(nu); + vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0); + if (t > 0.0) { + vec3 x0 = x + t * v; + float r0 = length(x0); + float rMu0 = dot(x0, v); + float mu0 = rMu0 / r0; + float muS0 = dot(x0, s) / r0; + + attenuation = analyticTransmittance(r, mu, t); + //attenuation = transmittance(r, mu, v, x+t*v); + + //The following Code is generating surface acne on atmosphere. JCC + // We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x + if (r0 > Rg + 0.1*r) { + inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0); + const float EPS = 0.004; + float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r)); + if (abs(mu - muHoriz) < EPS) { + float a = ((mu - muHoriz) + EPS) / (2.0 * EPS); + + mu = muHoriz - EPS; + r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); + mu0 = (r * mu + t) / r0; + vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); + vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); + vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); + + mu = muHoriz + EPS; + r0 = sqrt(r * r + t * t + 2.0 * r * t * mu); + mu0 = (r * mu + t) / r0; + inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu); + inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu); + vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0); + + inscatter = mix(inScatterA, inScatterB, a); + } + } + } + inscatter.w *= smoothstep(0.00, 0.02, muS); + result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0); + + } else { + // No intersection with earth + result = vec3(0.0); + } + return result * ISun; +} + +vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation) +{ + vec3 result; + // Ray hits ground + if (t > 0.0) { + vec3 x0 = x + t * v; + float r0 = length(x0); + vec3 n = x0 / r0; + + // Fixing texture coordinates: + vec4 reflectance = texture(reflectanceTexture, vs_st) * vec4(0.2, 0.2, 0.2, 1.0); + + // The following code is generating surface acne in ground. + // It is only necessary inside atmosphere rendering. JCC + // if (r0 > Rg + 0.01) { + // reflectance = vec4(0.4, 0.4, 0.4, 0.0); + // } + + float muS = dot(n, s); + vec3 sunLight = transmittanceWithShadow(r0, muS); + + vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS); + + vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st); + vec3 groundColor = (reflectance.rgb + clouds.rgb) * + (max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI; + + // Yellowish reflection from sun on oceans and rivers + if (reflectance.w > 0.0) { + vec3 h = normalize(s - v); + float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0); + float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0); + groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun; + } + + result = attenuation * groundColor; + } else { + // No hit + result = vec3(0.0); + } + return result; +} + +vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) { + if (t > 0.0) { + return vec3(0.0); + } else { + vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0); + float isun = step(cos(M_PI / 180.0), dot(v, s)) * ISun; + return transmittance * isun; + } +} + +/*********************************************************************** + ******* CALCULATIONS FOR SHADOWS ARE IN WORLD SPACE IN METERS ********* + ***********************************************************************/ + // TODO: Change calculations for view space in KM. +vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) { + if (shadowInfoArray[0].isShadowing) { + vec3 pc = shadowInfoArray[0].casterPositionVec - position; + vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader + vec3 pc_proj = dot(pc, sc_norm) * sc_norm; + vec3 d = pc - pc_proj; + + float length_d = length(d); + float length_pc_proj = length(pc_proj); + + float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp; + + //float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu; + float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu; + + if ( length_d < r_u_pi ) { // umbra + //return vec4(0.0, 0.0, 0.0, 1.0); + //return vec4(1.0, 0.0, 0.0, 1.0); + return butterworthFunc(length_d, r_u_pi, 4.0); + } + else if ( length_d < r_p_pi ) {// penumbra + //return vec4(0.5, 0.5, 0.5, 1.0); + //return vec4(0.0, 1.0, 0.0, 1.0); + return vec4(vec3(length_d/r_p_pi), 1.0); + } + } + + return vec4(1.0); +} + +Fragment getFragment() { + vec4 position = vs_position; + float depth = pscDepth(position); + vec4 diffuse = texture(texture1, vs_st); + vec4 diffuse2 = texture(nightTex, vs_st); + vec4 clouds = texture(cloudsTexture, vs_st); + + Fragment frag; + if (_performShading) { + // atmosphere + vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT); + vec4 ndcPos; + ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1; + ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / + (gl_DepthRange.far - gl_DepthRange.near); + ndcPos.w = 1.0; + vec4 clipPos = ndcPos / gl_FragCoord.w; + vec4 projCoords = projInverse * clipPos; + vec4 viewDirection = normalize(completeInverse * vec4(projCoords.xyz, 0.0)); + vec3 v = normalize(viewDirection.xyz); + + float offset, maxLength; + vec4 ppos = vec4(0.0); + //if (intersectAtmosphere(planetPositionObj, v, Rt, offset, maxLength)) { + if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) { + // Following paper nomenclature + float t = offset; + vec3 x = cameraPosObj.xyz;// + offset * v; + float r = length(x); + float mu = dot(x, v) / r; + vec3 s = normalize(sunPositionObj); + + vec3 attenuation; + vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation); + vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation); + vec3 sunColor = sunColor(x, t, v, s, r, mu); + + //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0)); + //diffuse = HDR(vec4(sunColor, 1.0)); + //diffuse = HDR(vec4(groundColor, 1.0)); + //diffuse = HDR(vec4(inscatterColor, 1.0)); + + //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2 + clouds); + diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) * + calcShadow(shadowDataArray, vs_posWorld.xyz) ); + } + // else + // diffuse = HDR(diffuse); + } + + diffuse[3] = transparency; + frag.color = diffuse; + frag.depth = depth; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/atmosphere_vs.glsl b/modules/base/shaders/atmosphere_vs.glsl new file mode 100644 index 0000000000..d514c15a90 --- /dev/null +++ b/modules/base/shaders/atmosphere_vs.glsl @@ -0,0 +1,76 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; +uniform mat4 NormalTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; +//layout(location = 3) in vec2 in_nightTex; + + +out vec2 vs_st; +out vec4 vs_normal; +out vec4 vs_position; +out vec4 vs_posWorld; +out float s; +out vec4 ray; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + // set variables + vs_st = in_st; + vs_position = in_position; + vec4 tmp = in_position; + + // 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)); + + // This is the wright transformation for the normals + vs_normal = normalize(NormalTransform * vec4(in_normal,0)); + + // The position is not in world coordinates, it is in + // regular view/eye coordinates. + vec4 position = pscTransform(tmp, ModelTransform); + + // Vertex position in world coordinates in meters and + // with no powerscalling coordiantes + 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; + + vs_position = tmp; + + // Now the position is transformed from view coordinates to SGCT projection + // coordinates. + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaE_calc_fs.glsl b/modules/base/shaders/deltaE_calc_fs.glsl new file mode 100644 index 0000000000..b68cebd774 --- /dev/null +++ b/modules/base/shaders/deltaE_calc_fs.glsl @@ -0,0 +1,48 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTableColor; + +// See paper algorithm +uniform int line; +uniform sampler2D deltaETexture; + +Fragment getFragment() { + if (line == 4) + renderTableColor = vec4(0.0); + else if (line == 10) { + vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H); + renderTableColor = texture(deltaETexture, uv); + } + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/deltaE_calc_vs.glsl b/modules/base/shaders/deltaE_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/deltaE_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaJ_calc_fs.glsl b/modules/base/shaders/deltaJ_calc_fs.glsl new file mode 100644 index 0000000000..c170ff6ccb --- /dev/null +++ b/modules/base/shaders/deltaJ_calc_fs.glsl @@ -0,0 +1,192 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTarget1; + +uniform float r; +uniform vec4 dhdH; + +uniform sampler2D transmittanceTexture; +uniform sampler2D deltaETexture; +uniform sampler3D deltaSRTexture; +uniform sampler3D deltaSMTexture; +uniform float first; + +const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); +const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); + +void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) { + float x = gl_FragCoord.x - 0.5; + float y = gl_FragCoord.y - 0.5; + if (y < float(RES_MU) / 2.0) { + float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); + mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); + mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); + } else { + float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); + mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); + } + mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); + mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); + nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; +} + +vec3 transmittanceFromTexture(const float r, const float mu) { + float u_r = sqrt((r - Rg) / (Rt - Rg)); + // See Colliene to understand the different mapping. + float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + + return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; +} + +vec3 transmittance(const float r, const float mu, float d) { + vec3 result; + float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); + float mu1 = (r * mu + d) / r1; + if (mu > 0.0) { + result = min(transmittanceFromTexture(r, mu) / + transmittanceFromTexture(r1, mu1), 1.0); + } else { + result = min(transmittanceFromTexture(r1, -mu1) / + transmittanceFromTexture(r, -mu), 1.0); + } + return result; +} + +// Rayleigh phase +float phaseFunctionR(const float mu) { + return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); +} + +// Mie phase +float phaseFunctionM(const float mu) { + return (3.0 / (8.0 * M_PI)) * + ( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) / + ( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) ); +} + +vec3 irradiance(sampler2D calcTexture, const float r, const float mu_s) { + float u_r = (r - Rg) / (Rt - Rg); + float u_mu_s = (mu_s + 0.2) / (1.0 + 0.2); + return texture(calcTexture, vec2(u_mu_s, u_r)).rgb; +} + +vec4 texture4D(sampler3D table, const float r, const float mu, + const float mu_s, const float nu) +{ + float H = sqrt(Rt * Rt - Rg * Rg); + float rho = sqrt(r * r - Rg * Rg); + float rmu = r * mu; + float delta = rmu * rmu - r * r + Rg * Rg; + vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); + float u_r = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); + float u_mu_s = 0.5 / float(RES_MU_S) + (atan(max(mu_s, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); + float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); + float uNu = floor(lerp); + lerp = lerp - uNu; + return texture(table, vec3((uNu + u_mu_s) / float(RES_NU), u_mu, u_r)) * (1.0 - lerp) + + texture(table, vec3((uNu + u_mu_s + 1.0) / float(RES_NU), u_mu, u_r)) * lerp; +} + +void inscatter(float r, float mu, float mu_s, float nu, out vec3 raymie) { + r = clamp(r, Rg, Rt); + mu = clamp(mu, -1.0, 1.0); + mu_s = clamp(mu_s, -1.0, 1.0); + float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - mu_s * mu_s); + nu = clamp(nu, mu_s * mu - var, mu_s * mu + var); + + float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r)); + + vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu); + float sx = v.x == 0.0 ? 0.0 : (nu - mu_s * mu) / v.x; + vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - mu_s * mu_s)), mu_s); + + raymie = vec3(0.0); + + for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) { + float theta = (float(itheta) + 0.5) * dtheta; + float ctheta = cos(theta); + + float greflectance = 0.0; + float dground = 0.0; + vec3 gtransp = vec3(0.0); + if (ctheta < cthetamin) { + greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI; + dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg); + gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground); + } + + for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) { + float phi = (float(iphi) + 0.5) * dphi; + float dw = dtheta * dphi * sin(theta); + vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta); + + float nu1 = dot(s, w); + float nu2 = dot(v, w); + float pr2 = phaseFunctionR(nu2); + float pm2 = phaseFunctionM(nu2); + + vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg; + vec3 girradiance = irradiance(deltaETexture, Rg, dot(gnormal, s)); + + vec3 raymie1; + + raymie1 = greflectance * girradiance * gtransp; + + if (first == 1.0) { + float pr1 = phaseFunctionR(nu1); + float pm1 = phaseFunctionM(nu1); + vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb; + vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu1).rgb; + raymie1 += ray1 * pr1 + mie1 * pm1; + } else { + raymie1 += texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb; + } + + raymie += raymie1 * (betaR * exp(-(r - Rg) / HR) * pr2 + betaMSca * exp(-(r - Rg) / HM) * pm2) * dw; + } + } +} + +Fragment getFragment() { + vec3 raymie; + float mu, mu_s, nu; + getMuMuSNu(r, dhdH, mu, mu_s, nu); + inscatter(r, mu, mu_s, nu, raymie); + + renderTarget1 = vec4(raymie, 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} diff --git a/modules/base/shaders/deltaJ_calc_gs.glsl b/modules/base/shaders/deltaJ_calc_gs.glsl new file mode 100644 index 0000000000..a4dd2d50b5 --- /dev/null +++ b/modules/base/shaders/deltaJ_calc_gs.glsl @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform int layer; + +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; + +void main() +{ + int n; + for (n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaJ_calc_vs.glsl b/modules/base/shaders/deltaJ_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/deltaJ_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_calc_fs.glsl b/modules/base/shaders/deltaS_calc_fs.glsl new file mode 100644 index 0000000000..c99ab18ad9 --- /dev/null +++ b/modules/base/shaders/deltaS_calc_fs.glsl @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTarget1; + +uniform int layer; + +uniform sampler3D deltaSRTexture; +uniform sampler3D deltaSMTexture; + +Fragment getFragment() { + vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R)); + vec4 ray = texture(deltaSRTexture, uvw); + vec4 mie = texture(deltaSMTexture, uvw); + + // We are using only the red component of the Mie scattering + // See the Precomputed Atmosphere Scattering paper for details about + // the angular precision. + renderTarget1 = vec4(ray.rgb, mie.r); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_calc_gs.glsl b/modules/base/shaders/deltaS_calc_gs.glsl new file mode 100644 index 0000000000..a4dd2d50b5 --- /dev/null +++ b/modules/base/shaders/deltaS_calc_gs.glsl @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform int layer; + +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; + +void main() +{ + int n; + for (n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_calc_vs.glsl b/modules/base/shaders/deltaS_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/deltaS_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_sup_calc_fs.glsl b/modules/base/shaders/deltaS_sup_calc_fs.glsl new file mode 100644 index 0000000000..68c6d6fe89 --- /dev/null +++ b/modules/base/shaders/deltaS_sup_calc_fs.glsl @@ -0,0 +1,54 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTarget1; + +uniform int layer; + +uniform sampler3D deltaSTexture; + +// Rayleigh phase +float phaseFunctionR(const float mu) { + return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); +} + +Fragment getFragment() { + float x = gl_FragCoord.x - 0.5; + float y = gl_FragCoord.y - 0.5; + + float nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; + vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R)); + + renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / phaseFunctionR(nu), 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_sup_calc_gs.glsl b/modules/base/shaders/deltaS_sup_calc_gs.glsl new file mode 100644 index 0000000000..8ca6044fd1 --- /dev/null +++ b/modules/base/shaders/deltaS_sup_calc_gs.glsl @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform int layer; + +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; + +void main() +{ + int n; + for (n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/modules/base/shaders/deltaS_sup_calc_vs.glsl b/modules/base/shaders/deltaS_sup_calc_vs.glsl new file mode 100644 index 0000000000..7e3574bd9d --- /dev/null +++ b/modules/base/shaders/deltaS_sup_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/hdr.glsl b/modules/base/shaders/hdr.glsl new file mode 100644 index 0000000000..4435f301b5 --- /dev/null +++ b/modules/base/shaders/hdr.glsl @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +uniform float exposure; + +vec4 HDR(vec4 color) { + color *= exposure; + + color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.r); + color.g = color.g < 1.413 ? pow(color.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.g); + color.b = color.b < 1.413 ? pow(color.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.b); + + return color; +} diff --git a/modules/base/shaders/inScattering_calc_fs.glsl b/modules/base/shaders/inScattering_calc_fs.glsl new file mode 100644 index 0000000000..5144c92bce --- /dev/null +++ b/modules/base/shaders/inScattering_calc_fs.glsl @@ -0,0 +1,154 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTarget1; +layout(location = 2) out vec4 renderTarget2; + +uniform float r; +uniform vec4 dhdH; + +uniform sampler2D transmittanceTexture; + +// In the following shaders r (altitude) is the length of vector/position x in the +// atmosphere (or on the top of it when considering an observer in space), +// where the light is comming from the opposity direction of the view direction, +// here the vector v or viewDirection. +// Rg is the planet radius + +void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) { + float x = gl_FragCoord.x - 0.5; + float y = gl_FragCoord.y - 0.5; + if (y < float(RES_MU) / 2.0) { + float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); + mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); + mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); + } else { + float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); + mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); + } + mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); + mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); + nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; +} + +vec3 transmittanceFromTexture(const float r, const float mu) { + float u_r = sqrt((r - Rg) / (Rt - Rg)); + // See Colliene to understand the different mapping. + float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + + return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; +} + +vec3 transmittance(const float r, const float mu, float d) { + vec3 result; + float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); + float mu1 = (r * mu + d) / r1; + if (mu > 0.0) { + result = min(transmittanceFromTexture(r, mu) / + transmittanceFromTexture(r1, mu1), 1.0); + } else { + result = min(transmittanceFromTexture(r1, -mu1) / + transmittanceFromTexture(r, -mu), 1.0); + } + return result; +} + +void integrand(const float r, const float mu, const float muS, const float nu, + const float t, out vec3 ray, out vec3 mie) { + ray = vec3(0.0); + mie = vec3(0.0); + float ri = sqrt(r * r + t * t + 2.0 * r * mu * t); + float muSi = (nu * t + muS * r) / ri; + ri = max(Rg, ri); + if (muSi >= -sqrt(1.0 - Rg * Rg / (ri * ri))) { + vec3 ti = transmittance(r, mu, t) * transmittanceFromTexture(ri, muSi); + ray = exp(-(ri - Rg) / HR) * ti; + mie = exp(-(ri - Rg) / HM) * ti; + } +} + +float rayDistance(const float r, const float mu) { + // cosine law + float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) + + (Rt + ATM_EPSILON)*(Rt + ATM_EPSILON)); + float distance = distanceAtmosphereIntersect; + float delta = r * r * (mu * mu - 1.0) + Rg * Rg; + // No imaginary numbers... :-) + if (delta >= 0.0) { + float distanceEarthIntersect = -r * mu - sqrt(delta); + if (distanceEarthIntersect >= 0.0) { + distance = min(distanceAtmosphereIntersect, distanceEarthIntersect); + } + } + return distance; +} + +void inscatter(float r, float mu, float muS, float nu, out vec3 ray, out vec3 mie) { + // Integrating using the Trapezoidal rule: + // Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i))) + ray = vec3(0.0); + mie = vec3(0.0); + float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); + float xi = 0.0; + vec3 rayi; + vec3 miei; + integrand(r, mu, muS, nu, 0.0, rayi, miei); + for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { + float xj = float(i) * dx; + vec3 rayj; + vec3 miej; + integrand(r, mu, muS, nu, xj, rayj, miej); + ray += (rayi + rayj) / 2.0 * dx; + mie += (miei + miej) / 2.0 * dx; + xi = xj; + rayi = rayj; + miei = miej; + } + ray *= betaR; + mie *= betaMSca; +} + +Fragment getFragment() { + vec3 ray; + vec3 mie; + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + inscatter(r, mu, muS, nu, ray, mie); + // store separately Rayleigh and Mie contributions, WITHOUT the phase function factor + // (cf "Angular precision") + renderTarget1 = vec4(ray, 1.0); + renderTarget2 = vec4(mie, 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_calc_gs.glsl b/modules/base/shaders/inScattering_calc_gs.glsl new file mode 100644 index 0000000000..aed3744bd2 --- /dev/null +++ b/modules/base/shaders/inScattering_calc_gs.glsl @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform int layer; + +layout (triangles) in; +layout (triangle_strip, max_vertices=3) out; + +void main() +{ + int n; + for (n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_calc_vs.glsl b/modules/base/shaders/inScattering_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/inScattering_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_sup_calc_fs.glsl b/modules/base/shaders/inScattering_sup_calc_fs.glsl new file mode 100644 index 0000000000..71f5943c04 --- /dev/null +++ b/modules/base/shaders/inScattering_sup_calc_fs.glsl @@ -0,0 +1,155 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTarget1; + +uniform float r; +uniform vec4 dhdH; + +uniform sampler2D transmittanceTexture; +uniform sampler3D deltaJTexture; + +void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) { + float x = gl_FragCoord.x - 0.5; + float y = gl_FragCoord.y - 0.5; + if (y < float(RES_MU) / 2.0) { + float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999); + mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d); + mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001); + } else { + float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0); + d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999); + mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d); + } + mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0); + mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1); + nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0; +} + +vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu) +{ + float H = sqrt(Rt * Rt - Rg * Rg); + float rho = sqrt(r * r - Rg * Rg); + float rmu = r * mu; + float delta = rmu * rmu - r * r + Rg * Rg; + vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); + float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); + float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); + float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); + float uNu = floor(lerp); + lerp = lerp - uNu; + return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + + texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; +} + +float limit(float r, float mu) { + float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + ((Rt+ATM_EPSILON) * (Rt+ATM_EPSILON))); + float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg; + if (delta2 >= 0.0) { + float din = -r * mu - sqrt(delta2); + if (din >= 0.0) { + dout = min(dout, din); + } + } + return dout; +} + +vec3 transmittanceFromTexture(const float r, const float mu) { + float u_r = sqrt((r - Rg) / (Rt - Rg)); + // See Colliene to understand the different mapping. + float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + + return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; +} + +vec3 transmittance(const float r, const float mu, const float d) { + vec3 result; + float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d); + float mu1 = (r * mu + d) / r1; + if (mu > 0.0) { + result = min(transmittanceFromTexture(r, mu) / + transmittanceFromTexture(r1, mu1), 1.0); + } else { + result = min(transmittanceFromTexture(r1, -mu1) / + transmittanceFromTexture(r, -mu), 1.0); + } + return result; +} + +vec3 integrand(float r, float mu, float muS, float nu, float t) { + float ri = sqrt(r * r + t * t + 2.0 * r * mu * t); + float mui = (r * mu + t) / ri; + float muSi = (nu * t + muS * r) / ri; + return texture4D(deltaJTexture, ri, mui, muSi, nu).rgb * transmittance(r, mu, t); +} + +float rayDistance(const float r, const float mu) { + // cosine law + float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) + + (Rt + ATM_EPSILON)*(Rt + ATM_EPSILON)); + float distance = distanceAtmosphereIntersect; + float delta = r * r * (mu * mu - 1.0) + Rg * Rg; + // No imaginary numbers... :-) + if (delta >= 0.0) { + float distanceEarthIntersect = -r * mu - sqrt(delta); + if (distanceEarthIntersect >= 0.0) { + distance = min(distanceAtmosphereIntersect, distanceEarthIntersect); + } + } + return distance; +} + +vec3 inscatter(float r, float mu, float muS, float nu) { + vec3 raymie = vec3(0.0); + float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES); + float xi = 0.0; + vec3 raymiei = integrand(r, mu, muS, nu, 0.0); + for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) { + float xj = float(i) * dx; + vec3 raymiej = integrand(r, mu, muS, nu, xj); + raymie += (raymiei + raymiej) / 2.0 * dx; + xi = xj; + raymiei = raymiej; + } + return raymie; +} + +Fragment getFragment() { + float mu, muS, nu; + getMuMuSNu(r, dhdH, mu, muS, nu); + + renderTarget1 = vec4(inscatter(r, mu, muS, nu), 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_sup_calc_gs.glsl b/modules/base/shaders/inScattering_sup_calc_gs.glsl new file mode 100644 index 0000000000..8ca6044fd1 --- /dev/null +++ b/modules/base/shaders/inScattering_sup_calc_gs.glsl @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +uniform int layer; + +layout (triangles) in; +layout (triangle_strip, max_vertices = 3) out; + +void main() +{ + int n; + for (n = 0; n < gl_in.length(); ++n) { + gl_Position = gl_in[n].gl_Position; + gl_Layer = layer; + EmitVertex(); + } + EndPrimitive(); +} \ No newline at end of file diff --git a/modules/base/shaders/inScattering_sup_calc_vs.glsl b/modules/base/shaders/inScattering_sup_calc_vs.glsl new file mode 100644 index 0000000000..7e3574bd9d --- /dev/null +++ b/modules/base/shaders/inScattering_sup_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/irradiance_calc_fs.glsl b/modules/base/shaders/irradiance_calc_fs.glsl new file mode 100644 index 0000000000..63cd9c238d --- /dev/null +++ b/modules/base/shaders/irradiance_calc_fs.glsl @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTableColor; + +uniform sampler2D transmittanceTexture; + +void getRAndMu(out float r, out float mu) { + // See Bruneton and Colliene to understand the mapping. + mu = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES_W) - 1.0) * (1.0 + 0.2); + r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES_H) - 1.0) * (Rt - Rg); +} + +vec3 transmittance(const float r, const float mu) { + float u_r = sqrt((r - Rg) / (Rt - Rg)); + // See Colliene to understand the different mapping. + float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; + + return texture2D(transmittanceTexture, vec2(u_mu, u_r)).rgb; +} + +Fragment getFragment() { + float mu, r; + getRAndMu(r, mu); + renderTableColor = vec4(transmittance(r, mu) * max(mu, 0.0), 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/irradiance_calc_vs.glsl b/modules/base/shaders/irradiance_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/irradiance_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/irradiance_sup_calc_fs.glsl b/modules/base/shaders/irradiance_sup_calc_fs.glsl new file mode 100644 index 0000000000..dceedff870 --- /dev/null +++ b/modules/base/shaders/irradiance_sup_calc_fs.glsl @@ -0,0 +1,101 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTableColor; + +uniform float first; + +const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); +const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES); + +uniform sampler2D transmittanceTexture; +uniform sampler3D deltaSRTexture; +uniform sampler3D deltaSMTexture; + +// Rayleigh phase +float phaseFunctionR(const float mu) { + return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu); +} + +// Mie phase +float phaseFunctionM(const float mu) { + return (3.0 / (8.0 * M_PI)) * + ( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) / + ( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) ); +} + +vec4 texture4D(sampler3D table, const float r, const float mu, + const float muS, const float nu) +{ + float H = sqrt(Rt * Rt - Rg * Rg); + float rho = sqrt(r * r - Rg * Rg); + float rmu = r * mu; + float delta = rmu * rmu - r * r + Rg * Rg; + vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU)); + float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R)); + float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU)); + float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S)); + float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0); + float uNu = floor(lerp); + lerp = lerp - uNu; + return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) + + texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp; +} + +Fragment getFragment() { + float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY_H) - 1.0) * (Rt - Rg); + float mu_s = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY_W) - 1.0) * (1.0 + 0.2); + vec3 s = vec3(max(sqrt(1.0 - mu_s * mu_s), 0.0), 0.0, mu_s); + + vec3 result = vec3(0.0); + for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) { + float phi = (float(iphi) + 0.5) * dphi; + for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) { + float theta = (float(itheta) + 0.5) * dtheta; + float dw = dtheta * dphi * sin(theta); + vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta)); + float nu = dot(s, w); + if (first == 1.0) { + float pr1 = phaseFunctionR(nu); + float pm1 = phaseFunctionM(nu); + vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb; + vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu).rgb; + result += (ray1 * pr1 + mie1 * pm1) * w.z * dw; + } else { + result += texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb * w.z * dw; + } + } + } + + renderTableColor = vec4(result, 0.0); + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/irradiance_sup_calc_vs.glsl b/modules/base/shaders/irradiance_sup_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/irradiance_sup_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/modules/base/shaders/transmittance_calc_fs.glsl b/modules/base/shaders/transmittance_calc_fs.glsl new file mode 100644 index 0000000000..7270a1d1f2 --- /dev/null +++ b/modules/base/shaders/transmittance_calc_fs.glsl @@ -0,0 +1,109 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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. * + ****************************************************************************************/ + +#include "atmosphere_common.glsl" +#include "fragment.glsl" +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 1) out vec4 renderTableColor; + +// In the following shaders r (altitude) is the length of vector/position x in the +// atmosphere (or on the top of it when considering an observer in space), +// where the light is comming from the opposity direction of the view direction, +// here the vector v or viewDirection. +// Rg is the planet radius + +float rayDistance(const float r, const float mu) { + // cosine law + float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) + + (Rt + ATM_EPSILON)*(Rt + ATM_EPSILON)); + float distance = distanceAtmosphereIntersect; + float delta = r * r * (mu * mu - 1.0) + Rg * Rg; + // No imaginary numbers... :-) + if (delta >= 0.0) { + float distanceEarthIntersect = -r * mu - sqrt(delta); + if (distanceEarthIntersect >= 0.0) { + distance = min(distanceAtmosphereIntersect, distanceEarthIntersect); + } + } + return distance; +} + +float opticalDepth(const float r, const float mu, const float scaleHeight) { + + float r2 = r*r; + // Is ray below horizon? + // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) + float cosZenithHorizon = -sqrt(1.0 - ((Rg*Rg)/r2)); + if (mu < cosZenithHorizon) + return 1e9; + + // Integrating using the Trapezoidal rule: + // Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i))) + float b_a = rayDistance(r, mu); + float deltaStep = b_a / float(TRANSMITTANCE_STEPS); + // cosine law + float y_i = exp(-(r - Rg) / scaleHeight); + + float x_step = 0.0; + float accumulation = 0.0; + for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) { + float x_i = float(i) * deltaStep; + // cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha) + // In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu + float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / scaleHeight); + accumulation += (y_ii + y_i); + //x_step = x_i; + y_i = y_ii; + } + return accumulation * (b_a/(2*TRANSMITTANCE_STEPS)); +} + +void getRandMU(out float r, out float mu) { + float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W); + float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H); + + // In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2) + r = sqrt(Rg*Rg + (u_r * u_r) * (Rt*Rt - Rg*Rg)); + + // In the paper the author suggest mu = dot(v,x)/||x|| with ||v|| = 1.0 + // Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6)) + // But the below one is better. See Colliene. + mu = -0.15 + tan(1.5 * u_mu) / tan(1.5) * (1.0 + 0.15); +} + +Fragment getFragment() { + float r, mu; + + getRandMU(r, mu); + vec3 depth = betaMEx * opticalDepth(r, mu, HM) + betaR * opticalDepth(r, mu, HR); + + renderTableColor = vec4(exp(-depth), 1.0); + + Fragment frag; + frag.color = vec4(1.0); + frag.depth = 1.0; + + return frag; +} \ No newline at end of file diff --git a/modules/base/shaders/transmittance_calc_vs.glsl b/modules/base/shaders/transmittance_calc_vs.glsl new file mode 100644 index 0000000000..578d7ab02f --- /dev/null +++ b/modules/base/shaders/transmittance_calc_vs.glsl @@ -0,0 +1,31 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec3 in_position; + +void main() { + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/openspace.cfg b/openspace.cfg index ccd19f6218..d5af8889e2 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -53,7 +53,7 @@ return { File = "${BASE_PATH}/Properties.txt" }, DownloadRequestURL = "http://openspace.itn.liu.se/request.cgi", - --RenderingMethod = "Framebuffer" + RenderingMethod = "Framebuffer" --RenderingMethod = "ABuffer" -- alternative: "Framebuffer" } \ No newline at end of file From f0b76267c402461aaaf641914c3d0d4f11e4c55d Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 7 Jun 2016 10:49:26 -0400 Subject: [PATCH 06/17] Added night texture. --- modules/base/shaders/atmosphere_fs.glsl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/base/shaders/atmosphere_fs.glsl b/modules/base/shaders/atmosphere_fs.glsl index be2c97ab5f..68b20b5779 100644 --- a/modules/base/shaders/atmosphere_fs.glsl +++ b/modules/base/shaders/atmosphere_fs.glsl @@ -68,11 +68,6 @@ uniform sampler2D transmittanceTexture; uniform sampler2D irradianceTexture; uniform sampler3D inscatterTexture; -// TODO: Remove from there! -// the transmittance sampler is in scatteringinclude.glsl - -//layout(origin_upper_left) in vec4 gl_FragCoord; - in vec2 vs_st; in vec2 vs_nightTex; in vec4 vs_normal; @@ -421,8 +416,8 @@ Fragment getFragment() { //diffuse = HDR(vec4(groundColor, 1.0)); //diffuse = HDR(vec4(inscatterColor, 1.0)); - //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2 + clouds); - diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) * + //diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2); + diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) * calcShadow(shadowDataArray, vs_posWorld.xyz) ); } // else From dd51c71fb17b1978c0d4680cd1ec0feb64696825 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 7 Jun 2016 13:51:28 -0400 Subject: [PATCH 07/17] Fixed bug in shader that was crashing OS in MacOSX. --- modules/base/rendering/renderableplanet.cpp | 40 ++++++++++---------- modules/base/shaders/irradiance_calc_fs.glsl | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index c7f0cecbb1..134e5d3795 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -769,14 +769,14 @@ void RenderablePlanet::render(const RenderData& data) // Atmosphere Data if (_atmosphereEnabled) { - GLenum err; - while ((err = glGetError()) != GL_NO_ERROR) { - const GLubyte * errorString = gluErrorString(err); - std::stringstream ss; - ss << "Error setting up atmosphere framebuffer. OpenGL error: " - << err << " - " << errorString << std::endl; - LERROR(ss.str()); - } +// GLenum err; +// while ((err = glGetError()) != GL_NO_ERROR) { +// const GLubyte * errorString = gluErrorString(err); +// std::stringstream ss; +// ss << "Error setting up atmosphere framebuffer. OpenGL error: " +// << err << " - " << errorString << std::endl; +// LERROR(ss.str()); +// } // Object Space (in Km) glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3() / 1000.0f); @@ -1156,12 +1156,12 @@ void RenderablePlanet::loadTexture() { } } - while ((err = glGetError()) != GL_NO_ERROR) { - const GLubyte * errString = gluErrorString(err); - std::stringstream ss; - ss << "Error after reading memory 4. OpenGL error: " << errString << std::endl; - LERROR(ss.str()); - } +// while ((err = glGetError()) != GL_NO_ERROR) { +// const GLubyte * errString = gluErrorString(err); +// std::stringstream ss; +// ss << "Error after reading memory 4. OpenGL error: " << errString << std::endl; +// LERROR(ss.str()); +// } if (_hasCloudsTexture) { _cloudsTexture = nullptr; @@ -1176,12 +1176,12 @@ void RenderablePlanet::loadTexture() { } } - while ((err = glGetError()) != GL_NO_ERROR) { - const GLubyte * errString = gluErrorString(err); - std::stringstream ss; - ss << "Error after reading memory 5. OpenGL error: " << errString << std::endl; - LERROR(ss.str()); - } +// while ((err = glGetError()) != GL_NO_ERROR) { +// const GLubyte * errString = gluErrorString(err); +// std::stringstream ss; +// ss << "Error after reading memory 5. OpenGL error: " << errString << std::endl; +// LERROR(ss.str()); +// } } void RenderablePlanet::loadComputationPrograms() { diff --git a/modules/base/shaders/irradiance_calc_fs.glsl b/modules/base/shaders/irradiance_calc_fs.glsl index 63cd9c238d..62d0a2122c 100644 --- a/modules/base/shaders/irradiance_calc_fs.glsl +++ b/modules/base/shaders/irradiance_calc_fs.glsl @@ -41,7 +41,7 @@ vec3 transmittance(const float r, const float mu) { // See Colliene to understand the different mapping. float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5; - return texture2D(transmittanceTexture, vec2(u_mu, u_r)).rgb; + return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb; } Fragment getFragment() { From 649aa879f26da4fecbade8e065b393631420eff4 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 9 Jun 2016 09:18:08 -0400 Subject: [PATCH 08/17] New textures for earth with atmosphere. --- data/scene/earth/earth.data | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/scene/earth/earth.data b/data/scene/earth/earth.data index 240c1d5212..e168d4c8be 100644 --- a/data/scene/earth/earth.data +++ b/data/scene/earth/earth.data @@ -1,5 +1,5 @@ return { FileRequest = { - { Identifier = "earth_textures", Destination = "textures", Version = 1 } + { Identifier = "earth_textures", Destination = "textures", Version = 2 } }, -} \ No newline at end of file +} From bc19a826bfb07bc0fb14fcfd7940c2572c99d0b0 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 9 Jun 2016 12:44:16 -0400 Subject: [PATCH 09/17] Factor out tile texture sampling --- .../globebrowsing/shaders/texturetile.hglsl | 14 ++ .../shaders/texturetilemapping.hglsl | 155 +++--------------- 2 files changed, 33 insertions(+), 136 deletions(-) diff --git a/modules/globebrowsing/shaders/texturetile.hglsl b/modules/globebrowsing/shaders/texturetile.hglsl index 38ef1b8eb4..970bec3896 100644 --- a/modules/globebrowsing/shaders/texturetile.hglsl +++ b/modules/globebrowsing/shaders/texturetile.hglsl @@ -50,4 +50,18 @@ vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) { return vec4(color, 0); } +vec4 getTexVal(const TextureTile tile, const vec2 tileUV){ + vec2 samplePos = tile.uvTransform.uvOffset + tile.uvTransform.uvScale * tileUV; + vec4 texVal = texture(tile.textureSampler, samplePos); + return texVal; +} + +vec4 getTransformedTexVal(const TileDepthTransform transform, const vec4 val){ + return transform.depthOffset + transform.depthScale * val; +} + +float getTransformedTexVal(const TileDepthTransform transform, const float val){ + return transform.depthOffset + transform.depthScale * val; +} + #endif // TEXTURETILE_HGLSL \ No newline at end of file diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index e48f97b5a6..087faf161b 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -121,38 +121,13 @@ float calculateHeight( #for i in 0..#{lastLayerIndexHeight} { - vec2 samplePos = - heightTiles[#{i}].uvTransform.uvScale * uv + - heightTiles[#{i}].uvTransform.uvOffset; - vec2 samplePosParent1 = - heightTilesParent1[#{i}].uvTransform.uvScale * uv + - heightTilesParent1[#{i}].uvTransform.uvOffset; - vec2 samplePosParent2 = - heightTilesParent2[#{i}].uvTransform.uvScale * uv + - heightTilesParent2[#{i}].uvTransform.uvOffset; + float untransformedHeight = + w1 * getTexVal(heightTiles[#{i}], uv).r + + w2 * getTexVal(heightTilesParent1[#{i}], uv).r + + w3 * getTexVal(heightTilesParent2[#{i}], uv).r; - /* - float sampledValue = - w1 * textureLod(heightTiles[#{i}].textureSampler, samplePos, 0).r + - w2 * textureLod(heightTilesParent1[#{i}].textureSampler, samplePosParent1, 0).r + - w3 * textureLod(heightTilesParent2[#{i}].textureSampler, samplePosParent2, 0).r; - */ - /* - float sampledValue = - w1 * textureGrad(heightTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)).r + - w2 * textureGrad(heightTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)).r + - w3 * textureGrad(heightTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0)).r; - */ - - float sampledValue = - w1 * texture(heightTiles[#{i}].textureSampler, samplePos).r + - w2 * texture(heightTilesParent1[#{i}].textureSampler, samplePosParent1).r + - w3 * texture(heightTilesParent2[#{i}].textureSampler, samplePosParent2).r; - - // TODO : Some kind of blending here. Now it just writes over - height = (sampledValue * - heightTiles[#{i}].depthTransform.depthScale + - heightTiles[#{i}].depthTransform.depthOffset); + // OBS! Only the values from the last height map will be used! + height = getTransformedTexVal(heightTiles[#{i}].depthTransform, untransformedHeight); } #endfor @@ -182,33 +157,10 @@ vec4 calculateColor( #for i in 0..#{lastLayerIndexColor} { - vec2 samplePos = - colorTiles[#{i}].uvTransform.uvScale * uv + - colorTiles[#{i}].uvTransform.uvOffset; - vec2 samplePosParent1 = - colorTilesParent1[#{i}].uvTransform.uvScale * uv + - colorTilesParent1[#{i}].uvTransform.uvOffset; - vec2 samplePosParent2 = - colorTilesParent2[#{i}].uvTransform.uvScale * uv + - colorTilesParent2[#{i}].uvTransform.uvOffset; - - /* - vec4 colorSample = - w1 * textureLod(colorTiles[#{i}].textureSampler, samplePos, 0) + - w2 * textureLod(colorTilesParent1[#{i}].textureSampler, samplePosParent1, 0) + - w3 * textureLod(colorTilesParent2[#{i}].textureSampler, samplePosParent2, 0); - */ - /* - vec4 colorSample = - w1 * textureGrad(colorTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) + - w2 * textureGrad(colorTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) + - w3 * textureGrad(colorTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0)); - */ - - vec4 colorSample = - w1 * texture(colorTiles[#{i}].textureSampler, samplePos) + - w2 * texture(colorTilesParent1[#{i}].textureSampler, samplePosParent1) + - w3 * texture(colorTilesParent2[#{i}].textureSampler, samplePosParent2); + vec4 colorSample = + w1 * getTexVal(colorTiles[#{i}], uv) + + w2 * getTexVal(colorTilesParent1[#{i}], uv) + + w3 * getTexVal(colorTilesParent2[#{i}], uv); color = blendOver(color, colorSample); } @@ -245,33 +197,10 @@ vec4 calculateNight( #for i in 0..#{lastLayerIndexNight} { - vec2 samplePos = - nightTiles[#{i}].uvTransform.uvScale * uv + - nightTiles[#{i}].uvTransform.uvOffset; - vec2 samplePosParent1 = - nightTilesParent1[#{i}].uvTransform.uvScale * uv + - nightTilesParent1[#{i}].uvTransform.uvOffset; - vec2 samplePosParent2 = - nightTilesParent2[#{i}].uvTransform.uvScale * uv + - nightTilesParent2[#{i}].uvTransform.uvOffset; - - /* vec4 colorSample = - w1 * textureLod(nightTiles[#{i}].textureSampler, samplePos, 0) + - w2 * textureLod(nightTilesParent1[#{i}].textureSampler, samplePosParent1, 0) + - w3 * textureLod(nightTilesParent2[#{i}].textureSampler, samplePosParent2, 0); - */ - /* - vec4 colorSample = - w1 * textureGrad(nightTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) + - w2 * textureGrad(nightTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) + - w3 * textureGrad(nightTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0)); - */ - - vec4 colorSample = - w1 * texture(nightTiles[#{i}].textureSampler, samplePos) + - w2 * texture(nightTilesParent1[#{i}].textureSampler, samplePosParent1) + - w3 * texture(nightTilesParent2[#{i}].textureSampler, samplePosParent2); + w1 * getTexVal(nightTiles[#{i}], uv) + + w2 * getTexVal(nightTilesParent1[#{i}], uv) + + w3 * getTexVal(nightTilesParent2[#{i}], uv); nightColor = blendOver(nightColor, colorSample); } @@ -307,33 +236,10 @@ vec4 calculateOverlay( #for i in 0..#{lastLayerIndexOverlay} { - vec2 samplePos = - overlayTiles[#{i}].uvTransform.uvScale * uv + - overlayTiles[#{i}].uvTransform.uvOffset; - vec2 samplePosParent1 = - overlayTilesParent1[#{i}].uvTransform.uvScale * uv + - overlayTilesParent1[#{i}].uvTransform.uvOffset; - vec2 samplePosParent2 = - overlayTilesParent2[#{i}].uvTransform.uvScale * uv + - overlayTilesParent2[#{i}].uvTransform.uvOffset; - - /* vec4 colorSample = - w1 * textureLod(overlayTiles[#{i}].textureSampler, samplePos, 0) + - w2 * textureLod(overlayTilesParent1[#{i}].textureSampler, samplePosParent1, 0) + - w3 * textureLod(overlayTilesParent2[#{i}].textureSampler, samplePosParent2, 0); - */ - /* - vec4 colorSample = - w1 * textureGrad(overlayTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) + - w2 * textureGrad(overlayTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) + - w3 * textureGrad(overlayTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0)); - */ - - vec4 colorSample = - w1 * texture(overlayTiles[#{i}].textureSampler, samplePos) + - w2 * texture(overlayTilesParent1[#{i}].textureSampler, samplePosParent1) + - w3 * texture(overlayTilesParent2[#{i}].textureSampler, samplePosParent2); + w1 * getTexVal(overlayTiles[#{i}], uv) + + w2 * getTexVal(overlayTilesParent1[#{i}], uv) + + w3 * getTexVal(overlayTilesParent2[#{i}], uv); color = blendOver(color, colorSample); } @@ -366,33 +272,10 @@ vec4 calculateWater( #for i in 0..#{lastLayerIndexWater} { - vec2 samplePos = - waterTiles[#{i}].uvTransform.uvScale * uv + - waterTiles[#{i}].uvTransform.uvOffset; - vec2 samplePosParent1 = - waterTilesParent1[#{i}].uvTransform.uvScale * uv + - waterTilesParent1[#{i}].uvTransform.uvOffset; - vec2 samplePosParent2 = - waterTilesParent2[#{i}].uvTransform.uvScale * uv + - waterTilesParent2[#{i}].uvTransform.uvOffset; - - /* vec4 colorSample = - w1 * textureLod(waterTiles[#{i}].textureSampler, samplePos, 0) + - w2 * textureLod(waterTilesParent1[#{i}].textureSampler, samplePosParent1, 0) + - w3 * textureLod(waterTilesParent2[#{i}].textureSampler, samplePosParent2, 0); - */ - /* - vec4 colorSample = - w1 * textureGrad(waterTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) + - w2 * textureGrad(waterTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) + - w3 * textureGrad(waterTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0)); - */ - - vec4 colorSample = - w1 * texture(waterTiles[#{i}].textureSampler, samplePos) + - w2 * texture(waterTilesParent1[#{i}].textureSampler, samplePosParent1) + - w3 * texture(waterTilesParent2[#{i}].textureSampler, samplePosParent2); + w1 * getTexVal(waterTiles[#{i}], uv) + + w2 * getTexVal(waterTilesParent1[#{i}], uv) + + w3 * getTexVal(waterTilesParent2[#{i}], uv); waterColor = blendOver(waterColor, colorSample); } From 7ac8e37807a47cbee8ce080192e968388a7d93b1 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 9 Jun 2016 13:22:44 -0400 Subject: [PATCH 10/17] Rename TextureTile to Tile in shader for better correspondance with its CPU counterpart --- .../shaders/globalchunkedlodpatch_fs.glsl | 26 +++++++-------- .../shaders/globalchunkedlodpatch_vs.glsl | 8 ++--- .../shaders/localchunkedlodpatch_fs.glsl | 26 +++++++-------- .../shaders/localchunkedlodpatch_vs.glsl | 8 ++--- .../shaders/texturetilemapping.hglsl | 32 +++++++++---------- .../shaders/{texturetile.hglsl => tile.hglsl} | 4 +-- 6 files changed, 52 insertions(+), 52 deletions(-) rename modules/globebrowsing/shaders/{texturetile.hglsl => tile.hglsl} (97%) diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index f43126de13..7ed4aadf36 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -22,34 +22,34 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" #if USE_COLORTEXTURE -uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; -uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; -uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTiles[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; #endif // USE_COLORTEXTURE #if USE_NIGHTTEXTURE -uniform TextureTile nightTiles[NUMLAYERS_NIGHTTEXTURE]; -uniform TextureTile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE]; -uniform TextureTile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTiles[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE]; #endif // USE_NIGHTTEXTURE #if USE_OVERLAY -uniform TextureTile overlayTiles[NUMLAYERS_OVERLAY]; -uniform TextureTile overlayTilesParent1[NUMLAYERS_OVERLAY]; -uniform TextureTile overlayTilesParent2[NUMLAYERS_OVERLAY]; +uniform Tile overlayTiles[NUMLAYERS_OVERLAY]; +uniform Tile overlayTilesParent1[NUMLAYERS_OVERLAY]; +uniform Tile overlayTilesParent2[NUMLAYERS_OVERLAY]; #endif // USE_OVERLAY #if USE_WATERMASK -uniform TextureTile waterTiles[NUMLAYERS_WATERMASK]; -uniform TextureTile waterTilesParent1[NUMLAYERS_WATERMASK]; -uniform TextureTile waterTilesParent2[NUMLAYERS_WATERMASK]; +uniform Tile waterTiles[NUMLAYERS_WATERMASK]; +uniform Tile waterTilesParent1[NUMLAYERS_WATERMASK]; +uniform Tile waterTilesParent2[NUMLAYERS_WATERMASK]; #endif // USE_WATERMASK #if USE_ATMOSPHERE diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index 977361cf63..b05416e099 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -26,7 +26,7 @@ #include "PowerScaling/powerScaling_vs.hglsl" #include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> uniform mat4 modelViewProjectionTransform; @@ -40,9 +40,9 @@ uniform int xSegments; uniform float skirtLength; #if USE_HEIGHTMAP -uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; -uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; -uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTiles[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; #endif // USE_HEIGHTMAP uniform vec3 cameraPosition; diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 01694a9a26..a4dae58f88 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -22,33 +22,33 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" #if USE_COLORTEXTURE -uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; -uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; -uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTiles[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; +uniform Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; #endif // USE_COLORTEXTURE #if USE_NIGHTTEXTURE -uniform TextureTile nightTiles[NUMLAYERS_NIGHTTEXTURE]; -uniform TextureTile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE]; -uniform TextureTile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTiles[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE]; +uniform Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE]; #endif // USE_NIGHTTEXTURE #if USE_OVERLAY -uniform TextureTile overlayTiles[NUMLAYERS_OVERLAY]; -uniform TextureTile overlayTilesParent1[NUMLAYERS_OVERLAY]; -uniform TextureTile overlayTilesParent2[NUMLAYERS_OVERLAY]; +uniform Tile overlayTiles[NUMLAYERS_OVERLAY]; +uniform Tile overlayTilesParent1[NUMLAYERS_OVERLAY]; +uniform Tile overlayTilesParent2[NUMLAYERS_OVERLAY]; #endif // USE_OVERLAY #if USE_WATERMASK -uniform TextureTile waterTiles[NUMLAYERS_WATERMASK]; -uniform TextureTile waterTilesParent1[NUMLAYERS_WATERMASK]; -uniform TextureTile waterTilesParent2[NUMLAYERS_WATERMASK]; +uniform Tile waterTiles[NUMLAYERS_WATERMASK]; +uniform Tile waterTilesParent1[NUMLAYERS_WATERMASK]; +uniform Tile waterTilesParent2[NUMLAYERS_WATERMASK]; #endif // USE_WATERMASK // tileInterpolationParameter is used to interpolate between a tile and its parent tiles diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 8312f2abde..8a69f69e79 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -26,7 +26,7 @@ #include "PowerScaling/powerScaling_vs.hglsl" #include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> -#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl> #define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColor} + 1 @@ -42,9 +42,9 @@ uniform vec3 p11; uniform vec3 patchNormalCameraSpace; #if USE_HEIGHTMAP -uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; -uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; -uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTiles[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; +uniform Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; #endif // USE_HEIGHTMAP uniform int xSegments; diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index 087faf161b..db1f68d42e 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -25,7 +25,7 @@ #ifndef TEXTURETILEMAPPING_HGLSL #define TEXTURETILEMAPPING_HGLSL -#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl> // First layer type from LayeredTextureShaderProvider is height map @@ -101,9 +101,9 @@ float calculateHeight( const vec2 uv, const float tileInterpolationParameter, - const TextureTile heightTiles[NUMLAYERS_HEIGHTMAP], - const TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP], - const TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP]) { + const Tile heightTiles[NUMLAYERS_HEIGHTMAP], + const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP], + const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]) { float height = 0; @@ -137,9 +137,9 @@ float calculateHeight( vec4 calculateColor( const vec2 uv, const float tileInterpolationParameter, - const TextureTile colorTiles[NUMLAYERS_COLORTEXTURE], - const TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE], - const TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE]) { + const Tile colorTiles[NUMLAYERS_COLORTEXTURE], + const Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE], + const Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE]) { vec4 color = vec4(0); @@ -173,9 +173,9 @@ vec4 calculateNight( const vec4 currentColor, const vec2 uv, const float tileInterpolationParameter, - const TextureTile nightTiles[NUMLAYERS_NIGHTTEXTURE], - const TextureTile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE], - const TextureTile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE], + const Tile nightTiles[NUMLAYERS_NIGHTTEXTURE], + const Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE], + const Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE], const vec3 ellipsoidNormalCameraSpace) { vec3 lightDirection = normalize(vec3(-1,-1,-1)); @@ -216,9 +216,9 @@ vec4 calculateOverlay( const vec4 currentColor, const vec2 uv, const float tileInterpolationParameter, - const TextureTile overlayTiles[NUMLAYERS_OVERLAY], - const TextureTile overlayTilesParent1[NUMLAYERS_OVERLAY], - const TextureTile overlayTilesParent2[NUMLAYERS_OVERLAY]) { + const Tile overlayTiles[NUMLAYERS_OVERLAY], + const Tile overlayTilesParent1[NUMLAYERS_OVERLAY], + const Tile overlayTilesParent2[NUMLAYERS_OVERLAY]) { vec4 color = currentColor; @@ -252,9 +252,9 @@ vec4 calculateWater( const vec4 currentColor, const vec2 uv, const float tileInterpolationParameter, - const TextureTile waterTiles[NUMLAYERS_WATERMASK], - const TextureTile waterTilesParent1[NUMLAYERS_WATERMASK], - const TextureTile waterTilesParent2[NUMLAYERS_WATERMASK]) { + const Tile waterTiles[NUMLAYERS_WATERMASK], + const Tile waterTilesParent1[NUMLAYERS_WATERMASK], + const Tile waterTilesParent2[NUMLAYERS_WATERMASK]) { vec4 waterColor = vec4(0,0,0,0); diff --git a/modules/globebrowsing/shaders/texturetile.hglsl b/modules/globebrowsing/shaders/tile.hglsl similarity index 97% rename from modules/globebrowsing/shaders/texturetile.hglsl rename to modules/globebrowsing/shaders/tile.hglsl index 970bec3896..129a48f256 100644 --- a/modules/globebrowsing/shaders/texturetile.hglsl +++ b/modules/globebrowsing/shaders/tile.hglsl @@ -35,7 +35,7 @@ struct TileUvTransform { vec2 uvScale; }; -struct TextureTile { +struct Tile { sampler2D textureSampler; TileDepthTransform depthTransform; @@ -50,7 +50,7 @@ vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) { return vec4(color, 0); } -vec4 getTexVal(const TextureTile tile, const vec2 tileUV){ +vec4 getTexVal(const Tile tile, const vec2 tileUV){ vec2 samplePos = tile.uvTransform.uvOffset + tile.uvTransform.uvScale * tileUV; vec4 texVal = texture(tile.textureSampler, samplePos); return texVal; From 25d02086a113c59d982b2c8b33338465a4650744 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 9 Jun 2016 14:18:39 -0400 Subject: [PATCH 11/17] Use separate function for getting level weights --- .../shaders/globalchunkedlodpatch_fs.glsl | 12 +-- .../shaders/globalchunkedlodpatch_vs.glsl | 8 +- .../shaders/localchunkedlodpatch_fs.glsl | 12 +-- .../shaders/localchunkedlodpatch_vs.glsl | 8 +- .../shaders/texturetilemapping.hglsl | 85 ++++++++----------- modules/globebrowsing/shaders/tile.hglsl | 23 +++++ 6 files changed, 79 insertions(+), 69 deletions(-) diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 7ed4aadf36..58fa26be17 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -60,18 +60,20 @@ in vec3 ellipsoidNormalCameraSpace; in vec4 fs_position; in vec2 fs_uv; -in float tileInterpolationParameter; +in float levelInterpolationParameter; Fragment getFragment() { Fragment frag; frag.color = vec4(0.1,0.1,0.1,1); + + #if USE_COLORTEXTURE frag.color = calculateColor( fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, colorTiles, colorTilesParent1, colorTilesParent2); @@ -83,7 +85,7 @@ Fragment getFragment() { frag.color = calculateWater( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, waterTiles, waterTilesParent1, waterTilesParent2); @@ -95,7 +97,7 @@ Fragment getFragment() { frag.color = calculateNight( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, nightTiles, nightTilesParent1, nightTilesParent2, @@ -112,7 +114,7 @@ Fragment getFragment() { frag.color = calculateOverlay( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, overlayTiles, overlayTilesParent1, overlayTilesParent2); diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index b05416e099..23f4cc5462 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -54,9 +54,9 @@ layout(location = 1) in vec2 in_uv; out vec2 fs_uv; out vec4 fs_position; out vec3 ellipsoidNormalCameraSpace; -// tileInterpolationParameter is used to interpolate between a tile and its parent tiles +// levelInterpolationParameter is used to interpolate between a tile and its parent tiles // The value increases with the distance from the vertex (or fragment) to the camera -out float tileInterpolationParameter; +out float levelInterpolationParameter; PositionNormalPair globalInterpolation() { vec2 lonLatInput; @@ -74,7 +74,7 @@ void main() float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; float desiredLevel = log2(projectedScaleFactor); - tileInterpolationParameter = chunkLevel - desiredLevel; + levelInterpolationParameter = chunkLevel - desiredLevel; float height = 0; @@ -84,7 +84,7 @@ void main() // Before any heightmapping is done height = calculateHeight( in_uv, - tileInterpolationParameter, // Variable to determine which texture to sample from + levelInterpolationParameter, // Variable to determine which texture to sample from heightTiles, heightTilesParent1, heightTilesParent2); // Three textures to sample from #endif // USE_HEIGHTMAP diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index a4dae58f88..0f7a19e962 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -51,9 +51,9 @@ uniform Tile waterTilesParent1[NUMLAYERS_WATERMASK]; uniform Tile waterTilesParent2[NUMLAYERS_WATERMASK]; #endif // USE_WATERMASK -// tileInterpolationParameter is used to interpolate between a tile and its parent tiles +// levelInterpolationParameter is used to interpolate between a tile and its parent tiles // The value increases with the distance from the vertex (or fragment) to the camera -in float tileInterpolationParameter; +in float levelInterpolationParameter; in vec4 fs_position; in vec2 fs_uv; @@ -68,7 +68,7 @@ Fragment getFragment() { frag.color = calculateColor( fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, colorTiles, colorTilesParent1, colorTilesParent2); @@ -81,7 +81,7 @@ Fragment getFragment() { frag.color = calculateWater( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, waterTiles, waterTilesParent1, waterTilesParent2); @@ -94,7 +94,7 @@ Fragment getFragment() { frag.color = calculateNight( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, nightTiles, nightTilesParent1, nightTilesParent2, @@ -111,7 +111,7 @@ Fragment getFragment() { frag.color = calculateOverlay( frag.color, fs_uv, - tileInterpolationParameter, + levelInterpolationParameter, overlayTiles, overlayTilesParent1, overlayTilesParent2); diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 8a69f69e79..a04f12ff29 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -59,9 +59,9 @@ out vec2 fs_uv; out vec4 fs_position; out vec3 ellipsoidNormalCameraSpace; -// tileInterpolationParameter is used to interpolate between a tile and its parent tiles +// levelInterpolationParameter is used to interpolate between a tile and its parent tiles // The value increases with the distance from the vertex (or fragment) to the camera -out float tileInterpolationParameter; +out float levelInterpolationParameter; vec3 bilinearInterpolation(vec2 uv) { // Bilinear interpolation @@ -84,7 +84,7 @@ void main() float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; float desiredLevel = log2(projectedScaleFactor); - tileInterpolationParameter = chunkLevel - desiredLevel; + levelInterpolationParameter = chunkLevel - desiredLevel; #if USE_HEIGHTMAP @@ -92,7 +92,7 @@ void main() // Before any heightmapping is done height = calculateHeight( in_uv, - tileInterpolationParameter, // Variable to determine which texture to sample from + levelInterpolationParameter, // Variable to determine which texture to sample from heightTiles, heightTilesParent1, heightTilesParent2); // Three textures to sample from #endif // USE_HEIGHTMAP diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index db1f68d42e..3338402719 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -100,7 +100,7 @@ float calculateHeight( const vec2 uv, - const float tileInterpolationParameter, + const float levelInterpolationParameter, const Tile heightTiles[NUMLAYERS_HEIGHTMAP], const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP], const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]) { @@ -109,22 +109,19 @@ float calculateHeight( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 + LevelWeights levelWeights; #if HEIGHTMAP_BLENDING_ENABLED - float w1 = clamp(1 - tileInterpolationParameter, 0 , 1); - float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1)); - float w3 = clamp(tileInterpolationParameter - 1, 0 , 1); + levelWeights = getLevelWeights(levelInterpolationParameter); #else // HEIGHTMAP_BLENDING_ENABLED - float w1 = 1; - float w2 = 0; - float w3 = 0; + levelWeights = getDefaultLevelWeights(); #endif // HEIGHTMAP_BLENDING_ENABLED #for i in 0..#{lastLayerIndexHeight} { float untransformedHeight = - w1 * getTexVal(heightTiles[#{i}], uv).r + - w2 * getTexVal(heightTilesParent1[#{i}], uv).r + - w3 * getTexVal(heightTilesParent2[#{i}], uv).r; + levelWeights.w1 * getTexVal(heightTiles[#{i}], uv).r + + levelWeights.w2 * getTexVal(heightTilesParent1[#{i}], uv).r + + levelWeights.w3 * getTexVal(heightTilesParent2[#{i}], uv).r; // OBS! Only the values from the last height map will be used! height = getTransformedTexVal(heightTiles[#{i}].depthTransform, untransformedHeight); @@ -136,7 +133,7 @@ float calculateHeight( vec4 calculateColor( const vec2 uv, - const float tileInterpolationParameter, + const float levelInterpolationParameter, const Tile colorTiles[NUMLAYERS_COLORTEXTURE], const Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE], const Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE]) { @@ -145,22 +142,19 @@ vec4 calculateColor( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 + LevelWeights levelWeights; #if COLORTEXTURE_BLENDING_ENABLED - float w1 = clamp(1 - tileInterpolationParameter, 0 , 1); - float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1)); - float w3 = clamp(tileInterpolationParameter - 1, 0 , 1); + levelWeights = getLevelWeights(levelInterpolationParameter); #else // COLORTEXTURE_BLENDING_ENABLED - float w1 = 1; - float w2 = 0; - float w3 = 0; + levelWeights = getDefaultLevelWeights(); #endif // COLORTEXTURE_BLENDING_ENABLED #for i in 0..#{lastLayerIndexColor} { vec4 colorSample = - w1 * getTexVal(colorTiles[#{i}], uv) + - w2 * getTexVal(colorTilesParent1[#{i}], uv) + - w3 * getTexVal(colorTilesParent2[#{i}], uv); + levelWeights.w1 * getTexVal(colorTiles[#{i}], uv) + + levelWeights.w2 * getTexVal(colorTilesParent1[#{i}], uv) + + levelWeights.w3 * getTexVal(colorTilesParent2[#{i}], uv); color = blendOver(color, colorSample); } @@ -172,7 +166,7 @@ vec4 calculateColor( vec4 calculateNight( const vec4 currentColor, const vec2 uv, - const float tileInterpolationParameter, + const float levelInterpolationParameter, const Tile nightTiles[NUMLAYERS_NIGHTTEXTURE], const Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE], const Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE], @@ -185,22 +179,19 @@ vec4 calculateNight( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 + LevelWeights levelWeights; #if NIGHTTEXTURE_BLENDING_ENABLED - float w1 = clamp(1 - tileInterpolationParameter, 0 , 1); - float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1)); - float w3 = clamp(tileInterpolationParameter - 1, 0 , 1); + levelWeights = getLevelWeights(levelInterpolationParameter) #else // NIGHTTEXTURE_BLENDING_ENABLED - float w1 = 1; - float w2 = 0; - float w3 = 0; + levelWeights = getDefaultLevelWeights(); #endif // NIGHTTEXTURE_BLENDING_ENABLED #for i in 0..#{lastLayerIndexNight} { vec4 colorSample = - w1 * getTexVal(nightTiles[#{i}], uv) + - w2 * getTexVal(nightTilesParent1[#{i}], uv) + - w3 * getTexVal(nightTilesParent2[#{i}], uv); + levelWeights.w1 * getTexVal(nightTiles[#{i}], uv) + + levelWeights.w2 * getTexVal(nightTilesParent1[#{i}], uv) + + levelWeights.w3 * getTexVal(nightTilesParent2[#{i}], uv); nightColor = blendOver(nightColor, colorSample); } @@ -215,7 +206,7 @@ vec4 calculateNight( vec4 calculateOverlay( const vec4 currentColor, const vec2 uv, - const float tileInterpolationParameter, + const float levelInterpolationParameter, const Tile overlayTiles[NUMLAYERS_OVERLAY], const Tile overlayTilesParent1[NUMLAYERS_OVERLAY], const Tile overlayTilesParent2[NUMLAYERS_OVERLAY]) { @@ -224,22 +215,19 @@ vec4 calculateOverlay( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 + LevelWeights levelWeights; #if OVERLAY_BLENDING_ENABLED - float w1 = clamp(1 - tileInterpolationParameter, 0 , 1); - float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1)); - float w3 = clamp(tileInterpolationParameter - 1, 0 , 1); + levelWeights = getLevelWeights(levelInterpolationParameter); #else // OVERLAY_BLENDING_ENABLED - float w1 = 1; - float w2 = 0; - float w3 = 0; + levelWeights = getDefaultLevelWeights(); #endif // OVERLAY_BLENDING_ENABLED #for i in 0..#{lastLayerIndexOverlay} { vec4 colorSample = - w1 * getTexVal(overlayTiles[#{i}], uv) + - w2 * getTexVal(overlayTilesParent1[#{i}], uv) + - w3 * getTexVal(overlayTilesParent2[#{i}], uv); + levelWeights.w1 * getTexVal(overlayTiles[#{i}], uv) + + levelWeights.w2 * getTexVal(overlayTilesParent1[#{i}], uv) + + levelWeights.w3 * getTexVal(overlayTilesParent2[#{i}], uv); color = blendOver(color, colorSample); } @@ -251,7 +239,7 @@ vec4 calculateOverlay( vec4 calculateWater( const vec4 currentColor, const vec2 uv, - const float tileInterpolationParameter, + const float levelInterpolationParameter, const Tile waterTiles[NUMLAYERS_WATERMASK], const Tile waterTilesParent1[NUMLAYERS_WATERMASK], const Tile waterTilesParent2[NUMLAYERS_WATERMASK]) { @@ -260,22 +248,19 @@ vec4 calculateWater( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 + LevelWeights levelWeights; #if WATERMASK_BLENDING_ENABLED - float w1 = clamp(1 - tileInterpolationParameter, 0 , 1); - float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1)); - float w3 = clamp(tileInterpolationParameter - 1, 0 , 1); + levelWeights = getLevelWeights(levelInterpolationParameter); #else // WATERMASK_BLENDING_ENABLED - float w1 = 1; - float w2 = 0; - float w3 = 0; + levelWeights = getDefaultLevelWeights(); #endif // WATERMASK_BLENDING_ENABLED #for i in 0..#{lastLayerIndexWater} { vec4 colorSample = - w1 * getTexVal(waterTiles[#{i}], uv) + - w2 * getTexVal(waterTilesParent1[#{i}], uv) + - w3 * getTexVal(waterTilesParent2[#{i}], uv); + levelWeights.w1 * getTexVal(waterTiles[#{i}], uv) + + levelWeights.w2 * getTexVal(waterTilesParent1[#{i}], uv) + + levelWeights.w3 * getTexVal(waterTilesParent2[#{i}], uv); waterColor = blendOver(waterColor, colorSample); } diff --git a/modules/globebrowsing/shaders/tile.hglsl b/modules/globebrowsing/shaders/tile.hglsl index 129a48f256..61c4b0991c 100644 --- a/modules/globebrowsing/shaders/tile.hglsl +++ b/modules/globebrowsing/shaders/tile.hglsl @@ -42,6 +42,29 @@ struct Tile { TileUvTransform uvTransform; }; +struct LevelWeights { + float w1; + float w2; + float w3; +}; + +LevelWeights getLevelWeights(float levelInterpolationParameter){ + LevelWeights levelWeights; + levelWeights.w1 = clamp(1 - levelInterpolationParameter, 0 , 1); + levelWeights.w2 = (clamp(levelInterpolationParameter, 0 , 1) - clamp(levelInterpolationParameter - 1, 0 , 1)); + levelWeights.w3 = clamp(levelInterpolationParameter - 1, 0 , 1); + return levelWeights; +} + +LevelWeights getDefaultLevelWeights(){ + LevelWeights levelWeights; + levelWeights.w1 = 1; + levelWeights.w2 = 0; + levelWeights.w3 = 0; + return levelWeights; +} + + vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) { vec2 uvOffset = uv - vec2(0.5); float thres = 0.5 - borderSize/2; From da956af2bc0af2cd6905eb21890582c78a8af2bc Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 9 Jun 2016 15:21:12 -0400 Subject: [PATCH 12/17] Update matrix type in atmosphere (new issues present to be fixed). --- modules/base/rendering/renderableplanet.cpp | 2 +- openspace.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 134e5d3795..5cacb79587 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -780,7 +780,7 @@ void RenderablePlanet::render(const RenderData& data) // Object Space (in Km) glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3() / 1000.0f); - glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * data.camera.viewRotationMatrix() * + glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * glm::mat4(data.camera.viewRotationMatrix()) * translateCamTrans * obj2World * transform; glm::mat4 completeInverse = glm::inverse(M); diff --git a/openspace.cfg b/openspace.cfg index a0a080511a..87cb583903 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -10,7 +10,7 @@ return { -- Scene = "${SCENE}/default-moon.scene", -- Scene = "${SCENE}/default_nh.scene", -- Scene = "${SCENE}/default.scene", - Scene = "${SCENE}/globebrowsing.scene", + Scene = "${SCENE}/globebrowsing.scene", -- Scene = "${SCENE}/default-modified.scene", -- Scene = "${SCENE}/rosetta.scene", -- Scene = "${SCENE}/dawn.scene", From b8025d8c23671ceae446b29e14f53a8867b8ce28 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 9 Jun 2016 16:03:28 -0400 Subject: [PATCH 13/17] New ray ellipsoid intersection routine (initial implementation). --- modules/base/rendering/renderableplanet.cpp | 4 +- modules/base/shaders/atmosphere_fs.glsl | 71 ++++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 5cacb79587..5fad671bc3 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -780,8 +780,10 @@ void RenderablePlanet::render(const RenderData& data) // Object Space (in Km) glm::mat4 obj2World = glm::translate(glm::mat4(1.0), data.position.vec3() / 1000.0f); - glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * glm::mat4(data.camera.viewRotationMatrix()) * + /*glm::mat4 M = data.camera.viewMatrix() * scaleCamTrans * glm::mat4(data.camera.viewRotationMatrix()) * translateCamTrans * obj2World * transform; + */ + glm::mat4 M = glm::mat4(data.camera.combinedViewMatrix()) * scaleCamTrans * obj2World * transform; glm::mat4 completeInverse = glm::inverse(M); diff --git a/modules/base/shaders/atmosphere_fs.glsl b/modules/base/shaders/atmosphere_fs.glsl index 68b20b5779..3dcd2ca5f7 100644 --- a/modules/base/shaders/atmosphere_fs.glsl +++ b/modules/base/shaders/atmosphere_fs.glsl @@ -92,6 +92,75 @@ vec4 butterworthFunc(const float d, const float r, const float n) { * and the second intersection: maxLength */ +struct Ray { + vec4 origin; + vec4 direction; +}; + +struct Ellipsoid { + vec4 center; + vec4 size; +}; + +bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out float offset, out float maxLength) { + vec4 O_C = ray.origin-ellipsoid.center; + vec4 dir = normalize(ray.direction); + + offset = 0.0f; + maxLength = 0.0f; + + float a = + ((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) + + ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) + + ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); + float b = + ((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x)) + + ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y)) + + ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z)); + float c = + ((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x)) + + ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y)) + + ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z)) + - 1.f; + + float d = ((b*b)-(4.f*a*c)); + if ( d<0.f || a==0.f || b==0.f || c==0.f ) + return false; + + d = sqrt(d); + + float t1 = (-b+d)/(2.f*a); + float t2 = (-b-d)/(2.f*a); + + if( t1<=EPSILON && t2<=EPSILON ) + return false; // both intersections are behind the ray origin + + bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid + float t=0.f; + if( t1<=EPSILON ) + t = t2; + else + if( t2<=EPSILON ) + t = t1; + else + t=(t1 Date: Thu, 9 Jun 2016 17:14:46 -0400 Subject: [PATCH 14/17] Toggle show chunk edges from gui and calculate level weights only once per vertex --- .../globebrowsing/globes/chunkedlodglobe.h | 1 + .../globebrowsing/globes/renderableglobe.cpp | 3 + .../globebrowsing/globes/renderableglobe.h | 1 + .../globebrowsing/rendering/chunkrenderer.cpp | 6 ++ .../shaders/globalchunkedlodpatch_fs.glsl | 16 ++-- .../shaders/globalchunkedlodpatch_vs.glsl | 11 ++- .../shaders/localchunkedlodpatch_fs.glsl | 17 ++-- .../shaders/localchunkedlodpatch_vs.glsl | 9 +-- .../shaders/texturetilemapping.hglsl | 78 +++---------------- 9 files changed, 51 insertions(+), 91 deletions(-) diff --git a/modules/globebrowsing/globes/chunkedlodglobe.h b/modules/globebrowsing/globes/chunkedlodglobe.h index 23719f21a8..d28a218093 100644 --- a/modules/globebrowsing/globes/chunkedlodglobe.h +++ b/modules/globebrowsing/globes/chunkedlodglobe.h @@ -107,6 +107,7 @@ namespace openspace { bool blendWaterMask; bool blendOverlay; bool atmosphereEnabled; + bool showChunkEdges; private: diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index f2e260ac4e..7a840f6502 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -68,6 +68,7 @@ namespace openspace { , blendOverlay(properties::BoolProperty("blendOverlay", "blendOverlay", true)) , blendWaterMask(properties::BoolProperty("blendWaterMask", "blendWaterMask", true)) , atmosphereEnabled(properties::BoolProperty("atmosphereEnabled", "atmosphereEnabled", false)) + , showChunkEdges(properties::BoolProperty("showChunkEdges", "showChunkEdges", false)) { setName("RenderableGlobe"); @@ -86,6 +87,7 @@ namespace openspace { addProperty(blendOverlay); addProperty(blendWaterMask); addProperty(atmosphereEnabled); + addProperty(showChunkEdges); doFrustumCulling.setValue(true); doHorizonCulling.setValue(true); @@ -200,6 +202,7 @@ namespace openspace { _chunkedLodGlobe->blendOverlay = blendOverlay.value(); _chunkedLodGlobe->blendWaterMask = blendWaterMask.value(); _chunkedLodGlobe->atmosphereEnabled = atmosphereEnabled.value(); + _chunkedLodGlobe->showChunkEdges = showChunkEdges.value(); std::vector& colorTextureProviders = _tileProviderManager->colorTextureProviders(); diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index bd4df3408e..7ca2aef429 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -82,6 +82,7 @@ public: properties::BoolProperty blendOverlay; properties::BoolProperty blendWaterMask; properties::BoolProperty atmosphereEnabled; + properties::BoolProperty showChunkEdges; private: std::string _frame; diff --git a/modules/globebrowsing/rendering/chunkrenderer.cpp b/modules/globebrowsing/rendering/chunkrenderer.cpp index 36ca20a13f..2c2c83c1a1 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.cpp +++ b/modules/globebrowsing/rendering/chunkrenderer.cpp @@ -187,6 +187,12 @@ namespace openspace { "useAtmosphere", std::to_string(chunk.owner()->atmosphereEnabled))); + layeredTexturePreprocessingData.keyValuePairs.push_back( + std::pair( + "showChunkEdges", + std::to_string(chunk.owner()->showChunkEdges))); + + // Now the shader program can be accessed ProgramObject* programObject = layeredTextureShaderProvider->getUpdatedShaderProgram( diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 58fa26be17..515418a4d3 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -60,20 +60,20 @@ in vec3 ellipsoidNormalCameraSpace; in vec4 fs_position; in vec2 fs_uv; -in float levelInterpolationParameter; +in LevelWeights levelWeights; Fragment getFragment() { Fragment frag; frag.color = vec4(0.1,0.1,0.1,1); - + //LevelWeights levelWeights = getLevelWeights(levelInterpolationParameter); #if USE_COLORTEXTURE frag.color = calculateColor( fs_uv, - levelInterpolationParameter, + levelWeights,//levelInterpolationParameter, colorTiles, colorTilesParent1, colorTilesParent2); @@ -85,7 +85,7 @@ Fragment getFragment() { frag.color = calculateWater( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, waterTiles, waterTilesParent1, waterTilesParent2); @@ -97,7 +97,7 @@ Fragment getFragment() { frag.color = calculateNight( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, nightTiles, nightTilesParent1, nightTilesParent2, @@ -114,14 +114,16 @@ Fragment getFragment() { frag.color = calculateOverlay( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, overlayTiles, overlayTilesParent1, overlayTilesParent2); #endif // USE_OVERLAY - //frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02); +#if SHOW_CHUNK_EDGES + frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02); +#endif // SHOW_CHUNK_EDGES frag.depth = fs_position.w; diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index 23f4cc5462..6d814e2b00 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -54,9 +54,8 @@ layout(location = 1) in vec2 in_uv; out vec2 fs_uv; out vec4 fs_position; out vec3 ellipsoidNormalCameraSpace; -// levelInterpolationParameter is used to interpolate between a tile and its parent tiles -// The value increases with the distance from the vertex (or fragment) to the camera -out float levelInterpolationParameter; + +out LevelWeights levelWeights; PositionNormalPair globalInterpolation() { vec2 lonLatInput; @@ -74,8 +73,8 @@ void main() float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; float desiredLevel = log2(projectedScaleFactor); - levelInterpolationParameter = chunkLevel - desiredLevel; - + float levelInterpolationParameter = chunkLevel - desiredLevel; + levelWeights = getLevelWeights(levelInterpolationParameter); float height = 0; #if USE_HEIGHTMAP @@ -84,7 +83,7 @@ void main() // Before any heightmapping is done height = calculateHeight( in_uv, - levelInterpolationParameter, // Variable to determine which texture to sample from + levelWeights, // Variable to determine which texture to sample from heightTiles, heightTilesParent1, heightTilesParent2); // Three textures to sample from #endif // USE_HEIGHTMAP diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 0f7a19e962..0469acf8e4 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -53,7 +53,7 @@ uniform Tile waterTilesParent2[NUMLAYERS_WATERMASK]; // levelInterpolationParameter is used to interpolate between a tile and its parent tiles // The value increases with the distance from the vertex (or fragment) to the camera -in float levelInterpolationParameter; +in LevelWeights levelWeights; in vec4 fs_position; in vec2 fs_uv; @@ -64,11 +64,13 @@ Fragment getFragment() { frag.color = vec4(1,1,1,1); + //LevelWeights levelWeights = getLevelWeights(levelInterpolationParameter); + #if USE_COLORTEXTURE frag.color = calculateColor( fs_uv, - levelInterpolationParameter, + levelWeights, colorTiles, colorTilesParent1, colorTilesParent2); @@ -81,7 +83,7 @@ Fragment getFragment() { frag.color = calculateWater( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, waterTiles, waterTilesParent1, waterTilesParent2); @@ -94,7 +96,7 @@ Fragment getFragment() { frag.color = calculateNight( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, nightTiles, nightTilesParent1, nightTilesParent2, @@ -111,14 +113,17 @@ Fragment getFragment() { frag.color = calculateOverlay( frag.color, fs_uv, - levelInterpolationParameter, + levelWeights, overlayTiles, overlayTilesParent1, overlayTilesParent2); #endif // USE_OVERLAY - //frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.02); +#if SHOW_CHUNK_EDGES + frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.02); +#endif // SHOW_CHUNK_EDGES + frag.depth = fs_position.w; diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index a04f12ff29..e079173722 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -59,9 +59,7 @@ out vec2 fs_uv; out vec4 fs_position; out vec3 ellipsoidNormalCameraSpace; -// levelInterpolationParameter is used to interpolate between a tile and its parent tiles -// The value increases with the distance from the vertex (or fragment) to the camera -out float levelInterpolationParameter; +out LevelWeights levelWeights; vec3 bilinearInterpolation(vec2 uv) { // Bilinear interpolation @@ -84,7 +82,8 @@ void main() float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid; float desiredLevel = log2(projectedScaleFactor); - levelInterpolationParameter = chunkLevel - desiredLevel; + float levelInterpolationParameter = chunkLevel - desiredLevel; + levelWeights = getLevelWeights(levelInterpolationParameter); #if USE_HEIGHTMAP @@ -92,7 +91,7 @@ void main() // Before any heightmapping is done height = calculateHeight( in_uv, - levelInterpolationParameter, // Variable to determine which texture to sample from + levelWeights, // Variable to determine which texture to sample from heightTiles, heightTilesParent1, heightTilesParent2); // Three textures to sample from #endif // USE_HEIGHTMAP diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index 3338402719..bb293013aa 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -29,78 +29,37 @@ #include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl> // First layer type from LayeredTextureShaderProvider is height map -#ifndef NUMLAYERS_HEIGHTMAP #define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeight} + 1 -#endif // NUMLAYERS_HEIGHTMAP - -#ifndef USE_HEIGHTMAP #define USE_HEIGHTMAP #{useHeightMap} -#endif // USE_HEIGHTMAP - -#ifndef HEIGHTMAP_BLENDING_ENABLED #define HEIGHTMAP_BLENDING_ENABLED #{heightMapBlendingEnabled} -#endif // HEIGHTMAP_BLENDING_ENABLED // Second layer type from LayeredTextureShaderProvider is color texture -#ifndef NUMLAYERS_COLORTEXTURE #define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColor} + 1 -#endif // NUMLAYERS_COLORTEXTURE - -#ifndef USE_COLORTEXTURE #define USE_COLORTEXTURE #{useColorTexture} -#endif // USE_COLORTEXTURE - -#ifndef COLORTEXTURE_BLENDING_ENABLED #define COLORTEXTURE_BLENDING_ENABLED #{colorTextureBlendingEnabled} -#endif // COLORTEXTURE_BLENDING_ENABLED // Third layer type from LayeredTextureShaderProvider is water mask -#ifndef NUMLAYERS_WATERMASK #define NUMLAYERS_WATERMASK #{lastLayerIndexWater} + 1 -#endif // NUMLAYERS_WATERMASK - -#ifndef USE_WATERMASK #define USE_WATERMASK #{useWaterMask} -#endif // USE_WATERMASK - -#ifndef WATERMASK_BLENDING_ENABLED #define WATERMASK_BLENDING_ENABLED #{waterMaskBlendingEnabled} -#endif // WATERMASK_BLENDING_ENABLED // Fourth layer type from LayeredTextureShaderProvider is night texture -#ifndef NUMLAYERS_NIGHTTEXTURE #define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNight} + 1 -#endif // NUMLAYERS_NIGHTTEXTURE - -#ifndef USE_NIGHTTEXTURE #define USE_NIGHTTEXTURE #{useNightTexture} -#endif // USE_NIGHTTEXTURE - -#ifndef NIGHTTEXTURE_BLENDING_ENABLED #define NIGHTTEXTURE_BLENDING_ENABLED #{nightTextureBlendingEnabled} -#endif // NIGHTTEXTURE_BLENDING_ENABLED // Fifth layer type from LayeredTextureShaderProvider is overlay -#ifndef NUMLAYERS_OVERLAY #define NUMLAYERS_OVERLAY #{lastLayerIndexOverlay} + 1 -#endif // NUMLAYERS_OVERLAY - -#ifndef USE_OVERLAY #define USE_OVERLAY #{useOverlay} -#endif // USE_OVERLAY - -#ifndef OVERLAY_BLENDING_ENABLED #define OVERLAY_BLENDING_ENABLED #{overlayBlendingEnabled} -#endif // OVERLAY_BLENDING_ENABLED // Other key value pairs used for settings -#ifndef USE_ATMOSPHERE #define USE_ATMOSPHERE #{useAtmosphere} -#endif // USE_ATMOSPHERE +#define SHOW_CHUNK_EDGES #{showChunkEdges} float calculateHeight( const vec2 uv, - const float levelInterpolationParameter, + LevelWeights levelWeights, const Tile heightTiles[NUMLAYERS_HEIGHTMAP], const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP], const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]) { @@ -109,10 +68,7 @@ float calculateHeight( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 - LevelWeights levelWeights; -#if HEIGHTMAP_BLENDING_ENABLED - levelWeights = getLevelWeights(levelInterpolationParameter); -#else // HEIGHTMAP_BLENDING_ENABLED +#if !HEIGHTMAP_BLENDING_ENABLED levelWeights = getDefaultLevelWeights(); #endif // HEIGHTMAP_BLENDING_ENABLED @@ -133,7 +89,7 @@ float calculateHeight( vec4 calculateColor( const vec2 uv, - const float levelInterpolationParameter, + LevelWeights levelWeights, const Tile colorTiles[NUMLAYERS_COLORTEXTURE], const Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE], const Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE]) { @@ -142,10 +98,7 @@ vec4 calculateColor( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 - LevelWeights levelWeights; -#if COLORTEXTURE_BLENDING_ENABLED - levelWeights = getLevelWeights(levelInterpolationParameter); -#else // COLORTEXTURE_BLENDING_ENABLED +#if !COLORTEXTURE_BLENDING_ENABLED levelWeights = getDefaultLevelWeights(); #endif // COLORTEXTURE_BLENDING_ENABLED @@ -166,7 +119,7 @@ vec4 calculateColor( vec4 calculateNight( const vec4 currentColor, const vec2 uv, - const float levelInterpolationParameter, + LevelWeights levelWeights, const Tile nightTiles[NUMLAYERS_NIGHTTEXTURE], const Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE], const Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE], @@ -179,10 +132,7 @@ vec4 calculateNight( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 - LevelWeights levelWeights; -#if NIGHTTEXTURE_BLENDING_ENABLED - levelWeights = getLevelWeights(levelInterpolationParameter) -#else // NIGHTTEXTURE_BLENDING_ENABLED +#if !NIGHTTEXTURE_BLENDING_ENABLED levelWeights = getDefaultLevelWeights(); #endif // NIGHTTEXTURE_BLENDING_ENABLED @@ -206,7 +156,7 @@ vec4 calculateNight( vec4 calculateOverlay( const vec4 currentColor, const vec2 uv, - const float levelInterpolationParameter, + LevelWeights levelWeights, const Tile overlayTiles[NUMLAYERS_OVERLAY], const Tile overlayTilesParent1[NUMLAYERS_OVERLAY], const Tile overlayTilesParent2[NUMLAYERS_OVERLAY]) { @@ -215,10 +165,7 @@ vec4 calculateOverlay( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 - LevelWeights levelWeights; -#if OVERLAY_BLENDING_ENABLED - levelWeights = getLevelWeights(levelInterpolationParameter); -#else // OVERLAY_BLENDING_ENABLED +#if !OVERLAY_BLENDING_ENABLED levelWeights = getDefaultLevelWeights(); #endif // OVERLAY_BLENDING_ENABLED @@ -239,7 +186,7 @@ vec4 calculateOverlay( vec4 calculateWater( const vec4 currentColor, const vec2 uv, - const float levelInterpolationParameter, + LevelWeights levelWeights, const Tile waterTiles[NUMLAYERS_WATERMASK], const Tile waterTilesParent1[NUMLAYERS_WATERMASK], const Tile waterTilesParent2[NUMLAYERS_WATERMASK]) { @@ -248,10 +195,7 @@ vec4 calculateWater( // The shader compiler will remove unused code when variables are multiplied by // a constant 0 - LevelWeights levelWeights; -#if WATERMASK_BLENDING_ENABLED - levelWeights = getLevelWeights(levelInterpolationParameter); -#else // WATERMASK_BLENDING_ENABLED +#if !WATERMASK_BLENDING_ENABLED levelWeights = getDefaultLevelWeights(); #endif // WATERMASK_BLENDING_ENABLED From f64998b5174b257014ca8b765612248d4dac6f20 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 9 Jun 2016 19:58:54 -0400 Subject: [PATCH 15/17] Fix CMake and add MultiLevelTile --- modules/globebrowsing/CMakeLists.txt | 2 +- .../shaders/globalchunkedlodpatch_fs.glsl | 2 +- .../shaders/localchunkedlodpatch_fs.glsl | 2 - modules/globebrowsing/shaders/tile.hglsl | 69 ++++++++++++++----- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index d9df98bb2e..c3c5d5a322 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -98,7 +98,7 @@ source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/blending.hglsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/ellipsoid.hglsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetile.hglsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetilemapping.hglsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalchunkedlodpatch_vs.glsl diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 515418a4d3..3c7b4bf19a 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -70,7 +70,7 @@ Fragment getFragment() { //LevelWeights levelWeights = getLevelWeights(levelInterpolationParameter); #if USE_COLORTEXTURE - + frag.color = calculateColor( fs_uv, levelWeights,//levelInterpolationParameter, diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 0469acf8e4..659f491c30 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -64,8 +64,6 @@ Fragment getFragment() { frag.color = vec4(1,1,1,1); - //LevelWeights levelWeights = getLevelWeights(levelInterpolationParameter); - #if USE_COLORTEXTURE frag.color = calculateColor( diff --git a/modules/globebrowsing/shaders/tile.hglsl b/modules/globebrowsing/shaders/tile.hglsl index 61c4b0991c..c00b6e40f1 100644 --- a/modules/globebrowsing/shaders/tile.hglsl +++ b/modules/globebrowsing/shaders/tile.hglsl @@ -25,16 +25,45 @@ #ifndef TEXTURETILE_HGLSL #define TEXTURETILE_HGLSL +vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) { + vec2 uvOffset = uv - vec2(0.5); + float thres = 0.5 - borderSize/2; + bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres; + vec3 color = isBorder ? borderColor : vec3(0); + return vec4(color, 0); +} + + +///////////////////////////////////////////////////////////////////// +// Tile Depth Transform // +///////////////////////////////////////////////////////////////////// + struct TileDepthTransform { float depthScale; float depthOffset; }; +float getTransformedTexVal(const TileDepthTransform transform, const float val){ + return transform.depthOffset + transform.depthScale * val; +} + +vec4 getTransformedTexVal(const TileDepthTransform transform, const vec4 val){ + return transform.depthOffset + transform.depthScale * val; +} + +///////////////////////////////////////////////////////////////////// +// Tile UV Transform // +///////////////////////////////////////////////////////////////////// + struct TileUvTransform { vec2 uvOffset; vec2 uvScale; }; + +///////////////////////////////////////////////////////////////////// +// Tile // +///////////////////////////////////////////////////////////////////// struct Tile { sampler2D textureSampler; @@ -42,6 +71,24 @@ struct Tile { TileUvTransform uvTransform; }; + +vec4 getTexVal(const Tile tile, const vec2 tileUV){ + vec2 samplePos = tile.uvTransform.uvOffset + tile.uvTransform.uvScale * tileUV; + vec4 texVal = texture(tile.textureSampler, samplePos); + return texVal; +} + + + +///////////////////////////////////////////////////////////////////// +// Multi Level Tile // +///////////////////////////////////////////////////////////////////// +struct MultiLevelTile { + Tile tile0; + Tile tile1; + Tile tile2; +}; + struct LevelWeights { float w1; float w2; @@ -65,26 +112,12 @@ LevelWeights getDefaultLevelWeights(){ } -vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) { - vec2 uvOffset = uv - vec2(0.5); - float thres = 0.5 - borderSize/2; - bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres; - vec3 color = isBorder ? borderColor : vec3(0); - return vec4(color, 0); +vec4 getTexVal(const MultiLevelTile multiLevelTile, const LevelWeights w, const vec2 uv){ + return w.w1 * getTexVal(multiLevelTile.tile0, uv) + + w.w2 * getTexVal(multiLevelTile.tile1, uv) + + w.w3 * getTexVal(multiLevelTile.tile2, uv); } -vec4 getTexVal(const Tile tile, const vec2 tileUV){ - vec2 samplePos = tile.uvTransform.uvOffset + tile.uvTransform.uvScale * tileUV; - vec4 texVal = texture(tile.textureSampler, samplePos); - return texVal; -} -vec4 getTransformedTexVal(const TileDepthTransform transform, const vec4 val){ - return transform.depthOffset + transform.depthScale * val; -} - -float getTransformedTexVal(const TileDepthTransform transform, const float val){ - return transform.depthOffset + transform.depthScale * val; -} #endif // TEXTURETILE_HGLSL \ No newline at end of file From b7f4398f33afc1066aa30f2edc55c6138443c144 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Thu, 9 Jun 2016 23:18:58 -0400 Subject: [PATCH 16/17] Add calculation of desired chunk level based on projected chunk area --- modules/globebrowsing/globes/chunk.cpp | 103 ++++++++++++++++++++++--- modules/globebrowsing/globes/chunk.h | 4 + 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/modules/globebrowsing/globes/chunk.cpp b/modules/globebrowsing/globes/chunk.cpp index 33e3035fd8..c8c24d8b2f 100644 --- a/modules/globebrowsing/globes/chunk.cpp +++ b/modules/globebrowsing/globes/chunk.cpp @@ -30,7 +30,7 @@ #include #include - +#include namespace { const std::string _loggerCat = "Chunk"; @@ -84,14 +84,26 @@ namespace openspace { return Status::WANT_MERGE; } + //int desiredLevel = desiredLevelByDistance(myRenderData); + int desiredLevel = desiredLevelByProjectedArea(myRenderData); + + // clamp level + desiredLevel = glm::clamp(desiredLevel, _owner->minSplitDepth, _owner->maxSplitDepth); + + if (desiredLevel < _index.level) return Status::WANT_MERGE; + else if (_index.level < desiredLevel) return Status::WANT_SPLIT; + else return Status::DO_NOTHING; + } + + int Chunk::desiredLevelByDistance(const RenderData& data) const { const Ellipsoid& ellipsoid = _owner->ellipsoid(); - Vec3 cameraPosition = myRenderData.camera.positionVec3(); + Vec3 cameraPosition = data.camera.positionVec3(); Geodetic2 pointOnPatch = _surfacePatch.closestPoint( - ellipsoid.cartesianToGeodetic2(cameraPosition)); - Vec3 globePosition = myRenderData.position.dvec3(); + ellipsoid.cartesianToGeodetic2(cameraPosition)); + Vec3 globePosition = data.position.dvec3(); Vec3 patchPosition = globePosition + ellipsoid.cartesianSurfacePosition(pointOnPatch); Vec3 cameraToChunk = patchPosition - cameraPosition; - + // Calculate desired level based on distance Scalar distance = glm::length(cameraToChunk); @@ -100,13 +112,84 @@ namespace openspace { Scalar scaleFactor = _owner->lodScaleFactor * ellipsoid.minimumRadius();; Scalar projectedScaleFactor = scaleFactor / distance; int desiredLevel = ceil(log2(projectedScaleFactor)); + return desiredLevel; + } - // clamp level - desiredLevel = glm::clamp(desiredLevel, _owner->minSplitDepth, _owner->maxSplitDepth); - if (desiredLevel < _index.level) return Status::WANT_MERGE; - else if (_index.level < desiredLevel) return Status::WANT_SPLIT; - else return Status::DO_NOTHING; + int Chunk::desiredLevelByProjectedArea(const RenderData& data) const { + const Ellipsoid& ellipsoid = _owner->ellipsoid(); + Vec3 cameraPosition = data.camera.positionVec3(); + Vec3 globePosition = data.position.dvec3(); + Vec3 cameraToEllipseCenter = globePosition - cameraPosition; + + const Geodetic2 nwCorner = _surfacePatch.northWestCorner(); + const Geodetic2 neCorner = _surfacePatch.northEastCorner(); + const Geodetic2 swCorner = _surfacePatch.southWestCorner(); + const Geodetic2 seCorner = _surfacePatch.southEastCorner(); + + Geodetic2 camPos = ellipsoid.cartesianToGeodetic2(cameraPosition); + + struct CornerDist { + Geodetic2 corner; + float dist; + }; + + struct { + bool operator()(const CornerDist& a, const CornerDist& b) { + return a.dist < b.dist; + } + } byDist; + + std::vector cornerDists(4); + for (size_t i = 0; i < 4; i++) { + const Geodetic2& c = _surfacePatch.getCorner((Quad)i); + Geodetic2 diff = (camPos - c); + float latDiff = fAngle::fromRadians(diff.lat).getNormalizedAround(fAngle::ZERO).asRadians(); + float lonDiff = fAngle::fromRadians(diff.lon).getNormalizedAround(fAngle::ZERO).asRadians(); + cornerDists[i].corner = c; + cornerDists[i].dist = latDiff*latDiff + lonDiff*lonDiff;; + } + + std::sort(cornerDists.begin(), cornerDists.end(), byDist); + + BoundingHeights heights = getBoundingHeights(); + + const Geodetic3 c0 = { cornerDists[0].corner, heights.min }; + const Geodetic3 c1 = { cornerDists[1].corner, heights.min }; + const Geodetic3 c2 = { cornerDists[2].corner, heights.max }; + const Geodetic3 c3 = { cornerDists[3].corner, heights.max }; + + Vec3 A = cameraToEllipseCenter + ellipsoid.cartesianPosition(c0); + Vec3 B = cameraToEllipseCenter + ellipsoid.cartesianPosition(c1); + Vec3 C = cameraToEllipseCenter + ellipsoid.cartesianPosition(c2); + Vec3 D = cameraToEllipseCenter + ellipsoid.cartesianPosition(c3); + + // Project points onto unit sphere + A = glm::normalize(A); + B = glm::normalize(B); + C = glm::normalize(C); + D = glm::normalize(D); + + + /* + A-----____ + | '''-----B + | __--' | + | __--'' | + C-----------------D + */ + + const Vec3 AB = B - A; + const Vec3 AC = C - A; + const Vec3 DC = C - D; + const Vec3 DB = B - D; + + double areaTriangle1 = 0.5 * glm::length(glm::cross(AC, AB)); + double areaTriangle2 = 0.5 * glm::length(glm::cross(DC, DB)); + double projectedChunkAreaApprox = areaTriangle1 + areaTriangle2; + + double scaledArea = _owner->lodScaleFactor * projectedChunkAreaApprox; + return _index.level + round(scaledArea - 1); } Chunk::BoundingHeights Chunk::getBoundingHeights() const { diff --git a/modules/globebrowsing/globes/chunk.h b/modules/globebrowsing/globes/chunk.h index 7352875084..df223d2d63 100644 --- a/modules/globebrowsing/globes/chunk.h +++ b/modules/globebrowsing/globes/chunk.h @@ -34,6 +34,7 @@ #include #include +#include namespace openspace { @@ -70,6 +71,9 @@ namespace openspace { private: + int desiredLevelByDistance(const RenderData& data) const; + int desiredLevelByProjectedArea(const RenderData& data) const; + ChunkedLodGlobe* _owner; ChunkIndex _index; bool _isVisible; From 795846f6eee1144a043dc4a479ed9ea21c86d3c5 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 10 Jun 2016 11:53:26 -0400 Subject: [PATCH 17/17] Updated file structure and removed unused class GlobeMesh --- modules/globebrowsing/CMakeLists.txt | 72 +++++------ .../globebrowsing/{globes => chunk}/chunk.cpp | 4 +- .../globebrowsing/{globes => chunk}/chunk.h | 8 +- .../{globes => chunk}/chunkedlodglobe.cpp | 4 +- .../{globes => chunk}/chunkedlodglobe.h | 10 +- .../{globes => chunk}/chunkindex.cpp | 4 +- .../{globes => chunk}/chunkindex.h | 0 .../{globes => chunk}/chunknode.cpp | 6 +- .../{globes => chunk}/chunknode.h | 10 +- .../{rendering => chunk}/chunkrenderer.cpp | 4 +- .../{rendering => chunk}/chunkrenderer.h | 10 +- .../{rendering => chunk}/culling.cpp | 14 ++- .../{rendering => chunk}/culling.h | 6 +- .../{rendering => geometry}/aabb.cpp | 2 +- .../{rendering => geometry}/aabb.h | 0 .../{geodetics => geometry}/angle.h | 2 +- .../{geodetics => geometry}/angle.inl | 2 +- .../{geodetics => geometry}/ellipsoid.cpp | 2 +- .../{geodetics => geometry}/ellipsoid.h | 2 +- .../{geodetics => geometry}/geodetic2.cpp | 6 +- .../{geodetics => geometry}/geodetic2.h | 2 +- modules/globebrowsing/globebrowsingmodule.cpp | 2 - modules/globebrowsing/globes/globemesh.cpp | 115 ------------------ modules/globebrowsing/globes/globemesh.h | 66 ---------- .../globebrowsing/globes/renderableglobe.cpp | 4 +- .../globebrowsing/globes/renderableglobe.h | 12 +- .../{other => tile}/TileProviderManager.cpp | 3 +- .../{other => tile}/TileProviderManager.h | 5 +- .../{other => tile}/asynctilereader.cpp | 7 +- .../{other => tile}/asynctilereader.h | 5 +- .../layeredtextureshaderprovider.cpp | 2 +- .../layeredtextureshaderprovider.h | 0 .../{other => tile}/temporaltileprovider.cpp | 7 +- .../{other => tile}/temporaltileprovider.h | 6 +- .../{other => tile}/tiledataset.cpp | 7 +- .../{other => tile}/tiledataset.h | 2 +- .../{other => tile}/tileprovider.cpp | 9 +- .../{other => tile}/tileprovider.h | 7 +- 38 files changed, 137 insertions(+), 292 deletions(-) rename modules/globebrowsing/{globes => chunk}/chunk.cpp (98%) rename modules/globebrowsing/{globes => chunk}/chunk.h (94%) rename modules/globebrowsing/{globes => chunk}/chunkedlodglobe.cpp (98%) rename modules/globebrowsing/{globes => chunk}/chunkedlodglobe.h (95%) rename modules/globebrowsing/{globes => chunk}/chunkindex.cpp (97%) rename modules/globebrowsing/{globes => chunk}/chunkindex.h (100%) rename modules/globebrowsing/{globes => chunk}/chunknode.cpp (97%) rename modules/globebrowsing/{globes => chunk}/chunknode.h (93%) rename modules/globebrowsing/{rendering => chunk}/chunkrenderer.cpp (99%) rename modules/globebrowsing/{rendering => chunk}/chunkrenderer.h (93%) rename modules/globebrowsing/{rendering => chunk}/culling.cpp (97%) rename modules/globebrowsing/{rendering => chunk}/culling.h (95%) rename modules/globebrowsing/{rendering => geometry}/aabb.cpp (99%) rename modules/globebrowsing/{rendering => geometry}/aabb.h (100%) rename modules/globebrowsing/{geodetics => geometry}/angle.h (99%) rename modules/globebrowsing/{geodetics => geometry}/angle.inl (99%) rename modules/globebrowsing/{geodetics => geometry}/ellipsoid.cpp (99%) rename modules/globebrowsing/{geodetics => geometry}/ellipsoid.h (98%) rename modules/globebrowsing/{geodetics => geometry}/geodetic2.cpp (98%) rename modules/globebrowsing/{geodetics => geometry}/geodetic2.h (99%) delete mode 100644 modules/globebrowsing/globes/globemesh.cpp delete mode 100644 modules/globebrowsing/globes/globemesh.h rename modules/globebrowsing/{other => tile}/TileProviderManager.cpp (99%) rename modules/globebrowsing/{other => tile}/TileProviderManager.h (96%) rename modules/globebrowsing/{other => tile}/asynctilereader.cpp (96%) rename modules/globebrowsing/{other => tile}/asynctilereader.h (97%) rename modules/globebrowsing/{other => tile}/layeredtextureshaderprovider.cpp (98%) rename modules/globebrowsing/{other => tile}/layeredtextureshaderprovider.h (100%) rename modules/globebrowsing/{other => tile}/temporaltileprovider.cpp (98%) rename modules/globebrowsing/{other => tile}/temporaltileprovider.h (98%) rename modules/globebrowsing/{other => tile}/tiledataset.cpp (99%) rename modules/globebrowsing/{other => tile}/tiledataset.h (99%) rename modules/globebrowsing/{other => tile}/tileprovider.cpp (97%) rename modules/globebrowsing/{other => tile}/tileprovider.h (97%) diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index c3c5d5a322..d8bc91a8ec 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -27,70 +27,74 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.h - ${CMAKE_CURRENT_SOURCE_DIR}/globes/globemesh.h - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.h - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunknode.h - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkindex.h - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunk.h + + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkedlodglobe.h + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunknode.h + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkindex.h + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunk.h + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkrenderer.h + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling.h + ${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.h ${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.h ${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.h ${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.h - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/geodetic2.h - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/angle.h - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/ellipsoid.h + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.h + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.h + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.h + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/culling.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/temporaltileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/temporaltileprovider.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovider.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/tiledataset.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/asynctilereader.h ${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.h ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h ${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovidermanager.h - ${CMAKE_CURRENT_SOURCE_DIR}/other/layeredtextureshaderprovider.h + ) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/globes/globemesh.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunknode.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkindex.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunk.cpp + + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkedlodglobe.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunknode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkindex.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunk.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunkrenderer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/geodetic2.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/angle.inl - ${CMAKE_CURRENT_SOURCE_DIR}/geodetics/ellipsoid.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.inl + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/culling.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/temporaltileprovider.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/temporaltileprovider.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovider.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/tiledataset.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/asynctilereader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl ${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovidermanager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/other/layeredtextureshaderprovider.cpp + ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/globebrowsing/globes/chunk.cpp b/modules/globebrowsing/chunk/chunk.cpp similarity index 98% rename from modules/globebrowsing/globes/chunk.cpp rename to modules/globebrowsing/chunk/chunk.cpp index c8c24d8b2f..943f2a3f8d 100644 --- a/modules/globebrowsing/globes/chunk.cpp +++ b/modules/globebrowsing/chunk/chunk.cpp @@ -27,8 +27,8 @@ #include -#include -#include +#include +#include #include diff --git a/modules/globebrowsing/globes/chunk.h b/modules/globebrowsing/chunk/chunk.h similarity index 94% rename from modules/globebrowsing/globes/chunk.h rename to modules/globebrowsing/chunk/chunk.h index df223d2d63..31953ad839 100644 --- a/modules/globebrowsing/globes/chunk.h +++ b/modules/globebrowsing/chunk/chunk.h @@ -30,11 +30,11 @@ #include #include -#include +#include +#include -#include -#include -#include +#include +#include namespace openspace { diff --git a/modules/globebrowsing/globes/chunkedlodglobe.cpp b/modules/globebrowsing/chunk/chunkedlodglobe.cpp similarity index 98% rename from modules/globebrowsing/globes/chunkedlodglobe.cpp rename to modules/globebrowsing/chunk/chunkedlodglobe.cpp index cecd5fb6b7..59601f3ec9 100644 --- a/modules/globebrowsing/globes/chunkedlodglobe.cpp +++ b/modules/globebrowsing/chunk/chunkedlodglobe.cpp @@ -22,10 +22,10 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include -#include +#include // open space includes #include diff --git a/modules/globebrowsing/globes/chunkedlodglobe.h b/modules/globebrowsing/chunk/chunkedlodglobe.h similarity index 95% rename from modules/globebrowsing/globes/chunkedlodglobe.h rename to modules/globebrowsing/chunk/chunkedlodglobe.h index d28a218093..fda448708d 100644 --- a/modules/globebrowsing/globes/chunkedlodglobe.h +++ b/modules/globebrowsing/chunk/chunkedlodglobe.h @@ -38,10 +38,12 @@ #include -#include -#include -#include -#include +#include + +#include +#include + +#include namespace ghoul { namespace opengl { diff --git a/modules/globebrowsing/globes/chunkindex.cpp b/modules/globebrowsing/chunk/chunkindex.cpp similarity index 97% rename from modules/globebrowsing/globes/chunkindex.cpp rename to modules/globebrowsing/chunk/chunkindex.cpp index 06af21d7df..edc05e9edf 100644 --- a/modules/globebrowsing/globes/chunkindex.cpp +++ b/modules/globebrowsing/chunk/chunkindex.cpp @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include +#include +#include namespace { diff --git a/modules/globebrowsing/globes/chunkindex.h b/modules/globebrowsing/chunk/chunkindex.h similarity index 100% rename from modules/globebrowsing/globes/chunkindex.h rename to modules/globebrowsing/chunk/chunkindex.h diff --git a/modules/globebrowsing/globes/chunknode.cpp b/modules/globebrowsing/chunk/chunknode.cpp similarity index 97% rename from modules/globebrowsing/globes/chunknode.cpp rename to modules/globebrowsing/chunk/chunknode.cpp index dd0b64c5d1..92e7cc62d6 100644 --- a/modules/globebrowsing/globes/chunknode.cpp +++ b/modules/globebrowsing/chunk/chunknode.cpp @@ -29,9 +29,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace { diff --git a/modules/globebrowsing/globes/chunknode.h b/modules/globebrowsing/chunk/chunknode.h similarity index 93% rename from modules/globebrowsing/globes/chunknode.h rename to modules/globebrowsing/chunk/chunknode.h index a32c5a9719..2ad4337a16 100644 --- a/modules/globebrowsing/globes/chunknode.h +++ b/modules/globebrowsing/chunk/chunknode.h @@ -31,10 +31,12 @@ #include #include -#include -#include -#include -#include +#include +#include +#include + +#include + diff --git a/modules/globebrowsing/rendering/chunkrenderer.cpp b/modules/globebrowsing/chunk/chunkrenderer.cpp similarity index 99% rename from modules/globebrowsing/rendering/chunkrenderer.cpp rename to modules/globebrowsing/chunk/chunkrenderer.cpp index 0554c1d953..463de9c309 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.cpp +++ b/modules/globebrowsing/chunk/chunkrenderer.cpp @@ -23,8 +23,8 @@ ****************************************************************************************/ -#include -#include +#include +#include // open space includes #include diff --git a/modules/globebrowsing/rendering/chunkrenderer.h b/modules/globebrowsing/chunk/chunkrenderer.h similarity index 93% rename from modules/globebrowsing/rendering/chunkrenderer.h rename to modules/globebrowsing/chunk/chunkrenderer.h index 5dde331563..e2956c2545 100644 --- a/modules/globebrowsing/rendering/chunkrenderer.h +++ b/modules/globebrowsing/chunk/chunkrenderer.h @@ -31,15 +31,15 @@ // open space includes #include -#include -#include +#include +#include #include -#include -#include +#include +#include -#include +#include namespace ghoul { namespace opengl { diff --git a/modules/globebrowsing/rendering/culling.cpp b/modules/globebrowsing/chunk/culling.cpp similarity index 97% rename from modules/globebrowsing/rendering/culling.cpp rename to modules/globebrowsing/chunk/culling.cpp index e306797cd9..43395fc7be 100644 --- a/modules/globebrowsing/rendering/culling.cpp +++ b/modules/globebrowsing/chunk/culling.cpp @@ -23,10 +23,16 @@ ****************************************************************************************/ -#include -#include -#include -#include + + + +#include +#include +#include + + +#include + #include namespace { diff --git a/modules/globebrowsing/rendering/culling.h b/modules/globebrowsing/chunk/culling.h similarity index 95% rename from modules/globebrowsing/rendering/culling.h rename to modules/globebrowsing/chunk/culling.h index a6d28d51c1..3ed58b422d 100644 --- a/modules/globebrowsing/rendering/culling.h +++ b/modules/globebrowsing/chunk/culling.h @@ -31,9 +31,9 @@ // open space includes #include -#include -#include -#include +#include +#include +#include diff --git a/modules/globebrowsing/rendering/aabb.cpp b/modules/globebrowsing/geometry/aabb.cpp similarity index 99% rename from modules/globebrowsing/rendering/aabb.cpp rename to modules/globebrowsing/geometry/aabb.cpp index d9b519ca94..41536297ad 100644 --- a/modules/globebrowsing/rendering/aabb.cpp +++ b/modules/globebrowsing/geometry/aabb.cpp @@ -23,7 +23,7 @@ ****************************************************************************************/ -#include +#include #include diff --git a/modules/globebrowsing/rendering/aabb.h b/modules/globebrowsing/geometry/aabb.h similarity index 100% rename from modules/globebrowsing/rendering/aabb.h rename to modules/globebrowsing/geometry/aabb.h diff --git a/modules/globebrowsing/geodetics/angle.h b/modules/globebrowsing/geometry/angle.h similarity index 99% rename from modules/globebrowsing/geodetics/angle.h rename to modules/globebrowsing/geometry/angle.h index fc3e1a4692..38af821533 100644 --- a/modules/globebrowsing/geodetics/angle.h +++ b/modules/globebrowsing/geometry/angle.h @@ -177,7 +177,7 @@ using fAngle = Angle; -#include +#include diff --git a/modules/globebrowsing/geodetics/angle.inl b/modules/globebrowsing/geometry/angle.inl similarity index 99% rename from modules/globebrowsing/geodetics/angle.inl rename to modules/globebrowsing/geometry/angle.inl index e40f636b3d..a4cc312198 100644 --- a/modules/globebrowsing/geodetics/angle.inl +++ b/modules/globebrowsing/geometry/angle.inl @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include diff --git a/modules/globebrowsing/geodetics/ellipsoid.cpp b/modules/globebrowsing/geometry/ellipsoid.cpp similarity index 99% rename from modules/globebrowsing/geodetics/ellipsoid.cpp rename to modules/globebrowsing/geometry/ellipsoid.cpp index cd37885a85..9c8fc8270f 100644 --- a/modules/globebrowsing/geodetics/ellipsoid.cpp +++ b/modules/globebrowsing/geometry/ellipsoid.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #define _USE_MATH_DEFINES #include diff --git a/modules/globebrowsing/geodetics/ellipsoid.h b/modules/globebrowsing/geometry/ellipsoid.h similarity index 98% rename from modules/globebrowsing/geodetics/ellipsoid.h rename to modules/globebrowsing/geometry/ellipsoid.h index 4f54a6727f..041d729ccd 100644 --- a/modules/globebrowsing/geodetics/ellipsoid.h +++ b/modules/globebrowsing/geometry/ellipsoid.h @@ -25,7 +25,7 @@ #ifndef __ELLIPSOID_H__ #define __ELLIPSOID_H__ -#include +#include namespace openspace { diff --git a/modules/globebrowsing/geodetics/geodetic2.cpp b/modules/globebrowsing/geometry/geodetic2.cpp similarity index 98% rename from modules/globebrowsing/geodetics/geodetic2.cpp rename to modules/globebrowsing/geometry/geodetic2.cpp index da8808fbeb..55e1d2e743 100644 --- a/modules/globebrowsing/geodetics/geodetic2.cpp +++ b/modules/globebrowsing/geometry/geodetic2.cpp @@ -22,9 +22,9 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include -#include +#include +#include +#include #include diff --git a/modules/globebrowsing/geodetics/geodetic2.h b/modules/globebrowsing/geometry/geodetic2.h similarity index 99% rename from modules/globebrowsing/geodetics/geodetic2.h rename to modules/globebrowsing/geometry/geodetic2.h index ac4e8d2f22..a87f357e04 100644 --- a/modules/globebrowsing/geodetics/geodetic2.h +++ b/modules/globebrowsing/geometry/geodetic2.h @@ -33,7 +33,7 @@ #define _USE_MATH_DEFINES #include -#include +#include #include diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index f8402d11f3..510938e4cc 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -63,7 +62,6 @@ void GlobeBrowsingModule::internalInitialize() { ghoul_assert(fRenderable, "Renderable factory was not created"); fRenderable->registerClass("RenderableGlobe"); - fRenderable->registerClass("GlobeMesh"); } } // namespace openspace diff --git a/modules/globebrowsing/globes/globemesh.cpp b/modules/globebrowsing/globes/globemesh.cpp deleted file mode 100644 index 509ae9787e..0000000000 --- a/modules/globebrowsing/globes/globemesh.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* 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. * -****************************************************************************************/ - -#include - -// open space includes -#include -#include -#include -#include - -// ghoul includes -#include - -#define _USE_MATH_DEFINES -#include - -namespace { - const std::string _loggerCat = "GlobeMesh"; -} - -namespace openspace { - GlobeMesh::GlobeMesh() - : _programObject(nullptr) - , _grid(10, 10, TriangleSoup::Positions::Yes, TriangleSoup::TextureCoordinates::No, TriangleSoup::Normals::No) - { - - } - - GlobeMesh::~GlobeMesh() { - } - - bool GlobeMesh::initialize() { - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject == nullptr) { - _programObject = renderEngine.buildRenderProgram( - "simpleTextureProgram", - "${MODULE_GLOBEBROWSING}/shaders/simple_vs.glsl", - "${MODULE_GLOBEBROWSING}/shaders/simple_fs.glsl"); - if (!_programObject) return false; - } - - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - _programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - - return isReady(); - } - - bool GlobeMesh::deinitialize() { - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject) { - renderEngine.removeRenderProgram(_programObject); - _programObject = nullptr; - } - - return true; - } - - bool GlobeMesh::isReady() const { - bool ready = true; - ready &= (_programObject != nullptr); - return ready; - } - - void GlobeMesh::render(const RenderData& data) - { - // activate shader - _programObject->activate(); - - // scale the planet to appropriate size since the planet is a unit sphere. Ehm no? - glm::mat4 transform = glm::mat4(1); - - // setup the data to the shader - // _programObject->setUniform("camdir", camSpaceEye); - _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); - _programObject->setUniform("ModelTransform", transform); - setPscUniforms(*_programObject.get(), data.camera, data.position); - - glDisable(GL_CULL_FACE); - //glCullFace(GL_BACK); - - // render - _grid.geometry().drawUsingActiveProgram(); - - // disable shader - _programObject->deactivate(); - } - - void GlobeMesh::update(const UpdateData& data) { - } - -} // namespace openspace diff --git a/modules/globebrowsing/globes/globemesh.h b/modules/globebrowsing/globes/globemesh.h deleted file mode 100644 index 8eb031b98f..0000000000 --- a/modules/globebrowsing/globes/globemesh.h +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* 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. * -****************************************************************************************/ - -#ifndef __GLOBEMESH_H__ -#define __GLOBEMESH_H__ - -// open space includes -#include - -#include -#include - -#include -#include -#include - -namespace ghoul { - namespace opengl { - class ProgramObject; - } -} - -namespace openspace { - - class GlobeMesh : public Renderable { - public: - GlobeMesh(); - virtual ~GlobeMesh(); - - bool initialize() override; - bool deinitialize() override; - bool isReady() const override; - - void render(const RenderData& data) override; - void update(const UpdateData& data) override; - - private: - std::unique_ptr _programObject; - - BasicGrid _grid; - }; - -} // namespace openspace - -#endif // __GLOBEMESH_H__ \ No newline at end of file diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 010297738b..c76c097686 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -23,9 +23,9 @@ ****************************************************************************************/ #include -#include + #include -#include +#include // open space includes #include diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index 7ca2aef429..917229f5d9 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -35,13 +35,15 @@ #include #include -#include -#include -#include -#include -#include +#include + +#include + +#include + #include +#include namespace ghoul { namespace opengl { diff --git a/modules/globebrowsing/other/TileProviderManager.cpp b/modules/globebrowsing/tile/TileProviderManager.cpp similarity index 99% rename from modules/globebrowsing/other/TileProviderManager.cpp rename to modules/globebrowsing/tile/TileProviderManager.cpp index 3d1121796e..d5df9f0046 100644 --- a/modules/globebrowsing/other/TileProviderManager.cpp +++ b/modules/globebrowsing/tile/TileProviderManager.cpp @@ -22,7 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include + #include #include "cpl_minixml.h" diff --git a/modules/globebrowsing/other/TileProviderManager.h b/modules/globebrowsing/tile/TileProviderManager.h similarity index 96% rename from modules/globebrowsing/other/TileProviderManager.h rename to modules/globebrowsing/tile/TileProviderManager.h index 3155370691..f2dc5e176d 100644 --- a/modules/globebrowsing/other/TileProviderManager.h +++ b/modules/globebrowsing/tile/TileProviderManager.h @@ -26,8 +26,9 @@ #define __TILE_PROVIDER_MANAGER_H__ -#include -#include +#include +#include + #include #include diff --git a/modules/globebrowsing/other/asynctilereader.cpp b/modules/globebrowsing/tile/asynctilereader.cpp similarity index 96% rename from modules/globebrowsing/other/asynctilereader.cpp rename to modules/globebrowsing/tile/asynctilereader.cpp index 0e9cb5b481..fcce97d5b9 100644 --- a/modules/globebrowsing/other/asynctilereader.cpp +++ b/modules/globebrowsing/tile/asynctilereader.cpp @@ -27,9 +27,10 @@ #include // abspath #include -#include -#include -#include +#include +#include + +#include namespace { const std::string _loggerCat = "AsyncTextureDataProvider"; diff --git a/modules/globebrowsing/other/asynctilereader.h b/modules/globebrowsing/tile/asynctilereader.h similarity index 97% rename from modules/globebrowsing/other/asynctilereader.h rename to modules/globebrowsing/tile/asynctilereader.h index 9d3667b008..acf69e8e5e 100644 --- a/modules/globebrowsing/other/asynctilereader.h +++ b/modules/globebrowsing/tile/asynctilereader.h @@ -30,11 +30,12 @@ #include -#include +#include #include #include -#include + +#include #include #include diff --git a/modules/globebrowsing/other/layeredtextureshaderprovider.cpp b/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp similarity index 98% rename from modules/globebrowsing/other/layeredtextureshaderprovider.cpp rename to modules/globebrowsing/tile/layeredtextureshaderprovider.cpp index 9544fd550f..77e90e57c8 100644 --- a/modules/globebrowsing/other/layeredtextureshaderprovider.cpp +++ b/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include #include diff --git a/modules/globebrowsing/other/layeredtextureshaderprovider.h b/modules/globebrowsing/tile/layeredtextureshaderprovider.h similarity index 100% rename from modules/globebrowsing/other/layeredtextureshaderprovider.h rename to modules/globebrowsing/tile/layeredtextureshaderprovider.h diff --git a/modules/globebrowsing/other/temporaltileprovider.cpp b/modules/globebrowsing/tile/temporaltileprovider.cpp similarity index 98% rename from modules/globebrowsing/other/temporaltileprovider.cpp rename to modules/globebrowsing/tile/temporaltileprovider.cpp index 9f3b206e49..8eae51a155 100644 --- a/modules/globebrowsing/other/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/temporaltileprovider.cpp @@ -22,10 +22,11 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include +#include -#include +#include + +#include #include diff --git a/modules/globebrowsing/other/temporaltileprovider.h b/modules/globebrowsing/tile/temporaltileprovider.h similarity index 98% rename from modules/globebrowsing/other/temporaltileprovider.h rename to modules/globebrowsing/tile/temporaltileprovider.h index f58578f4bf..0c6bad3be8 100644 --- a/modules/globebrowsing/other/temporaltileprovider.h +++ b/modules/globebrowsing/tile/temporaltileprovider.h @@ -28,8 +28,10 @@ #include -#include -#include +#include + +#include + #include #include diff --git a/modules/globebrowsing/other/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp similarity index 99% rename from modules/globebrowsing/other/tiledataset.cpp rename to modules/globebrowsing/tile/tiledataset.cpp index 564be88140..15da1bd632 100644 --- a/modules/globebrowsing/other/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -27,9 +27,10 @@ #include // abspath #include -#include -#include -#include +#include +#include + +#include #include diff --git a/modules/globebrowsing/other/tiledataset.h b/modules/globebrowsing/tile/tiledataset.h similarity index 99% rename from modules/globebrowsing/other/tiledataset.h rename to modules/globebrowsing/tile/tiledataset.h index 2fed6e554a..9f835f37ba 100644 --- a/modules/globebrowsing/other/tiledataset.h +++ b/modules/globebrowsing/tile/tiledataset.h @@ -29,7 +29,7 @@ #include -#include +#include #include #include "gdal_priv.h" diff --git a/modules/globebrowsing/other/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider.cpp similarity index 97% rename from modules/globebrowsing/other/tileprovider.cpp rename to modules/globebrowsing/tile/tileprovider.cpp index d6f0aa8f2b..fc69a280e3 100644 --- a/modules/globebrowsing/other/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider.cpp @@ -22,11 +22,12 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include -#include +#include -#include +#include +#include + +#include #include diff --git a/modules/globebrowsing/other/tileprovider.h b/modules/globebrowsing/tile/tileprovider.h similarity index 97% rename from modules/globebrowsing/other/tileprovider.h rename to modules/globebrowsing/tile/tileprovider.h index de1fe309f6..e71eabdbc3 100644 --- a/modules/globebrowsing/other/tileprovider.h +++ b/modules/globebrowsing/tile/tileprovider.h @@ -35,9 +35,12 @@ #include #include -#include +#include + +#include + #include -#include + ////////////////////////////////////////////////////////////////////////////////////////// // TILE PROVIDER //