From 096c19e49fa90ac98bff26bd38d9c99dbc5482fb Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Tue, 31 May 2016 12:17:40 -0400 Subject: [PATCH 1/4] Change definition of for loop statements in shader preprocessor to include both max and min. --- ext/ghoul | 2 +- .../shaders/globalchunkedlodpatch_fs.glsl | 9 +++++---- .../shaders/globalchunkedlodpatch_vs.glsl | 13 +++++++------ .../shaders/localchunkedlodpatch_fs.glsl | 9 +++++---- .../shaders/localchunkedlodpatch_vs.glsl | 13 +++++++------ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 5c9f358af8..f3420c0b5c 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 5c9f358af8056944d09b48c23cb9633aa5e533ff +Subproject commit f3420c0b5c40cb0819e9b67a85c3ab51fce6be8f diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 1665862311..0c5c83bdaf 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -38,12 +38,13 @@ in vec2 fs_uv; Fragment getFragment() { Fragment frag; - #for i in 0..#{numLayersColor} + #for j in 1..#{numLayersColor} { + int i = #{j} - 1; vec2 samplePos = - colorTiles[#{i}].uvTransform.uvScale * fs_uv + - colorTiles[#{i}].uvTransform.uvOffset; - vec4 colorSample = texture(colorTiles[#{i}].textureSampler, samplePos); + colorTiles[i].uvTransform.uvScale * fs_uv + + colorTiles[i].uvTransform.uvOffset; + vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); frag.color = blendOver(frag.color, colorSample); } #endfor diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index da7f692152..25938406d3 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -61,18 +61,19 @@ void main() float height = 0; - #for i in 0..#{numLayersHeight} + #for j in 1..#{numLayersHeight} { + int i = #{j} - 1; vec2 samplePos = - heightTiles[#{i}].uvTransform.uvScale * in_uv + - heightTiles[#{i}].uvTransform.uvOffset; + heightTiles[i].uvTransform.uvScale * in_uv + + heightTiles[i].uvTransform.uvOffset; - float sampledValue = texture(heightTiles[#{i}].textureSampler, samplePos).r; + float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r; // TODO : Some kind of blending here. Now it just writes over height = (sampledValue * - heightTiles[#{i}].depthTransform.depthScale + - heightTiles[#{i}].depthTransform.depthOffset); + heightTiles[i].depthTransform.depthScale + + heightTiles[i].depthTransform.depthOffset); // Skirts int vertexIDx = gl_VertexID % (xSegments + 3); diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index f0cb8f2ed0..487bc44f90 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -38,12 +38,13 @@ in vec2 fs_uv; Fragment getFragment() { Fragment frag; - #for i in 0..#{numLayersColor} + #for j in 1..#{numLayersColor} { + int i = #{j} - 1; vec2 samplePos = - colorTiles[#{i}].uvTransform.uvScale * fs_uv + - colorTiles[#{i}].uvTransform.uvOffset; - vec4 colorSample = texture(colorTiles[#{i}].textureSampler, samplePos); + colorTiles[i].uvTransform.uvScale * fs_uv + + colorTiles[i].uvTransform.uvOffset; + vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); frag.color = blendOver(frag.color, colorSample); } #endfor diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 51128d0a7e..1b54b2c395 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -65,18 +65,19 @@ void main() float height = 0; - #for i in 0..#{numLayersHeight} + #for j in 1..#{numLayersHeight} { + int i = #{j} - 1; vec2 samplePos = - heightTiles[#{i}].uvTransform.uvScale * in_uv + - heightTiles[#{i}].uvTransform.uvOffset; + heightTiles[i].uvTransform.uvScale * in_uv + + heightTiles[i].uvTransform.uvOffset; - float sampledValue = texture(heightTiles[#{i}].textureSampler, samplePos).r; + float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r; // TODO : Some kind of blending here. Now it just writes over height = (sampledValue * - heightTiles[#{i}].depthTransform.depthScale + - heightTiles[#{i}].depthTransform.depthOffset); + heightTiles[i].depthTransform.depthScale + + heightTiles[i].depthTransform.depthOffset); // Skirts int vertexIDx = gl_VertexID % (xSegments + 3); From aa5e64c31b6b6b09c430df816400fa9e4475c269 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Tue, 31 May 2016 12:49:08 -0400 Subject: [PATCH 2/4] Change length of skirts to be relative the size of the patches. --- modules/globebrowsing/rendering/patchrenderer.cpp | 5 +++++ modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl | 3 ++- modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index f50d03991a..2753d29e9a 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -248,6 +248,8 @@ namespace openspace { programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2())); programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); programObject->setUniform("xSegments", _grid->xSegments()); + // The length of the skirts is proportional to its size + programObject->setUniform("skirtLength", static_cast(chunk.surfacePatch().halfSize().lat * 1000000)); // OpenGL rendering settings glEnable(GL_DEPTH_TEST); @@ -483,6 +485,9 @@ namespace openspace { data.camera.projectionMatrix()); programObject->setUniform("xSegments", _grid->xSegments()); + // The length of the skirts is proportional to its size + programObject->setUniform("skirtLength", static_cast(chunk.surfacePatch().halfSize().lat * 1000000)); + // OpenGL rendering settings glEnable(GL_DEPTH_TEST); diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index 25938406d3..f7a3f2cefc 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -39,6 +39,7 @@ uniform vec2 lonLatScalingFactor; uniform int xSegments; uniform int ySegments; +uniform float skirtLength; uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; @@ -82,7 +83,7 @@ void main() vertexIDy == 0 || vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2) ) { - height = 0; + height -= skirtLength; } } #endfor diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 1b54b2c395..38b87213f0 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -44,6 +44,7 @@ uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; uniform int xSegments; uniform int ySegments; +uniform float skirtLength; layout(location = 1) in vec2 in_uv; @@ -86,7 +87,7 @@ void main() vertexIDy == 0 || vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2) ) { - height = 0; + height -= skirtLength; } } #endfor From 0202828c731f65e541cb789e7f352d5109651d7c Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Tue, 31 May 2016 19:26:42 -0400 Subject: [PATCH 3/4] Layers can be turned on and off during runtime and shaders will be recompiled accordingly. --- data/scene/debugglobe/debugglobe.mod | 20 +- .../globebrowsing/globes/renderableglobe.cpp | 43 +++- .../globebrowsing/globes/renderableglobe.h | 3 + .../other/TileProviderManager.cpp | 42 +++- .../globebrowsing/other/TileProviderManager.h | 27 ++- .../other/layeredtextureshaderprovider.cpp | 3 + .../globebrowsing/rendering/patchrenderer.cpp | 210 +----------------- 7 files changed, 112 insertions(+), 236 deletions(-) diff --git a/data/scene/debugglobe/debugglobe.mod b/data/scene/debugglobe/debugglobe.mod index dd494b168f..b6c0348725 100644 --- a/data/scene/debugglobe/debugglobe.mod +++ b/data/scene/debugglobe/debugglobe.mod @@ -10,32 +10,20 @@ return { Textures = { ColorTextures = { { - Name = "ESRI Imagery World 2D", - FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms", + Name = "VIIRS_SNPP_CorrectedReflectance_TrueColor", + FilePath = "map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml" }, - - - --[[ { Name = "Coastlines", FilePath = "map_service_configs/Coastlines.xml", }, - { - Name = "VIIRS_SNPP_CorrectedReflectance_TrueColor", - FilePath = "map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml" - }, { Name = "ESRI Imagery World 2D", FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms", }, - - { - Name = "MODIS_Terra_CorrectedReflectance_TrueColor", - FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml", - }, - - --]] + }, + HeightMaps = { { Name = "Terrain tileset", diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 24122d6a3f..467408db42 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -130,7 +130,10 @@ namespace openspace { std::shared_ptr colorTextureProvider = std::shared_ptr( new TileProvider(tileReader, cacheSize, frameUntilFlushRequestQueue)); - _tileProviderManager->addColorTexture(name, colorTextureProvider); + _tileProviderManager->addColorTexture(name, colorTextureProvider, true); + + // Create property for this tile provider + _activeColorLayers.push_back(properties::BoolProperty(name, name, true)); } ghoul::Dictionary heightMapsDictionary; @@ -158,8 +161,20 @@ namespace openspace { new TileProvider(tileReader, cacheSize, frameUntilFlushRequestQueue)); - _tileProviderManager->addHeightMap(name, heightMapProvider); + _tileProviderManager->addHeightMap(name, heightMapProvider, true); + + // Create property for this tile provider + _activeHeightMapLayers.push_back(properties::BoolProperty(name, name, true)); } + + // Add properties for the tile providers + for (auto it = _activeColorLayers.begin(); it != _activeColorLayers.end(); it++) { + addProperty(*it); + } + for (auto it = _activeHeightMapLayers.begin(); it != _activeHeightMapLayers.end(); it++) { + addProperty(*it); + } + _chunkedLodGlobe = std::shared_ptr( new ChunkedLodGlobe(_ellipsoid, patchSegments, _tileProviderManager)); @@ -198,17 +213,31 @@ namespace openspace { _chunkedLodGlobe->setSaveCamera(nullptr); } } - _chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value(); - _chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value(); - _chunkedLodGlobe->mergeInvisible = mergeInvisible.value(); - _chunkedLodGlobe->lodScaleFactor= lodScaleFactor.value(); - _chunkedLodGlobe->initChunkVisible = initChunkVisible.value(); + _distanceSwitch.render(data); } void RenderableGlobe::update(const UpdateData& data) { _time = data.time; _distanceSwitch.update(data); + + _chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value(); + _chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value(); + _chunkedLodGlobe->mergeInvisible = mergeInvisible.value(); + _chunkedLodGlobe->lodScaleFactor = lodScaleFactor.value(); + _chunkedLodGlobe->initChunkVisible = initChunkVisible.value(); + + std::vector& colorTextureProviders = + _tileProviderManager->colorTextureProviders(); + std::vector& heightMapProviders = + _tileProviderManager->heightMapProviders(); + + for (size_t i = 0; i < colorTextureProviders.size(); i++) { + colorTextureProviders[i].isActive = _activeColorLayers[i].value(); + } + for (size_t i = 0; i < heightMapProviders.size(); i++) { + heightMapProviders[i].isActive = _activeHeightMapLayers[i].value(); + } } glm::dvec3 RenderableGlobe::geodeticSurfaceProjection(glm::dvec3 position) { diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index 6b4163158d..0cbeaf200d 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -88,6 +88,9 @@ private: properties::BoolProperty _saveOrThrowCamera; + std::vector _activeColorLayers; + std::vector _activeHeightMapLayers; + DistanceSwitch _distanceSwitch; }; diff --git a/modules/globebrowsing/other/TileProviderManager.cpp b/modules/globebrowsing/other/TileProviderManager.cpp index 09115b4728..b4afd69e77 100644 --- a/modules/globebrowsing/other/TileProviderManager.cpp +++ b/modules/globebrowsing/other/TileProviderManager.cpp @@ -44,29 +44,57 @@ namespace openspace { void TileProviderManager::addHeightMap( std::string name, - std::shared_ptr tileProvider) + std::shared_ptr tileProvider, + bool isActive) { - _heightMapProviders.push_back(tileProvider); + _heightMapProviders.push_back({ name , tileProvider, isActive}); } void TileProviderManager::addColorTexture( std::string name, - std::shared_ptr tileProvider) + std::shared_ptr tileProvider, + bool isActive) { - _colorTextureProviders.push_back(tileProvider); - + _colorTextureProviders.push_back({ name , tileProvider, isActive }); } - const std::vector >& + std::vector& TileProviderManager::heightMapProviders() { return _heightMapProviders; } - const std::vector >& + std::vector& TileProviderManager::colorTextureProviders() { return _colorTextureProviders; } + const std::vector > + TileProviderManager::getActiveHeightMapProviders() + { + std::vector > tileProviders; + for (auto it = _heightMapProviders.begin(); it != _heightMapProviders.end(); it++) + { + if (it->isActive) { + tileProviders.push_back(it->tileProvider); + } + } + return tileProviders; + } + + const std::vector > + TileProviderManager::getActiveColorTextureProviders() + { + std::vector > tileProviders; + for (auto it = _colorTextureProviders.begin(); it != _colorTextureProviders.end(); it++) + { + if (it->isActive) { + tileProviders.push_back(it->tileProvider); + } + } + return tileProviders; + } + + } // namespace openspace diff --git a/modules/globebrowsing/other/TileProviderManager.h b/modules/globebrowsing/other/TileProviderManager.h index 1142c1e26d..40aa8bef57 100644 --- a/modules/globebrowsing/other/TileProviderManager.h +++ b/modules/globebrowsing/other/TileProviderManager.h @@ -37,23 +37,38 @@ namespace openspace { class TileProviderManager { public: + struct TileProviderWithName { + std::string name; + std::shared_ptr tileProvider; + bool isActive; + }; + TileProviderManager(); ~TileProviderManager(); static ThreadPool tileRequestThreadPool; - void addHeightMap(std::string name, std::shared_ptr tileProvider); - void addColorTexture(std::string name, std::shared_ptr tileProvider); + void addHeightMap( + std::string name, + std::shared_ptr tileProvider, + bool isActive); + void addColorTexture( + std::string name, + std::shared_ptr tileProvider, + bool isActive); /* std::shared_ptr getHeightMap(std::string name); std::shared_ptr getColorTexture(std::string name); */ - const std::vector >& heightMapProviders(); - const std::vector >& colorTextureProviders(); + const std::vector > getActiveHeightMapProviders(); + const std::vector > getActiveColorTextureProviders(); + + std::vector& heightMapProviders(); + std::vector& colorTextureProviders(); private: - std::vector > _heightMapProviders; - std::vector > _colorTextureProviders; + std::vector _heightMapProviders; + std::vector _colorTextureProviders; }; } // namespace openspace diff --git a/modules/globebrowsing/other/layeredtextureshaderprovider.cpp b/modules/globebrowsing/other/layeredtextureshaderprovider.cpp index 843f2fb1dc..dbd984511d 100644 --- a/modules/globebrowsing/other/layeredtextureshaderprovider.cpp +++ b/modules/globebrowsing/other/layeredtextureshaderprovider.cpp @@ -107,6 +107,9 @@ namespace openspace { textureTypes[i].keyNumLayers, textureTypes[i].numLayers); } + // Remove old program + _programObject.release(); + _programObject = OsEng.renderEngine().buildRenderProgram( _shaderName, _vsPath, diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index 2753d29e9a..8e5b469b34 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -69,12 +69,12 @@ namespace openspace { } void PatchRenderer::update() { - auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders(); for (auto iter = heightMapProviders.begin(); iter != heightMapProviders.end(); iter++) { iter->get()->prerender(); } - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders(); for (auto iter = colorTextureProviders.begin(); iter != colorTextureProviders.end(); iter++) { iter->get()->prerender(); @@ -101,24 +101,6 @@ namespace openspace { "LocalChunkedLodPatch", "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl", "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl")); - - /* - _programObjectGlobalRendering = OsEng.renderEngine().buildRenderProgram( - "GlobalChunkedLodPatch", - "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl", - "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_fs.glsl"); - ghoul_assert(_programObjectGlobalRendering != nullptr, "Failed to initialize programObject!"); - - _programObjectLocalRendering = OsEng.renderEngine().buildRenderProgram( - "LocalChunkedLodPatch", - "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl", - "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl"); - ghoul_assert(_programObjectLocalRendering != nullptr, "Failed to initialize programObject!"); - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - _programObjectGlobalRendering->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - _programObjectLocalRendering->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - */ - } void ChunkRenderer::renderChunk(const Chunk& chunk, const RenderData& data) { @@ -134,8 +116,8 @@ namespace openspace { using namespace glm; // All providers of tiles - auto heightMapProviders = _tileProviderManager->heightMapProviders(); - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders(); + auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders(); int numHeightMapProviders = heightMapProviders.size(); int numColorTextureProviders = colorTextureProviders.size(); @@ -261,73 +243,6 @@ namespace openspace { // disable shader programObject->deactivate(); - - - - - - - - - /* - // activate shader - _programObjectGlobalRendering->activate(); - - - // For now just pick the first one from height maps - //auto heightMapProviders = _tileProviderManager->heightMapProviders(); - //auto tileProviderHeight = heightMapProviders.begin()->second; - - // Get the textures that should be used for rendering - Tile heightTile = tileProviderHeight->getHighestResolutionTile(chunk.index()); - - - // Bind and use the texture - ghoul::opengl::TextureUnit texUnitHeight; - texUnitHeight.activate(); - heightTile.texture->bind(); - _programObjectGlobalRendering->setUniform("heightTile.textureSampler", texUnitHeight); - - _programObjectGlobalRendering->setUniform("heightTile.uvTransform.uvScale", heightTile.uvTransform.uvScale); - _programObjectGlobalRendering->setUniform("heightTile.uvTransform.uvOffset", heightTile.uvTransform.uvOffset); - - TileDepthTransform depthTransformHeight = tileProviderHeight->depthTransform(); - _programObjectGlobalRendering->setUniform("heightTile.depthTransform.depthScale", depthTransformHeight.depthScale); - _programObjectGlobalRendering->setUniform("heightTile.depthTransform.depthOffset", depthTransformHeight.depthOffset); - - - // Pick the first color texture - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); - auto tileProviderColor = colorTextureProviders.begin()->second; - Tile colorTile = tileProviderColor->getHighestResolutionTile(chunk.index()); - - - // Bind and use the texture - ghoul::opengl::TextureUnit texUnitColor; - texUnitColor.activate(); - colorTile.texture->bind(); - _programObjectGlobalRendering->setUniform("colorTile.textureSampler", texUnitColor); - _programObjectGlobalRendering->setUniform("colorTile.uvTransform.uvScale", colorTile.uvTransform.uvScale); - _programObjectGlobalRendering->setUniform("colorTile.uvTransform.uvOffset", colorTile.uvTransform.uvOffset); - - Geodetic2 swCorner = chunk.surfacePatch().southWestCorner(); - auto patchSize = chunk.surfacePatch().size(); - const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); - _programObjectGlobalRendering->setUniform("modelViewProjectionTransform", modelViewProjectionTransform); - _programObjectGlobalRendering->setUniform("minLatLon", vec2(swCorner.toLonLatVec2())); - _programObjectGlobalRendering->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2())); - _programObjectGlobalRendering->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - // render - _grid->geometry().drawUsingActiveProgram(); - - // disable shader - _programObjectGlobalRendering->deactivate(); - */ } void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& data) @@ -335,8 +250,8 @@ namespace openspace { using namespace glm; // All providers of tiles - auto heightMapProviders = _tileProviderManager->heightMapProviders(); - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders(); + auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders(); int numHeightMapProviders = heightMapProviders.size(); int numColorTextureProviders = colorTextureProviders.size(); @@ -434,12 +349,6 @@ namespace openspace { } - - - - - - // Calculate other uniform variables needed for rendering // TODO : Model transform should be fetched as a matrix directly. @@ -499,105 +408,6 @@ namespace openspace { // disable shader programObject->deactivate(); - - - - - - - /* - using namespace glm; - - // TODO : Model transform should be fetched as a matrix directly. - mat4 modelTransform = translate(mat4(1), data.position.vec3()); - mat4 viewTransform = data.camera.combinedViewMatrix(); - mat4 modelViewTransform = viewTransform * modelTransform; - - // activate shader - _programObjectLocalRendering->activate(); - - - // For now just pick the first one from height maps - auto heightMapProviders = _tileProviderManager->heightMapProviders(); - auto tileProviderHeight = heightMapProviders.begin()->second; - - // Get the textures that should be used for rendering - Tile heightTile = tileProviderHeight->getHighestResolutionTile(chunk.index()); - - // Bind and use the texture - ghoul::opengl::TextureUnit texUnitHeight; - texUnitHeight.activate(); - heightTile.texture->bind(); - _programObjectLocalRendering->setUniform("heightTile.textureSampler", texUnitHeight); - _programObjectLocalRendering->setUniform("heightTile.uvTransform.uvScale", heightTile.uvTransform.uvScale); - _programObjectLocalRendering->setUniform("heightTile.uvTransform.uvOffset", heightTile.uvTransform.uvOffset); - - TileDepthTransform depthTransformHeight = tileProviderHeight->depthTransform(); - _programObjectLocalRendering->setUniform("heightTile.depthTransform.depthScale", depthTransformHeight.depthScale); - _programObjectLocalRendering->setUniform("heightTile.depthTransform.depthOffset", depthTransformHeight.depthOffset); - - // Pick the first color texture - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); - auto tileProviderColor = colorTextureProviders.begin()->second; - Tile colorTile = tileProviderColor->getHighestResolutionTile(chunk.index()); - - - // Bind and use the texture - ghoul::opengl::TextureUnit texUnitColor; - texUnitColor.activate(); - colorTile.texture->bind(); - _programObjectLocalRendering->setUniform("colorTile.textureSampler", texUnitColor); - _programObjectLocalRendering->setUniform("colorTile.uvTransform.uvScale", colorTile.uvTransform.uvScale); - _programObjectLocalRendering->setUniform("colorTile.uvTransform.uvOffset", colorTile.uvTransform.uvOffset); - - - Geodetic2 sw = chunk.surfacePatch().southWestCorner(); - Geodetic2 se = chunk.surfacePatch().southEastCorner(); - Geodetic2 nw = chunk.surfacePatch().northWestCorner(); - Geodetic2 ne = chunk.surfacePatch().northEastCorner(); - - const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); - - // Get model space positions of the four control points - Vec3 patchSwModelSpace = ellipsoid.cartesianSurfacePosition(sw); - Vec3 patchSeModelSpace = ellipsoid.cartesianSurfacePosition(se); - Vec3 patchNwModelSpace = ellipsoid.cartesianSurfacePosition(nw); - Vec3 patchNeModelSpace = ellipsoid.cartesianSurfacePosition(ne); - - // Transform all control points to camera space - Vec3 patchSwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSwModelSpace, 1)); - Vec3 patchSeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSeModelSpace, 1)); - Vec3 patchNwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNwModelSpace, 1)); - Vec3 patchNeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNeModelSpace, 1)); - - // Send control points to shader - _programObjectLocalRendering->setUniform("p00", vec3(patchSwCameraSpace)); - _programObjectLocalRendering->setUniform("p10", vec3(patchSeCameraSpace)); - _programObjectLocalRendering->setUniform("p01", vec3(patchNwCameraSpace)); - _programObjectLocalRendering->setUniform("p11", vec3(patchNeCameraSpace)); - - vec3 patchNormalCameraSpace = normalize( - cross(patchSeCameraSpace - patchSwCameraSpace, - patchNwCameraSpace - patchSwCameraSpace)); - - _programObjectLocalRendering->setUniform( - "patchNormalCameraSpace", - patchNormalCameraSpace); - - _programObjectLocalRendering->setUniform( - "projectionTransform", - data.camera.projectionMatrix()); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - // render - _grid->geometry().drawUsingActiveProgram(); - - // disable shader - _programObjectLocalRendering->deactivate(); - */ } ////////////////////////////////////////////////////////////////////////////////////// @@ -692,7 +502,7 @@ namespace openspace { // For now just pick the first one from height maps - auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders(); auto tileProviderHeight = heightMapProviders[0]; PatchCoverage patchCoverageHeight = _patchCoverageProvider.getCoverage(newPatch, tileProviderHeight); @@ -747,7 +557,7 @@ namespace openspace { // Pick the first color texture - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders(); auto tileProviderColor = colorTextureProviders[0]; PatchCoverage patchCoverageColor = _patchCoverageProvider.getCoverage(newPatch, tileProviderColor); @@ -879,7 +689,7 @@ namespace openspace { _programObjectLocalRendering->setUniform("patchNormal", patchNormal); // For now just pick the first one from height maps - auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders(); auto tileProviderHeight = heightMapProviders[0]; PatchCoverage patchCoverageHeight = _patchCoverageProvider.getCoverage(newPatch, tileProviderHeight); @@ -935,7 +745,7 @@ namespace openspace { // Pick the first color texture - auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders(); auto tileProviderColor = colorTextureProviders[0]; PatchCoverage patchCoverageColor = _patchCoverageProvider.getCoverage(newPatch, tileProviderColor); From c2414480079f1314d6b714dc318eb3e37f7cc951 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Wed, 1 Jun 2016 20:47:07 -0400 Subject: [PATCH 4/4] Enable blending between ties of different levels to avoid some of the poping artifacts. --- data/scene/debugglobe/debugglobe.mod | 10 +- modules/globebrowsing/globes/chunk.cpp | 2 +- .../globebrowsing/globes/renderableglobe.cpp | 2 +- modules/globebrowsing/other/tileprovider.cpp | 21 ++- modules/globebrowsing/other/tileprovider.h | 10 +- .../globebrowsing/rendering/patchrenderer.cpp | 176 +++++++++++++++++- .../shaders/globalchunkedlodpatch_fs.glsl | 31 ++- .../shaders/globalchunkedlodpatch_vs.glsl | 30 ++- .../shaders/localchunkedlodpatch_fs.glsl | 30 ++- .../shaders/localchunkedlodpatch_vs.glsl | 30 ++- 10 files changed, 325 insertions(+), 17 deletions(-) diff --git a/data/scene/debugglobe/debugglobe.mod b/data/scene/debugglobe/debugglobe.mod index b6c0348725..7332347b93 100644 --- a/data/scene/debugglobe/debugglobe.mod +++ b/data/scene/debugglobe/debugglobe.mod @@ -13,6 +13,14 @@ return { Name = "VIIRS_SNPP_CorrectedReflectance_TrueColor", FilePath = "map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml" }, + { + Name = "MODIS_Terra_CorrectedReflectance_TrueColor", + FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml" + }, + { + Name = "MODIS_Water_Mask", + FilePath = "map_service_configs/MODIS_Water_Mask.xml" + }, { Name = "Coastlines", FilePath = "map_service_configs/Coastlines.xml", @@ -21,9 +29,7 @@ return { Name = "ESRI Imagery World 2D", FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms", }, - }, - HeightMaps = { { Name = "Terrain tileset", diff --git a/modules/globebrowsing/globes/chunk.cpp b/modules/globebrowsing/globes/chunk.cpp index dea8a7fd4a..a33bf03377 100644 --- a/modules/globebrowsing/globes/chunk.cpp +++ b/modules/globebrowsing/globes/chunk.cpp @@ -121,7 +121,7 @@ namespace openspace { Scalar scaleFactor = _owner->lodScaleFactor * ellipsoid.minimumRadius();; Scalar projectedScaleFactor = scaleFactor / distance; - int desiredLevel = floor(log2(projectedScaleFactor)); + int desiredLevel = ceil(log2(projectedScaleFactor)); // clamp level desiredLevel = glm::clamp(desiredLevel, _owner->minSplitDepth, _owner->maxSplitDepth); diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 467408db42..7d4d30058e 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -60,7 +60,7 @@ namespace openspace { , doFrustumCulling(properties::BoolProperty("doFrustumCulling", "doFrustumCulling")) , doHorizonCulling(properties::BoolProperty("doHorizonCulling", "doHorizonCulling")) , mergeInvisible(properties::BoolProperty("mergeInvisible", "mergeInvisible", true)) - , lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 10.0f, 0.0f, 100.0f)) + , lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 5.0f, 0.0f, 20.0f)) , initChunkVisible(properties::BoolProperty("initChunkVisible", "initChunkVisible", true)) , renderSmallChunksFirst(properties::BoolProperty("renderSmallChunksFirst", "renderSmallChunksFirst", true)) { diff --git a/modules/globebrowsing/other/tileprovider.cpp b/modules/globebrowsing/other/tileprovider.cpp index bbfe8d3133..74abfe41d8 100644 --- a/modules/globebrowsing/other/tileprovider.cpp +++ b/modules/globebrowsing/other/tileprovider.cpp @@ -98,10 +98,9 @@ namespace openspace { } - Tile TileProvider::getHighestResolutionTile(ChunkIndex chunkIndex) { - TileUvTransform uvTransform; - uvTransform.uvOffset = glm::vec2(0, 0); - uvTransform.uvScale = glm::vec2(1, 1); + Tile TileProvider::getHighestResolutionTile( + ChunkIndex chunkIndex, + TileUvTransform uvTransform) { int maximumLevel = _asyncTextureDataProvider->getTextureDataProvider()->getMaximumLevel(); @@ -113,6 +112,20 @@ namespace openspace { return getOrEnqueueHighestResolutionTile(chunkIndex, uvTransform); } + Tile TileProvider::getHighestResolutionParentTile(ChunkIndex chunkIndex, int levelOffset) { + TileUvTransform uvTransform; + uvTransform.uvOffset = glm::vec2(0, 0); + uvTransform.uvScale = glm::vec2(1, 1); + + for (int i = 0; i < levelOffset && chunkIndex.level > 2; i++) { + transformFromParent(chunkIndex, uvTransform); + chunkIndex = chunkIndex.parent(); + } + + Tile toReturn = getHighestResolutionTile(chunkIndex, uvTransform); + return toReturn; + } + Tile TileProvider::getOrEnqueueHighestResolutionTile(const ChunkIndex& chunkIndex, TileUvTransform& uvTransform) { diff --git a/modules/globebrowsing/other/tileprovider.h b/modules/globebrowsing/other/tileprovider.h index 7474ba6411..95e2a6df73 100644 --- a/modules/globebrowsing/other/tileprovider.h +++ b/modules/globebrowsing/other/tileprovider.h @@ -81,7 +81,15 @@ namespace openspace { ~TileProvider(); - Tile getHighestResolutionTile(ChunkIndex chunkIndex); + Tile getHighestResolutionTile( + ChunkIndex chunkIndex, + TileUvTransform uvTransform = {glm::vec2(0.0f,0.0f), glm::vec2(1.0f,1.0f)}); + /** + \param levelOffset gives a tile from a parent chunk with that particular + offset. For example levelOffset = 1 gives the first parent and levelOffset = 2 + gives the grand parent. + */ + Tile getHighestResolutionParentTile(ChunkIndex chunkIndex, int levelOffset = 1); std::shared_ptr getOrStartFetchingTile(ChunkIndex chunkIndex); std::shared_ptr getDefaultTexture(); diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index 8e5b469b34..f5c9eca9de 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -145,10 +145,18 @@ namespace openspace { programObject->activate(); std::vector texUnitHeight; + std::vector texUnitHeightParent1; + std::vector texUnitHeightParent2; std::vector texUnitColor; + std::vector texUnitColorParent1; + std::vector texUnitColorParent2; texUnitHeight.resize(numHeightMapProviders); + texUnitHeightParent1.resize(numHeightMapProviders); + texUnitHeightParent2.resize(numHeightMapProviders); texUnitColor.resize(numColorTextureProviders); + texUnitColorParent1.resize(numColorTextureProviders); + texUnitColorParent2.resize(numColorTextureProviders); // Go through all the height map providers @@ -159,11 +167,12 @@ namespace openspace { auto tileProvider = it->get(); // Get the texture that should be used for rendering Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); + Tile tileParent1 = tileProvider->getHighestResolutionParentTile(chunk.index(), 1); + Tile tileParent2 = tileProvider->getHighestResolutionParentTile(chunk.index(), 2); TileDepthTransform depthTransform = tileProvider->depthTransform(); // The texture needs a unit to sample from texUnitHeight[i].activate(); - int hej = 0; tile.texture->bind(); std::string indexedTileKey = "heightTiles[" + std::to_string(i) + "]"; @@ -177,6 +186,41 @@ namespace openspace { indexedTileKey + ".uvTransform.uvOffset", tile.uvTransform.uvOffset); + // Blend tile with two parents + // The texture needs a unit to sample from + texUnitHeightParent1[i].activate(); + tileParent1.texture->bind(); + + std::string indexedTileKeyParent1 = "heightTilesParent1[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent1 + ".textureSampler", texUnitHeightParent1[i]); + + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvScale", + tileParent1.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvOffset", + tileParent1.uvTransform.uvOffset); + + + + // The texture needs a unit to sample from + texUnitHeightParent2[i].activate(); + tileParent2.texture->bind(); + + std::string indexedTileKeyParent2 = "heightTilesParent2[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent2 + ".textureSampler", texUnitHeightParent2[i]); + + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvScale", + tileParent2.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvOffset", + tileParent2.uvTransform.uvOffset); + + + programObject->setUniform( indexedTileKey + ".depthTransform.depthScale", depthTransform.depthScale); @@ -194,6 +238,8 @@ namespace openspace { auto tileProvider = it->get(); // Get the texture that should be used for rendering Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); + Tile tileParent1 = tileProvider->getHighestResolutionParentTile(chunk.index(), 1); + Tile tileParent2 = tileProvider->getHighestResolutionParentTile(chunk.index(), 2); // The texture needs a unit to sample from texUnitColor[i].activate(); @@ -209,6 +255,38 @@ namespace openspace { programObject->setUniform( indexedTileKey + ".uvTransform.uvOffset", tile.uvTransform.uvOffset); + + // Blend tile with two parents + // The texture needs a unit to sample from + texUnitColorParent1[i].activate(); + tileParent1.texture->bind(); + + std::string indexedTileKeyParent1 = "colorTilesParent1[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent1 + ".textureSampler", texUnitColorParent1[i]); + + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvScale", + tileParent1.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvOffset", + tileParent1.uvTransform.uvOffset); + + + // The texture needs a unit to sample from + texUnitColorParent2[i].activate(); + tileParent2.texture->bind(); + + std::string indexedTileKeyParent2 = "colorTilesParent2[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent2 + ".textureSampler", texUnitColorParent2[i]); + + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvScale", + tileParent2.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvOffset", + tileParent2.uvTransform.uvOffset); i++; } @@ -224,6 +302,12 @@ namespace openspace { * viewTransform * modelTransform; const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); + vec3 pointClosestToCamera = chunk.owner()->ellipsoid().cartesianSurfacePosition(chunk.surfacePatch().closestPoint(chunk.owner()->ellipsoid().cartesianToGeodetic2(data.camera.positionVec3()))); + + + + float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius(); + // Upload the uniform variables programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform); programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2())); @@ -232,6 +316,11 @@ namespace openspace { programObject->setUniform("xSegments", _grid->xSegments()); // The length of the skirts is proportional to its size programObject->setUniform("skirtLength", static_cast(chunk.surfacePatch().halfSize().lat * 1000000)); + + programObject->setUniform("cameraPosition", vec3(data.camera.positionVec3())); + programObject->setUniform("distanceScaleFactor", distanceScaleFactor); + programObject->setUniform("chunkLevel", chunk.index().level); + // OpenGL rendering settings glEnable(GL_DEPTH_TEST); @@ -278,22 +367,31 @@ namespace openspace { // Activate the shader program programObject->activate(); - std::vector texUnitHeight; + std::vector texUnitHeightParent1; + std::vector texUnitHeightParent2; std::vector texUnitColor; + std::vector texUnitColorParent1; + std::vector texUnitColorParent2; texUnitHeight.resize(numHeightMapProviders); + texUnitHeightParent1.resize(numHeightMapProviders); + texUnitHeightParent2.resize(numHeightMapProviders); texUnitColor.resize(numColorTextureProviders); + texUnitColorParent1.resize(numColorTextureProviders); + texUnitColorParent2.resize(numColorTextureProviders); // Go through all the height map providers int i = 0; for (auto it = heightMapProviders.begin(); it != heightMapProviders.end(); it++) { + texUnitHeight.push_back(ghoul::opengl::TextureUnit()); auto tileProvider = it->get(); - // Get the texture that should be used for rendering Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); + Tile tileParent1 = tileProvider->getHighestResolutionParentTile(chunk.index(), 1); + Tile tileParent2 = tileProvider->getHighestResolutionParentTile(chunk.index(), 2); TileDepthTransform depthTransform = tileProvider->depthTransform(); // The texture needs a unit to sample from @@ -311,6 +409,40 @@ namespace openspace { indexedTileKey + ".uvTransform.uvOffset", tile.uvTransform.uvOffset); + // Blend tile with two parents + // The texture needs a unit to sample from + texUnitHeightParent1[i].activate(); + tileParent1.texture->bind(); + + std::string indexedTileKeyParent1 = "heightTilesParent1[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent1 + ".textureSampler", texUnitHeightParent1[i]); + + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvScale", + tileParent1.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvOffset", + tileParent1.uvTransform.uvOffset); + + + // The texture needs a unit to sample from + texUnitHeightParent2[i].activate(); + tileParent2.texture->bind(); + + std::string indexedTileKeyParent2 = "heightTilesParent2[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent2 + ".textureSampler", texUnitHeightParent2[i]); + + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvScale", + tileParent2.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvOffset", + tileParent2.uvTransform.uvOffset); + + + programObject->setUniform( indexedTileKey + ".depthTransform.depthScale", depthTransform.depthScale); @@ -326,9 +458,10 @@ namespace openspace { for (auto it = colorTextureProviders.begin(); it != colorTextureProviders.end(); it++) { auto tileProvider = it->get(); - // Get the texture that should be used for rendering Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); + Tile tileParent1 = tileProvider->getHighestResolutionParentTile(chunk.index(), 1); + Tile tileParent2 = tileProvider->getHighestResolutionParentTile(chunk.index(), 2); // The texture needs a unit to sample from texUnitColor[i].activate(); @@ -345,6 +478,38 @@ namespace openspace { indexedTileKey + ".uvTransform.uvOffset", tile.uvTransform.uvOffset); + // Blend tile with two parents + // The texture needs a unit to sample from + texUnitColorParent1[i].activate(); + tileParent1.texture->bind(); + + std::string indexedTileKeyParent1 = "colorTilesParent1[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent1 + ".textureSampler", texUnitColorParent1[i]); + + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvScale", + tileParent1.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent1 + ".uvTransform.uvOffset", + tileParent1.uvTransform.uvOffset); + + + // The texture needs a unit to sample from + texUnitColorParent2[i].activate(); + tileParent2.texture->bind(); + + std::string indexedTileKeyParent2 = "colorTilesParent2[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKeyParent2 + ".textureSampler", texUnitColorParent2[i]); + + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvScale", + tileParent2.uvTransform.uvScale); + programObject->setUniform( + indexedTileKeyParent2 + ".uvTransform.uvOffset", + tileParent2.uvTransform.uvOffset); + i++; } @@ -397,6 +562,9 @@ namespace openspace { // The length of the skirts is proportional to its size programObject->setUniform("skirtLength", static_cast(chunk.surfacePatch().halfSize().lat * 1000000)); + float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius(); + programObject->setUniform("distanceScaleFactor", distanceScaleFactor); + programObject->setUniform("chunkLevel", chunk.index().level); // OpenGL rendering settings glEnable(GL_DEPTH_TEST); diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 0c5c83bdaf..69183277db 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -31,20 +31,49 @@ #define NUMLAYERS_HEIGHTMAP #{numLayersHeight} uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; +uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; +uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; in vec4 fs_position; in vec2 fs_uv; +in vec3 positionWorldSpace; + +uniform vec3 cameraPosition; +uniform float distanceScaleFactor; +uniform int chunkLevel; + Fragment getFragment() { Fragment frag; + // Calculate desired level based on distance + float distToFrag = length(positionWorldSpace - cameraPosition); + float projectedScaleFactor = distanceScaleFactor / distToFrag; + float desiredLevel = log2(projectedScaleFactor); + + // x increases with distance + float x = chunkLevel - desiredLevel; + float w1 = clamp(1 - x, 0 , 1); + float w2 = (clamp(x, 0 , 1) - clamp(x - 1, 0 , 1)); + float w3 = clamp(x - 1, 0 , 1); + #for j in 1..#{numLayersColor} { int i = #{j} - 1; vec2 samplePos = colorTiles[i].uvTransform.uvScale * fs_uv + colorTiles[i].uvTransform.uvOffset; - vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); + vec2 samplePosParent1 = + colorTilesParent1[i].uvTransform.uvScale * fs_uv + + colorTilesParent1[i].uvTransform.uvOffset; + vec2 samplePosParent2 = + colorTilesParent2[i].uvTransform.uvScale * fs_uv + + colorTilesParent2[i].uvTransform.uvOffset; + + vec4 colorSample = + w1 * texture(colorTiles[i].textureSampler, samplePos) + + w2 * texture(colorTilesParent1[i].textureSampler, samplePosParent1) + + w3 * texture(colorTilesParent2[i].textureSampler, samplePosParent2); frag.color = blendOver(frag.color, colorSample); } #endfor diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index f7a3f2cefc..7e54669ad1 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -42,11 +42,18 @@ uniform int ySegments; uniform float skirtLength; uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; +uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; +uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; + +uniform vec3 cameraPosition; +uniform float distanceScaleFactor; +uniform int chunkLevel; layout(location = 1) in vec2 in_uv; out vec2 fs_uv; out vec4 fs_position; +out vec3 positionWorldSpace; PositionNormalPair globalInterpolation() { vec2 lonLatInput; @@ -59,17 +66,38 @@ PositionNormalPair globalInterpolation() { void main() { PositionNormalPair pair = globalInterpolation(); + positionWorldSpace = pair.position; float height = 0; + // Calculate desired level based on distance + float distToVertex = length(positionWorldSpace - cameraPosition); + float projectedScaleFactor = distanceScaleFactor / distToVertex; + float desiredLevel = log2(projectedScaleFactor); + + // x increases with distance + float x = chunkLevel - desiredLevel; + float w1 = clamp(1 - x, 0 , 1); + float w2 = (clamp(x, 0 , 1) - clamp(x - 1, 0 , 1)); + float w3 = clamp(x - 1, 0 , 1); + #for j in 1..#{numLayersHeight} { int i = #{j} - 1; vec2 samplePos = heightTiles[i].uvTransform.uvScale * in_uv + heightTiles[i].uvTransform.uvOffset; + vec2 samplePosParent1 = + heightTilesParent1[i].uvTransform.uvScale * in_uv + + heightTilesParent1[i].uvTransform.uvOffset; + vec2 samplePosParent2 = + heightTilesParent2[i].uvTransform.uvScale * in_uv + + heightTilesParent2[i].uvTransform.uvOffset; - float sampledValue = texture(heightTiles[i].textureSampler, samplePos).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 * diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 487bc44f90..1066b3c267 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -31,20 +31,48 @@ #define NUMLAYERS_HEIGHTMAP #{numLayersHeight} uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; +uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE]; +uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE]; in vec4 fs_position; in vec2 fs_uv; +in vec3 positionCameraSpace; + +uniform float distanceScaleFactor; +uniform int chunkLevel; Fragment getFragment() { Fragment frag; + // Calculate desired level based on distance + float distToFrag = length(positionCameraSpace); + float projectedScaleFactor = distanceScaleFactor / distToFrag; + float desiredLevel = log2(projectedScaleFactor); + + // x increases with distance + float x = chunkLevel - desiredLevel; + float w1 = clamp(1 - x, 0 , 1); + float w2 = (clamp(x, 0 , 1) - clamp(x - 1, 0 , 1)); + float w3 = clamp(x - 1, 0 , 1); + #for j in 1..#{numLayersColor} { int i = #{j} - 1; + vec2 samplePos = colorTiles[i].uvTransform.uvScale * fs_uv + colorTiles[i].uvTransform.uvOffset; - vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); + vec2 samplePosParent1 = + colorTilesParent1[i].uvTransform.uvScale * fs_uv + + colorTilesParent1[i].uvTransform.uvOffset; + vec2 samplePosParent2 = + colorTilesParent2[i].uvTransform.uvScale * fs_uv + + colorTilesParent2[i].uvTransform.uvOffset; + + vec4 colorSample = + w1 * texture(colorTiles[i].textureSampler, samplePos) + + w2 * texture(colorTilesParent1[i].textureSampler, samplePosParent1) + + w3 * texture(colorTilesParent2[i].textureSampler, samplePosParent2); frag.color = blendOver(frag.color, colorSample); } #endfor diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 38b87213f0..fefd829b79 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -41,15 +41,21 @@ uniform vec3 p11; uniform vec3 patchNormalCameraSpace; uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; +uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP]; +uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP]; uniform int xSegments; uniform int ySegments; uniform float skirtLength; +uniform float distanceScaleFactor; +uniform int chunkLevel; + layout(location = 1) in vec2 in_uv; out vec2 fs_uv; out vec4 fs_position; +out vec3 positionCameraSpace; vec3 bilinearInterpolation(vec2 uv) { // Bilinear interpolation @@ -66,14 +72,36 @@ void main() float height = 0; + positionCameraSpace = p; + + // Calculate desired level based on distance + float distToVertex = length(positionCameraSpace); + float projectedScaleFactor = distanceScaleFactor / distToVertex; + float desiredLevel = log2(projectedScaleFactor); + + // x increases with distance + float x = chunkLevel - desiredLevel; + float w1 = clamp(1 - x, 0 , 1); + float w2 = (clamp(x, 0 , 1) - clamp(x - 1, 0 , 1)); + float w3 = clamp(x - 1, 0 , 1); + #for j in 1..#{numLayersHeight} { int i = #{j} - 1; vec2 samplePos = heightTiles[i].uvTransform.uvScale * in_uv + heightTiles[i].uvTransform.uvOffset; + vec2 samplePosParent1 = + heightTilesParent1[i].uvTransform.uvScale * in_uv + + heightTilesParent1[i].uvTransform.uvOffset; + vec2 samplePosParent2 = + heightTilesParent2[i].uvTransform.uvScale * in_uv + + heightTilesParent2[i].uvTransform.uvOffset; - float sampledValue = texture(heightTiles[i].textureSampler, samplePos).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 *