From 12bb47c71e2cd8a3ce4b8c1697604ed1f2dffe3a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 7 Nov 2022 15:45:54 +0100 Subject: [PATCH] Recalculate chunk bounding boxes when the settings of a heightlayer change (closes #2096) * Correctly calculate Offset when negative numbers are involved * Adds tile index layer for the Moon * Remove empty spaces --- .../moon/layers/overlays/tile_indices.asset | 29 +++++++++++++++++ .../shaders/advanced_rings_fs.glsl | 4 +-- .../shaders/advanced_rings_vs.glsl | 2 +- .../globebrowsing/shaders/interpolate_fs.glsl | 2 +- .../shaders/localrenderer_vs.glsl | 4 +-- .../globebrowsing/shaders/renderer_fs.glsl | 2 +- modules/globebrowsing/shaders/rings_fs.glsl | 2 +- .../globebrowsing/shaders/rings_geom_fs.glsl | 4 +-- modules/globebrowsing/shaders/rings_vs.glsl | 2 +- .../shaders/texturetilemapping.glsl | 31 ++++++++++--------- modules/globebrowsing/shaders/tile.glsl | 2 +- modules/globebrowsing/shaders/tileheight.glsl | 2 +- modules/globebrowsing/src/layer.cpp | 8 +++++ .../globebrowsing/src/layerrendersettings.cpp | 8 +++++ .../globebrowsing/src/layerrendersettings.h | 2 ++ modules/globebrowsing/src/renderableglobe.cpp | 3 -- 16 files changed, 76 insertions(+), 31 deletions(-) create mode 100644 data/assets/scene/solarsystem/planets/earth/moon/layers/overlays/tile_indices.asset diff --git a/data/assets/scene/solarsystem/planets/earth/moon/layers/overlays/tile_indices.asset b/data/assets/scene/solarsystem/planets/earth/moon/layers/overlays/tile_indices.asset new file mode 100644 index 0000000000..326a169176 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/moon/layers/overlays/tile_indices.asset @@ -0,0 +1,29 @@ +local globeIdentifier = asset.require("../../moon").Moon.Identifier + +local layer = { + Identifier = "Tile_Indices", + Name = "Tile Indices", + Enabled = asset.enabled, + Type = "TileIndexTileLayer" +} + +asset.onInitialize(function() + openspace.globebrowsing.addLayer(globeIdentifier, "Overlays", layer) +end) + +asset.onDeinitialize(function() + openspace.globebrowsing.deleteLayer(globeIdentifier, "Overlays", layer) +end) + +asset.export("layer", layer) + + + +asset.meta = { + Name = "Moon Tile Indices", + Version = "1.0", + Description = "Tile index layer for Moon globe", + Author = "OpenSpace Team", + URL = "http://openspaceproject.com", + License = "MIT license" +} diff --git a/modules/globebrowsing/shaders/advanced_rings_fs.glsl b/modules/globebrowsing/shaders/advanced_rings_fs.glsl index 2958c4b681..ea732f55fa 100644 --- a/modules/globebrowsing/shaders/advanced_rings_fs.glsl +++ b/modules/globebrowsing/shaders/advanced_rings_fs.glsl @@ -91,7 +91,7 @@ Fragment getFragment() { normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - + float sum = 0; #for i in 0..#{nShadowSamples} sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); @@ -116,7 +116,7 @@ Fragment getFragment() { // Reduce the color of the fragment by the user factor // if we are facing away from the Sun if (dot(sunPosition, normal) < 0.0) { - diffuse.xyz = + diffuse.xyz = vec3(1.0, 0.97075, 0.952) * texture(ringTextureUnlit, texCoord).xyz * nightFactor; } diff --git a/modules/globebrowsing/shaders/advanced_rings_vs.glsl b/modules/globebrowsing/shaders/advanced_rings_vs.glsl index 98a205289d..958b9ef2ca 100644 --- a/modules/globebrowsing/shaders/advanced_rings_vs.glsl +++ b/modules/globebrowsing/shaders/advanced_rings_vs.glsl @@ -46,7 +46,7 @@ void main() { dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); - + shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); vs_screenSpaceDepth = positionClipSpaceZNorm.w; gl_Position = positionClipSpaceZNorm; diff --git a/modules/globebrowsing/shaders/interpolate_fs.glsl b/modules/globebrowsing/shaders/interpolate_fs.glsl index 6ce6118903..ec2af69bdc 100644 --- a/modules/globebrowsing/shaders/interpolate_fs.glsl +++ b/modules/globebrowsing/shaders/interpolate_fs.glsl @@ -38,7 +38,7 @@ Fragment getFragment() { vec4 mixedTexture = mix(texel0, texel1, blendFactor); - Fragment frag; + Fragment frag; if (mixedTexture.r > 0.999) { frag.color = texture(colormapTexture, mixedTexture.r - 0.01); } diff --git a/modules/globebrowsing/shaders/localrenderer_vs.glsl b/modules/globebrowsing/shaders/localrenderer_vs.glsl index faf4c50d3c..0809d84d7f 100644 --- a/modules/globebrowsing/shaders/localrenderer_vs.glsl +++ b/modules/globebrowsing/shaders/localrenderer_vs.glsl @@ -90,7 +90,7 @@ vec3 getLevelWeights(float distToVertexOnEllipsoid) { void main() { // Position in cameraspace vec3 p = bilinearInterpolation(in_uv); - + // Calculate desired level based on distance to the vertex on the ellipsoid // Before any heightmapping is done float distToVertexOnEllipsoid = length(p + patchNormalCameraSpace * chunkMinHeight); @@ -100,7 +100,7 @@ void main() { // Get the height value and apply skirts float height = getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength() * 100.0; - + // Translate the point along normal p += patchNormalCameraSpace * height; diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index 63a81341f5..083bd5dbc5 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -126,7 +126,7 @@ vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[NSEclipseShadows], } else if (length_d < r_p_pi) {// penumbra #if USE_ECLIPSE_HARD_SHADOWS - return vec4(0.5, 0.5, 0.5, 1.0); + return vec4(0.5, 0.5, 0.5, 1.0); #else return vec4(vec3(length_d / r_p_pi), 1.0); #endif diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 901f51811a..23a90a5eb6 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -80,7 +80,7 @@ Fragment getFragment() { normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - + float sum = 0; #for i in 0..#{nShadowSamples} sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 20866b4480..e29e24c843 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -54,7 +54,7 @@ Fragment getFragment() { } float diffuse = length(texture(ringTexture, texCoord).rgb); - + // The normal for the one plane depends on whether we are dealing // with a front facing or back facing fragment //vec3 normal; @@ -70,6 +70,6 @@ Fragment getFragment() { Fragment frag; frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); frag.depth = (diffuse < 0.5) ? 1E30 : vs_screenSpaceDepth; - + return frag; } diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl index 98a205289d..958b9ef2ca 100644 --- a/modules/globebrowsing/shaders/rings_vs.glsl +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -46,7 +46,7 @@ void main() { dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); - + shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); vs_screenSpaceDepth = positionClipSpaceZNorm.w; gl_Position = positionClipSpaceZNorm; diff --git a/modules/globebrowsing/shaders/texturetilemapping.glsl b/modules/globebrowsing/shaders/texturetilemapping.glsl index c591d38dcb..7d36e067c2 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.glsl +++ b/modules/globebrowsing/shaders/texturetilemapping.glsl @@ -73,38 +73,39 @@ float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNorm { // calculate intermediary values float NdotL = dot(surfaceNormal, lightDirection); - float NdotV = dot(surfaceNormal, viewDirection); + float NdotV = dot(surfaceNormal, viewDirection); float angleVN = acos(NdotV); float angleLN = acos(NdotL); - + float alpha = max(angleVN, angleLN); float beta = min(angleVN, angleLN); float gamma = dot( viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal), lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal) ); - + float roughnessSquared = roughness * roughness; - + // calculate A and B float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57)); float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09)); float C = sin(alpha) * tan(beta); - + // put it all together return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C); } float performLayerSettings(float value, LayerSettings settings) { - float v = pow(abs(value), settings.gamma) * settings.multiplier + settings.offset; - return sign(value) * v * settings.opacity; + float v = sign(value) * pow(abs(value), settings.gamma) * + settings.multiplier + settings.offset; + return v * settings.opacity; } -vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) { - vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) * - settings.multiplier + settings.offset; - return vec4(newValue, currentValue.a * settings.opacity); +vec4 performLayerSettings(vec4 value, LayerSettings settings) { + vec3 v = sign(value.rgb) * pow(abs(value.rgb), vec3(settings.gamma)) * + settings.multiplier + settings.offset; + return vec4(v, value.a * settings.opacity); } vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV, PixelPadding padding) @@ -194,7 +195,7 @@ vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor) #elif (#{#{layerGroup}#{i}BlendMode} == BlendModeColor) // Convert color to grayscale float gray = (newColor.r + newColor.g + newColor.b) / 3.0; - + vec3 hsvCurrent = rgb2hsv(currentColor.rgb); // Use gray from new color as value in hsv vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray); @@ -248,7 +249,7 @@ float calculateUntransformedHeight(vec2 uv, vec3 levelWeights, #if !HEIGHTMAP_BLENDING_ENABLED levelWeights = DefaultLevelWeights; #endif // HEIGHTMAP_BLENDING_ENABLED - + #for i in 0..#{lastLayerIndexHeightLayers} { vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers); @@ -354,7 +355,7 @@ vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights, vec3 n = normalize(ellipsoidNormalCameraSpace); vec3 l = lightDirectionCameraSpace; float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1); - + #for i in 0..#{lastLayerIndexNightLayers} { vec4 colorSample = getSampleNightLayers#{i}(uv, levelWeights, NightLayers); @@ -420,7 +421,7 @@ vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights, return color; } -vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights, +vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights, Layer WaterMasks[NUMLAYERS_WATERMASK], vec3 ellipsoidNormalCameraSpace, vec3 lightDirectionCameraSpace, vec3 positionCameraSpace, out float reflectance) diff --git a/modules/globebrowsing/shaders/tile.glsl b/modules/globebrowsing/shaders/tile.glsl index 7d140905b3..eb8e4b35d4 100644 --- a/modules/globebrowsing/shaders/tile.glsl +++ b/modules/globebrowsing/shaders/tile.glsl @@ -70,7 +70,7 @@ struct Layer { LayerSettings settings; LayerAdjustment adjustment; PixelPadding padding; - + // Other layer type properties stuff vec3 color; }; diff --git a/modules/globebrowsing/shaders/tileheight.glsl b/modules/globebrowsing/shaders/tileheight.glsl index 3df2ea0ec4..731c786ff0 100644 --- a/modules/globebrowsing/shaders/tileheight.glsl +++ b/modules/globebrowsing/shaders/tileheight.glsl @@ -79,7 +79,7 @@ float getTileHeight(vec2 uv, vec3 levelWeights) { float getTileHeightScaled(vec2 uv, vec3 levelWeights) { float height = getTileHeight(uv, levelWeights); - + #if USE_HEIGHTMAP height *= heightScale; #endif // USE_HEIGHTMAP diff --git a/modules/globebrowsing/src/layer.cpp b/modules/globebrowsing/src/layer.cpp index baee723ec4..f21ca9f39f 100644 --- a/modules/globebrowsing/src/layer.cpp +++ b/modules/globebrowsing/src/layer.cpp @@ -296,6 +296,14 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou } }); + _renderSettings.onChange([&]() { + // Only if we are a height layer will anyone care about these settings changing as + // that will change the overall bounding box of the layer and thus require culling + if (_parent.isHeightLayer() && _onChangeCallback) { + _onChangeCallback(this); + } + }); + _typeOption.onChange([&]() { switch (type()) { // Intentional fall through. Same for all tile layers diff --git a/modules/globebrowsing/src/layerrendersettings.cpp b/modules/globebrowsing/src/layerrendersettings.cpp index 1147900c9c..f634b9b328 100644 --- a/modules/globebrowsing/src/layerrendersettings.cpp +++ b/modules/globebrowsing/src/layerrendersettings.cpp @@ -85,6 +85,14 @@ LayerRenderSettings::LayerRenderSettings() }); } +void LayerRenderSettings::onChange(std::function callback) { + opacity.onChange(callback); + gamma.onChange(callback); + multiplier.onChange(callback); + multiplier.onChange(callback); + offset.onChange(callback); +} + float LayerRenderSettings::performLayerSettings(float v) const { return ((glm::sign(v) * glm::pow(glm::abs(v), gamma) * multiplier) + offset) * opacity; diff --git a/modules/globebrowsing/src/layerrendersettings.h b/modules/globebrowsing/src/layerrendersettings.h index 642f05069c..1a235a406b 100644 --- a/modules/globebrowsing/src/layerrendersettings.h +++ b/modules/globebrowsing/src/layerrendersettings.h @@ -41,6 +41,8 @@ struct LayerRenderSettings : public properties::PropertyOwner { properties::FloatProperty offset; properties::TriggerProperty setDefault; + void onChange(std::function callback); + /// This function matches the function with the same name in the /// shader code float performLayerSettings(float value) const; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 2144d8739c..f7647a7d5e 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -1858,9 +1858,6 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const { const int chunkLevel = node.tileIndex.level; - //TileIndex::TileIndex(const Geodetic2& point, int level_) - // : level(level_) - //{ const int numIndicesAtLevel = 1 << chunkLevel; const double u = 0.5 + geodeticPosition.lon / glm::two_pi(); const double v = 0.25 - geodeticPosition.lat / glm::two_pi();