From 54cf26755cfdaad1893c92c726cd36962b10fea4 Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Thu, 18 Jan 2024 13:23:22 +0100 Subject: [PATCH] Feature/point cloud scaling (#2994) * Try using angular max size rather than max pixel size * Update property name and use for shader * Add docs and remove mention of angle from user's perspective * People will wonder, so add some details as to what the value represents * Fix inconsistent punctuation in property texts with multiple sentences * Slight clarification of transformation matrix usage * Add values to asset files * Increase max size of example points a bit * Remove/Update comment * Add TODO comment about potential optimization * Reduce max size of SDSS and quasars a bit * Address review comment * Decrease 6df and increase globular clusters size as per review comment * Remove any mention of pixel size in the example asset * Remove some more mentions of pixel size * Write view space position to G-buffer to prevent atm. from shining through points --- data/assets/examples/pointclouds/points.asset | 21 ++-- data/assets/scene/digitaluniverse/2dF.asset | 4 +- data/assets/scene/digitaluniverse/2mass.asset | 6 +- data/assets/scene/digitaluniverse/6dF.asset | 6 +- data/assets/scene/digitaluniverse/abell.asset | 4 +- .../scene/digitaluniverse/deepsky.asset | 4 +- .../assets/scene/digitaluniverse/dwarfs.asset | 4 +- .../scene/digitaluniverse/exoplanets.asset | 4 +- .../exoplanets_candidates.asset | 4 +- .../digitaluniverse/globularclusters.asset | 6 +- .../scene/digitaluniverse/h2regions.asset | 4 +- data/assets/scene/digitaluniverse/hdf.asset | 4 +- .../scene/digitaluniverse/localdwarfs.asset | 4 +- .../digitaluniverse/obassociations.asset | 4 +- .../scene/digitaluniverse/openclusters.asset | 4 +- .../digitaluniverse/planetarynebulae.asset | 4 +- .../scene/digitaluniverse/pulsars.asset | 4 +- .../scene/digitaluniverse/quasars.asset | 4 +- data/assets/scene/digitaluniverse/sdss.asset | 4 +- .../scene/digitaluniverse/superclusters.asset | 4 +- .../digitaluniverse/supernovaremnants.asset | 4 +- data/assets/scene/digitaluniverse/tully.asset | 4 +- .../pointcloud/renderablepointcloud.cpp | 107 +++++++++--------- .../pointcloud/renderablepointcloud.h | 16 +-- modules/base/shaders/billboardpoint_fs.glsl | 4 +- modules/base/shaders/billboardpoint_gs.glsl | 54 ++++----- 26 files changed, 143 insertions(+), 149 deletions(-) diff --git a/data/assets/examples/pointclouds/points.asset b/data/assets/examples/pointclouds/points.asset index e298045d79..8007829406 100644 --- a/data/assets/examples/pointclouds/points.asset +++ b/data/assets/examples/pointclouds/points.asset @@ -23,10 +23,9 @@ local FixedColor_FixedSize = { } } --- Point cloud with fixed color and size scaling that is limited by a certain size, --- in pixels -local FixedColor_MaxPixelSize = { - Identifier = "ExamplePoints_MaxPixelSize", +-- Point cloud with fixed color and size scaling that is limited by a certain size +local FixedColor_MaxSize = { + Identifier = "ExamplePoints_MaxSize", Parent = earthAsset.Earth.Identifier, Transform = { Rotation = { @@ -41,14 +40,14 @@ local FixedColor_MaxPixelSize = { FixedColor = { 0.0, 1.0, 1.0 } }, SizeSettings = { - MaxPixelSize = 4.7, - EnablePixelSizeControl = true + MaxSize = 0.7, + EnableMaxSizeControl = true } }, GUI = { - Name = "Fixed Color / Max Pixel Size", + Name = "Fixed Color / Max Size", Path = "/Example/Point Clouds", - Description = "Point cloud with a fixed color and sizing with a given max pixel size" + Description = "Point cloud with a fixed color and sizing with a given max size" } } @@ -201,7 +200,7 @@ local ColorMappedAdvanced_NoBlend = { asset.onInitialize(function() openspace.addSceneGraphNode(FixedColor_FixedSize) - openspace.addSceneGraphNode(FixedColor_MaxPixelSize) + openspace.addSceneGraphNode(FixedColor_MaxSize) openspace.addSceneGraphNode(FixedColor_ScaleBasedOnData) openspace.addSceneGraphNode(Textured) openspace.addSceneGraphNode(ColorMapped_FixedSize) @@ -213,12 +212,12 @@ asset.onDeinitialize(function() openspace.removeSceneGraphNode(ColorMapped_FixedSize) openspace.removeSceneGraphNode(Textured) openspace.removeSceneGraphNode(FixedColor_ScaleBasedOnData) - openspace.removeSceneGraphNode(FixedColor_MaxPixelSize) + openspace.removeSceneGraphNode(FixedColor_MaxSize) openspace.removeSceneGraphNode(FixedColor_FixedSize) end) asset.export(FixedColor_FixedSize) -asset.export(FixedColor_MaxPixelSize) +asset.export(FixedColor_MaxSize) asset.export(FixedColor_ScaleBasedOnData) asset.export(Textured) asset.export(ColorMapped_FixedSize) diff --git a/data/assets/scene/digitaluniverse/2dF.asset b/data/assets/scene/digitaluniverse/2dF.asset index a86bea1544..48441443d8 100644 --- a/data/assets/scene/digitaluniverse/2dF.asset +++ b/data/assets/scene/digitaluniverse/2dF.asset @@ -33,8 +33,8 @@ local Object = { }, SizeSettings = { ScaleExponent = 22.6, - MaxPixelSize = 4.7, - EnablePixelSizeControl = true + MaxSize = 0.2, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/2mass.asset b/data/assets/scene/digitaluniverse/2mass.asset index 8ed791380b..daf8dfe6d9 100644 --- a/data/assets/scene/digitaluniverse/2mass.asset +++ b/data/assets/scene/digitaluniverse/2mass.asset @@ -33,9 +33,9 @@ local Object = { } }, SizeSettings = { - ScaleExponent = 22.5, - MaxPixelSize = 11.15, - EnablePixelSizeControl = true + ScaleExponent = 22.2, + MaxSize = 0.44, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/6dF.asset b/data/assets/scene/digitaluniverse/6dF.asset index 780aefc678..f3d5528369 100644 --- a/data/assets/scene/digitaluniverse/6dF.asset +++ b/data/assets/scene/digitaluniverse/6dF.asset @@ -33,9 +33,9 @@ local Object = { } }, SizeSettings = { - ScaleExponent = 23.2, - MaxPixelSize = 9.0, - EnablePixelSizeControl = true + ScaleExponent = 22.5, + MaxSize = 0.2, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/abell.asset b/data/assets/scene/digitaluniverse/abell.asset index 2e3f6f0d02..43ef6c6796 100644 --- a/data/assets/scene/digitaluniverse/abell.asset +++ b/data/assets/scene/digitaluniverse/abell.asset @@ -45,8 +45,8 @@ local Object = { TransformationMatrix = TransformMatrix, SizeSettings = { ScaleExponent = 22.6, - MaxPixelSize = 7.0, - EnablePixelSizeControl = true + MaxSize = 0.27, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/deepsky.asset b/data/assets/scene/digitaluniverse/deepsky.asset index 6be73ad6e4..5aa89ea88b 100644 --- a/data/assets/scene/digitaluniverse/deepsky.asset +++ b/data/assets/scene/digitaluniverse/deepsky.asset @@ -35,8 +35,8 @@ local DeepSkyObjects = { --FadeInDistances = { 0.05, 1.0 }, -- Fade in value in the same unit as "Unit" SizeSettings = { ScaleExponent = 21.7, - MaxPixelSize = 8.22, - EnablePixelSizeControl = true + MaxSize = 0.32, + EnableMaxSizeControl = true } }, Transform = { diff --git a/data/assets/scene/digitaluniverse/dwarfs.asset b/data/assets/scene/digitaluniverse/dwarfs.asset index 312112931d..fd13e0e4ec 100644 --- a/data/assets/scene/digitaluniverse/dwarfs.asset +++ b/data/assets/scene/digitaluniverse/dwarfs.asset @@ -40,8 +40,8 @@ local Object = { }, SizeSettings = { ScaleExponent = 16.2, - MaxPixelSize = 20.0, - EnablePixelSizeControl = true + MaxSize = 0.7, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/exoplanets.asset b/data/assets/scene/digitaluniverse/exoplanets.asset index f7abff68f8..c53f3ae27d 100644 --- a/data/assets/scene/digitaluniverse/exoplanets.asset +++ b/data/assets/scene/digitaluniverse/exoplanets.asset @@ -31,8 +31,8 @@ local Object = { Unit = "pc", SizeSettings = { ScaleExponent = 16.9, - MaxPixelSize = 75.0, - EnablePixelSizeControl = true + MaxSize = 2.8, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/exoplanets_candidates.asset b/data/assets/scene/digitaluniverse/exoplanets_candidates.asset index d33e413484..e0bb934486 100644 --- a/data/assets/scene/digitaluniverse/exoplanets_candidates.asset +++ b/data/assets/scene/digitaluniverse/exoplanets_candidates.asset @@ -27,8 +27,8 @@ local Object = { }, SizeSettings = { ScaleExponent = 17.8, - MaxPixelSize = 30.0, - EnablePixelSizeControl = true + MaxSize = 1.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/globularclusters.asset b/data/assets/scene/digitaluniverse/globularclusters.asset index ec6232b7af..2ce9c05cd5 100644 --- a/data/assets/scene/digitaluniverse/globularclusters.asset +++ b/data/assets/scene/digitaluniverse/globularclusters.asset @@ -33,9 +33,9 @@ local Object = { PolygonSides = 5, Unit = "pc", SizeSettings = { - ScaleExponent = 18.7, - MaxPixelSize = 500.0, - EnablePixelSizeControl = true + ScaleExponent = 18.9, + MaxSize = 13.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/h2regions.asset b/data/assets/scene/digitaluniverse/h2regions.asset index 3868e22b08..f704d48757 100644 --- a/data/assets/scene/digitaluniverse/h2regions.asset +++ b/data/assets/scene/digitaluniverse/h2regions.asset @@ -34,8 +34,8 @@ local Object = { Unit = "pc", SizeSettings = { ScaleExponent = 18.24, - MaxPixelSize = 300.0, - EnablePixelSizeControl = false + MaxSize = 8.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/hdf.asset b/data/assets/scene/digitaluniverse/hdf.asset index e44aeec0c0..964144e69c 100644 --- a/data/assets/scene/digitaluniverse/hdf.asset +++ b/data/assets/scene/digitaluniverse/hdf.asset @@ -39,9 +39,7 @@ local Object = { }, Unit = "Mpc", SizeSettings = { - ScaleExponent = 21.9, - MaxPixelSize = 4.7, - EnablePixelSizeControl = true + ScaleExponent = 21.9 } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/localdwarfs.asset b/data/assets/scene/digitaluniverse/localdwarfs.asset index 635b6e0edc..b09da57150 100644 --- a/data/assets/scene/digitaluniverse/localdwarfs.asset +++ b/data/assets/scene/digitaluniverse/localdwarfs.asset @@ -45,8 +45,8 @@ local Object = { Unit = "Mpc", SizeSettings = { ScaleExponent = 20.2, - MaxPixelSize = 20.0, - EnablePixelSizeControl = true + MaxSize = 0.7, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/obassociations.asset b/data/assets/scene/digitaluniverse/obassociations.asset index c1793d6717..fd0610c6f1 100644 --- a/data/assets/scene/digitaluniverse/obassociations.asset +++ b/data/assets/scene/digitaluniverse/obassociations.asset @@ -41,8 +41,8 @@ local Object = { SizeSettings = { SizeMapping = { "diameter" }, ScaleExponent = 16.9, - MaxPixelSize = 450.0, - EnablePixelSizeControl = true + MaxSize = 17, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/openclusters.asset b/data/assets/scene/digitaluniverse/openclusters.asset index dd35569693..d7a4e2a551 100644 --- a/data/assets/scene/digitaluniverse/openclusters.asset +++ b/data/assets/scene/digitaluniverse/openclusters.asset @@ -34,8 +34,8 @@ local Object = { PolygonSides = 12, SizeSettings = { ScaleExponent = 17.6, - MaxPixelSize = 604.0, - EnablePixelSizeControl = true + MaxSize = 23.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/planetarynebulae.asset b/data/assets/scene/digitaluniverse/planetarynebulae.asset index 303243769a..f9638d1392 100644 --- a/data/assets/scene/digitaluniverse/planetarynebulae.asset +++ b/data/assets/scene/digitaluniverse/planetarynebulae.asset @@ -34,8 +34,8 @@ local Object = { Unit = "pc", SizeSettings = { ScaleExponent = 18.46, - MaxPixelSize = 500.0, - EnablePixelSizeControl = true + MaxSize = 19.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/pulsars.asset b/data/assets/scene/digitaluniverse/pulsars.asset index f18b4e3b5a..fd8a4edee1 100644 --- a/data/assets/scene/digitaluniverse/pulsars.asset +++ b/data/assets/scene/digitaluniverse/pulsars.asset @@ -34,8 +34,8 @@ local Object = { Unit = "pc", SizeSettings = { ScaleExponent = 18.4, - MaxPixelSize = 500.0, - EnablePixelSizeControl = false + MaxSize = 19.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/quasars.asset b/data/assets/scene/digitaluniverse/quasars.asset index 92c57b19e0..93efec3236 100644 --- a/data/assets/scene/digitaluniverse/quasars.asset +++ b/data/assets/scene/digitaluniverse/quasars.asset @@ -46,8 +46,8 @@ local Object = { }, SizeSettings = { ScaleExponent = 23.5, - MaxPixelSize = 11.1, - EnablePixelSizeControl = true + MaxSize = 0.3, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/sdss.asset b/data/assets/scene/digitaluniverse/sdss.asset index 0ed6ee3d8c..0ffa195d31 100644 --- a/data/assets/scene/digitaluniverse/sdss.asset +++ b/data/assets/scene/digitaluniverse/sdss.asset @@ -37,8 +37,8 @@ local Object = { }, SizeSettings = { ScaleExponent = 22.6, - MaxPixelSize = 5.5, - EnablePixelSizeControl = true + MaxSize = 0.15, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/superclusters.asset b/data/assets/scene/digitaluniverse/superclusters.asset index 19d8a55c41..77260619f7 100644 --- a/data/assets/scene/digitaluniverse/superclusters.asset +++ b/data/assets/scene/digitaluniverse/superclusters.asset @@ -33,8 +33,8 @@ local Object = { Unit = "Mpc", SizeSettings = { ScaleExponent = 23.1, - MaxPixelSize = 7.2, - EnablePixelSizeControl = true + MaxSize = 0.2, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/supernovaremnants.asset b/data/assets/scene/digitaluniverse/supernovaremnants.asset index 388118796a..6a6c8816a8 100644 --- a/data/assets/scene/digitaluniverse/supernovaremnants.asset +++ b/data/assets/scene/digitaluniverse/supernovaremnants.asset @@ -34,8 +34,8 @@ local Object = { Unit = "pc", SizeSettings = { ScaleExponent = 18.4, - MaxPixelSize = 500.0, - EnablePixelSizeControl = true + MaxSize = 19.0, + EnableMaxSizeControl = true } }, GUI = { diff --git a/data/assets/scene/digitaluniverse/tully.asset b/data/assets/scene/digitaluniverse/tully.asset index f3a329348a..b7739c503d 100644 --- a/data/assets/scene/digitaluniverse/tully.asset +++ b/data/assets/scene/digitaluniverse/tully.asset @@ -52,8 +52,8 @@ local TullyGalaxies = { }, SizeSettings = { ScaleExponent = 21.9, - MaxPixelSize = 7.0, - EnablePixelSizeControl = true + MaxSize = 0.3, + EnableMaxSizeControl = true } }, GUI = { diff --git a/modules/base/rendering/pointcloud/renderablepointcloud.cpp b/modules/base/rendering/pointcloud/renderablepointcloud.cpp index be5d3fd6e6..6c8e08031f 100644 --- a/modules/base/rendering/pointcloud/renderablepointcloud.cpp +++ b/modules/base/rendering/pointcloud/renderablepointcloud.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -56,11 +55,11 @@ namespace { constexpr std::string_view _loggerCat = "RenderablePointCloud"; constexpr std::array UniformNames = { - "cameraViewProjectionMatrix", "modelMatrix", "cameraPosition", "cameraLookUp", - "renderOption", "maxBillboardSize", "color", "opacity", "scaleExponent", - "scaleFactor", "up", "right", "fadeInValue", "screenSize", "hasSpriteTexture", + "cameraViewMatrix", "projectionMatrix", "modelMatrix", "cameraPosition", + "cameraLookUp", "renderOption", "maxAngularSize", "color", "opacity", + "scaleExponent", "scaleFactor", "up", "right", "fadeInValue", "hasSpriteTexture", "spriteTexture", "useColorMap", "colorMapTexture", "cmapRangeMin", "cmapRangeMax", - "nanColor", "useNanColor", "hideOutsideRange", "enablePixelSizeControl", + "nanColor", "useNanColor", "hideOutsideRange", "enableMaxSizeControl", "aboveRangeColor", "useAboveRangeColor", "belowRangeColor", "useBelowRangeColor", "hasDvarScaling" }; @@ -81,7 +80,7 @@ namespace { "UseTexture", "Use Texture", "If true, use the provided sprite texture to render the point. If false, draw " - "the points using the default point shape", + "the points using the default point shape.", openspace::properties::Property::Visibility::AdvancedUser }; @@ -127,7 +126,7 @@ namespace { "Unit, or meters. With normal fading the points are fully visible once the " "camera is outside this range and fully invisible when inside the range. With " "inverted fading the situation is the opposite: the points are visible inside " - "hen closer than the min value of the range and invisible when further away", + "hen closer than the min value of the range and invisible when further away.", // @VISIBILITY(3.25) openspace::properties::Property::Visibility::AdvancedUser }; @@ -136,7 +135,7 @@ namespace { "Enabled", "Enable Distance-based Fading", "Enables/disables the Fade-in effect based on camera distance. Automatically set " - "to true if FadeInDistances are specified in the asset", + "to true if FadeInDistances are specified in the asset.", openspace::properties::Property::Visibility::User }; @@ -145,7 +144,7 @@ namespace { "Invert", "This property can be used the invert the fading so that the points are " "invisible when the camera is further away than the max fade distance " - "and fully visible when it is closer than the min distance", + "and fully visible when it is closer than the min distance.", openspace::properties::Property::Visibility::AdvancedUser }; @@ -176,7 +175,7 @@ namespace { "value should be. If not included, it is computed based on the maximum " "positional component of the data points. This is useful for showing the " "dataset at all, but you will likely want to change it to something that looks " - "good", + "good.", openspace::properties::Property::Visibility::User }; @@ -184,25 +183,29 @@ namespace { "ScaleFactor", "Scale Factor", "This value is used as a multiplicative factor to adjust the size of the points, " - "after the exponential scaling and any pixel-size control effects. Simply just " - "increases or decreases the visual size of the points", + "after the exponential scaling and any max size control effects. Simply just " + "increases or decreases the visual size of the points.", openspace::properties::Property::Visibility::User }; - constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { - "EnablePixelSizeControl", - "Enable Pixel Size Control", - "If true, the Max Size in Pixels property will be used as an upper limit for the " - "size of the point. Reduces the size of the points when approaching them, so that " - "they stick to a maximum screen space size. Currently, the scaling is computed " - "based on rectangular displays and might look weird in other projections", + constexpr openspace::properties::Property::PropertyInfo UseMaxSizeControlInfo = { + "EnableMaxSizeControl", + "Enable Max Size Control", + "If true, the Max Size property will be used as an upper limit for the size of " + "the point. This reduces the size of the points when approaching them, so that " + "they stick to a maximum visual size depending on the Max Size value.", openspace::properties::Property::Visibility::AdvancedUser }; - constexpr openspace::properties::Property::PropertyInfo MaxPixelSizeInfo = { - "MaxPixelSize", - "Max Size in Pixels", - "The maximum size (in pixels) for the billboard representing the point.", + constexpr openspace::properties::Property::PropertyInfo MaxSizeInfo = { + "MaxSize", + "Max Size", + "This value controls the maximum allowed size for the points, when the max size " + "control feature is enabled. This limits the visual size of the points based on " + "the distance to the camera. The larger the value, the larger the points are " + "allowed to become. In the background, the computations are made by limiting the " + "size to a certain angle based on the field of view of the camera. So a value of " + "1 limits the point size to take up a maximum of one degree of the view space.", openspace::properties::Property::Visibility::AdvancedUser }; @@ -220,7 +223,7 @@ namespace { "Parameter Option", "This value determines which parameter is used for scaling of the point. The " "parameter value will be used as a miltiplicative factor to scale the size of " - "the points. Not that they may however still be scaled by pixel size adjustment " + "the points. Note that they may however still be scaled by max size adjustment " "effects.", openspace::properties::Property::Visibility::AdvancedUser }; @@ -242,8 +245,8 @@ namespace { // interactively when OpenSpace is running until you find a value that you find // suitable. // - // - There is also an option to limit the size of the points based on a given pixel - // size. For now, this only works for flat projection displays. + // - There is also an option to limit the size of the points based on a given max + // size value. // // - To easily change the visual size of the points, the multiplicative 'ScaleFactor' // may be used. A value of 2 makes the points twice as large, visually, compared @@ -315,14 +318,14 @@ namespace { // [[codegen::verbatim(ScaleFactorInfo.description)]] std::optional scaleFactor; - // [[codegen::verbatim(PixelSizeControlInfo.description)]] - std::optional enablePixelSizeControl; + // [[codegen::verbatim(UseMaxSizeControlInfo.description)]] + std::optional enableMaxSizeControl; - // [[codegen::verbatim(MaxPixelSizeInfo.description)]] - std::optional maxPixelSize; + // [[codegen::verbatim(MaxSizeInfo.description)]] + std::optional maxSize; }; // Settings related to the scale of the points, whether they should limit to - // a certain pixel size, etc. + // a certain max size, etc. std::optional sizeSettings; struct ColorSettings { @@ -352,7 +355,7 @@ namespace { // origin of the dataset std::optional fading; - // Transformation matrix to be applied to each object + // Transformation matrix to be applied to the position of each object std::optional transformationMatrix; }; @@ -369,8 +372,8 @@ RenderablePointCloud::SizeSettings::SizeSettings(const ghoul::Dictionary& dictio : properties::PropertyOwner({ "Sizing", "Sizing", ""}) , scaleExponent(ScaleExponentInfo, 1.f, 0.f, 25.f) , scaleFactor(ScaleFactorInfo, 1.f, 0.f, 50.f) - , pixelSizeControl(PixelSizeControlInfo, false) - , maxPixelSize(MaxPixelSizeInfo, 400.f, 0.f, 1000.f) + , useMaxSizeControl(UseMaxSizeControlInfo, false) + , maxAngularSize(MaxSizeInfo, 1.f, 0.f, 45.f) { const Parameters p = codegen::bake(dictionary); @@ -379,8 +382,8 @@ RenderablePointCloud::SizeSettings::SizeSettings(const ghoul::Dictionary& dictio scaleFactor = settings.scaleFactor.value_or(scaleFactor); scaleExponent = settings.scaleExponent.value_or(scaleExponent); - pixelSizeControl = settings.enablePixelSizeControl.value_or(pixelSizeControl); - maxPixelSize = settings.maxPixelSize.value_or(maxPixelSize); + useMaxSizeControl = settings.enableMaxSizeControl.value_or(useMaxSizeControl); + maxAngularSize = settings.maxSize.value_or(maxAngularSize); if (settings.sizeMapping.has_value()) { std::vector opts = *settings.sizeMapping; @@ -396,8 +399,8 @@ RenderablePointCloud::SizeSettings::SizeSettings(const ghoul::Dictionary& dictio addProperty(scaleFactor); addProperty(scaleExponent); - addProperty(pixelSizeControl); - addProperty(maxPixelSize); + addProperty(useMaxSizeControl); + addProperty(maxAngularSize); } RenderablePointCloud::SizeSettings::SizeMapping::SizeMapping() @@ -720,11 +723,6 @@ void RenderablePointCloud::renderBillboards(const RenderData& data, _program->activate(); - _program->setUniform( - "screenSize", - glm::vec2(global::renderEngine->renderingResolution()) - ); - _program->setUniform(_uniformCache.cameraPos, data.camera.positionVec3()); _program->setUniform( _uniformCache.cameraLookup, @@ -732,9 +730,15 @@ void RenderablePointCloud::renderBillboards(const RenderData& data, ); _program->setUniform(_uniformCache.renderOption, _renderOption.value()); _program->setUniform(_uniformCache.modelMatrix, modelMatrix); + _program->setUniform( - _uniformCache.cameraViewProjectionMatrix, - glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() + _uniformCache.cameraViewMatrix, + data.camera.combinedViewMatrix() + ); + + _program->setUniform( + _uniformCache.projectionMatrix, + glm::dmat4(data.camera.projectionMatrix()) ); _program->setUniform(_uniformCache.up, glm::vec3(orthoUp)); @@ -744,14 +748,10 @@ void RenderablePointCloud::renderBillboards(const RenderData& data, _program->setUniform(_uniformCache.scaleExponent, _sizeSettings.scaleExponent); _program->setUniform(_uniformCache.scaleFactor, _sizeSettings.scaleFactor); - _program->setUniform(_uniformCache.enablePixelSizeControl, _sizeSettings.pixelSizeControl); - _program->setUniform(_uniformCache.maxBillboardSize, _sizeSettings.maxPixelSize); + _program->setUniform(_uniformCache.enableMaxSizeControl, _sizeSettings.useMaxSizeControl); + _program->setUniform(_uniformCache.maxAngularSize, _sizeSettings.maxAngularSize); _program->setUniform(_uniformCache.hasDvarScaling, _sizeSettings.sizeMapping.enabled); - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - _program->setUniform(_uniformCache.screenSize, glm::vec2(viewport[2], viewport[3])); - bool useTexture = _hasSpriteTexture && _useSpriteTexture; _program->setUniform(_uniformCache.hasSpriteTexture, useTexture); @@ -829,8 +829,6 @@ void RenderablePointCloud::render(const RenderData& data, RendererTasks&) { } glm::dmat4 modelMatrix = calcModelTransform(data); - glm::dmat4 modelViewProjectionMatrix = - calcModelViewProjectionTransform(data, modelMatrix); glm::dvec3 cameraViewDirectionWorld = -data.camera.viewDirectionWorldSpace(); glm::dvec3 cameraUpDirectionWorld = data.camera.lookUpVectorWorldSpace(); @@ -852,6 +850,9 @@ void RenderablePointCloud::render(const RenderData& data, RendererTasks&) { } if (_hasLabels) { + glm::dmat4 modelViewProjectionMatrix = + calcModelViewProjectionTransform(data, modelMatrix); + _labels->render(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVar); } } diff --git a/modules/base/rendering/pointcloud/renderablepointcloud.h b/modules/base/rendering/pointcloud/renderablepointcloud.h index 0cfcbed715..ab51cfe2d9 100644 --- a/modules/base/rendering/pointcloud/renderablepointcloud.h +++ b/modules/base/rendering/pointcloud/renderablepointcloud.h @@ -114,8 +114,8 @@ protected: properties::FloatProperty scaleExponent; properties::FloatProperty scaleFactor; - properties::BoolProperty pixelSizeControl; - properties::FloatProperty maxPixelSize; + properties::BoolProperty useMaxSizeControl; + properties::FloatProperty maxAngularSize; }; SizeSettings _sizeSettings; @@ -148,12 +148,12 @@ protected: ghoul::opengl::ProgramObject* _program = nullptr; UniformCache( - cameraViewProjectionMatrix, modelMatrix, cameraPos, cameraLookup, renderOption, - maxBillboardSize, color, opacity, scaleExponent, scaleFactor, up, right, - fadeInValue, screenSize, hasSpriteTexture, spriteTexture, useColormap, - colorMapTexture, cmapRangeMin, cmapRangeMax, nanColor, useNanColor, - hideOutsideRange, enablePixelSizeControl, aboveRangeColor, useAboveRangeColor, - belowRangeColor, useBelowRangeColor, hasDvarScaling + cameraViewMatrix, projectionMatrix, modelMatrix, cameraPos, cameraLookup, + renderOption, maxAngularSize, color, opacity, scaleExponent, scaleFactor, up, + right, fadeInValue, hasSpriteTexture, spriteTexture, useColormap, colorMapTexture, + cmapRangeMin, cmapRangeMax, nanColor, useNanColor, hideOutsideRange, + enableMaxSizeControl, aboveRangeColor, useAboveRangeColor, belowRangeColor, + useBelowRangeColor, hasDvarScaling ) _uniformCache; std::string _dataFile; diff --git a/modules/base/shaders/billboardpoint_fs.glsl b/modules/base/shaders/billboardpoint_fs.glsl index b0dfaaeb6b..7b6b51c8e4 100644 --- a/modules/base/shaders/billboardpoint_fs.glsl +++ b/modules/base/shaders/billboardpoint_fs.glsl @@ -26,6 +26,7 @@ flat in float gs_colorParameter; flat in float vs_screenSpaceDepth; +flat in vec4 vs_positionViewSpace; in vec2 texCoord; uniform float opacity; @@ -107,8 +108,7 @@ Fragment getFragment() { Fragment frag; frag.color = fullColor; frag.depth = vs_screenSpaceDepth; - // Setting the position of the billboards to not interact with the ATM - frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); + frag.gPosition = vs_positionViewSpace; frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); return frag; diff --git a/modules/base/shaders/billboardpoint_gs.glsl b/modules/base/shaders/billboardpoint_gs.glsl index 19db521a59..51e58c3774 100644 --- a/modules/base/shaders/billboardpoint_gs.glsl +++ b/modules/base/shaders/billboardpoint_gs.glsl @@ -34,14 +34,16 @@ layout(triangle_strip, max_vertices = 4) out; flat out float gs_colorParameter; out vec2 texCoord; flat out float vs_screenSpaceDepth; +flat out vec4 vs_positionViewSpace; // General settings uniform float scaleExponent; uniform float scaleFactor; uniform int renderOption; -uniform dmat4 cameraViewProjectionMatrix; +uniform dmat4 cameraViewMatrix; +uniform dmat4 projectionMatrix; uniform dmat4 modelMatrix; -uniform bool enablePixelSizeControl; +uniform bool enableMaxSizeControl; uniform bool hasDvarScaling; // RenderOption: CameraViewDirection @@ -52,9 +54,9 @@ uniform vec3 right; uniform dvec3 cameraPosition; uniform vec3 cameraLookUp; -// Pixel size control: true -uniform vec2 screenSize; -uniform float maxBillboardSize; +// Max size control: true +// The max size is an angle, in degrees, for the diameter +uniform float maxAngularSize; const vec2 corners[4] = vec2[4]( vec2(0.0, 0.0), @@ -93,41 +95,35 @@ void main() { scaledUp = scaleMultiply * newUp * 0.5; } - // @TODO: Come up with some better solution for this scaling, that - // also work with non planar projections and multiple viewport resolutions. - if (enablePixelSizeControl) { - vec4 initialPosition = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz - dvec3(scaledRight - scaledUp), dpos.w))); + if (enableMaxSizeControl) { + // Limit the max size of the points, as the angle in "FOV" that the point is allowed + // to take up. Note that the max size is for the diameter, and we need the radius + float desiredAngleRadians = radians(maxAngularSize * 0.5); - vs_screenSpaceDepth = initialPosition.w; + double distanceToCamera = length(dpos.xyz - cameraPosition); + double pointSize = length(dvec3(scaledRight)); + // @TODO (2023-01-05, emmbr) Consider if this atan computation can be optimized using + // approximation + float angle = atan(float(pointSize / distanceToCamera)); - vec4 crossCorner = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + dvec3(scaledRight + scaledUp), dpos.w))); - - // Testing size for rectangular viewport: - vec2 halfViewSize = screenSize * 0.5; - vec2 topRight = crossCorner.xy / crossCorner.w; - vec2 bottomLeft = initialPosition.xy / initialPosition.w; - - // width and height - vec2 sizes = abs(halfViewSize * (topRight - bottomLeft)); - - if (length(sizes) > maxBillboardSize) { - float correctionScale = maxBillboardSize / length(sizes); - scaledRight *= correctionScale; - scaledUp *= correctionScale; + if ((angle > desiredAngleRadians) && (distanceToCamera > 0.0)) { + float correctionScaleFactor = float(distanceToCamera) * tan(desiredAngleRadians) / float(pointSize); + scaledRight *= correctionScaleFactor; + scaledUp *= correctionScaleFactor; } - - // TODO: add checks for wether the generated plane covers too many or too few pixels } - // Saving one matrix multiplication: + dmat4 cameraViewProjectionMatrix = projectionMatrix * cameraViewMatrix; + vec4 dposClip = vec4(cameraViewProjectionMatrix * dpos); vec4 scaledRightClip = scaleFactor * vec4(cameraViewProjectionMatrix * dvec4(scaledRight, 0.0)); vec4 scaledUpClip = scaleFactor * vec4(cameraViewProjectionMatrix * dvec4(scaledUp, 0.0)); + vec4 dposViewSpace= vec4(cameraViewMatrix * dpos); + vs_positionViewSpace = dposViewSpace; + vec4 initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip); vs_screenSpaceDepth = initialPosition.w; vec4 secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip);