diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index ae37a25c30..47f5af91dd 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -140,6 +140,7 @@ protected: // Border properties::FloatProperty _borderWidth; properties::Vec3Property _borderColor; + properties::BoolProperty _borderFeather; properties::FloatProperty _scale; properties::FloatProperty _gammaOffset; @@ -149,7 +150,7 @@ protected: glm::ivec2 _objectSize = glm::ivec2(0); UniformCache(color, opacity, blackoutFactor, hue, value, saturation, mvpMatrix, tex, - backgroundColor, gamma, borderColor, borderWidth) _uniformCache; + backgroundColor, gamma, borderColor, borderWidth, borderFeather) _uniformCache; std::unique_ptr _shader; }; diff --git a/modules/base/shaders/screenspace_fs.glsl b/modules/base/shaders/screenspace_fs.glsl index 88be411afb..68402103a1 100644 --- a/modules/base/shaders/screenspace_fs.glsl +++ b/modules/base/shaders/screenspace_fs.glsl @@ -40,6 +40,7 @@ uniform float saturation; uniform float gamma = 1.0; uniform vec2 borderWidth = vec2(0.1); uniform vec3 borderColor = vec3(0.0); +uniform int borderFeather = 0; Fragment getFragment() { @@ -54,6 +55,13 @@ Fragment getFragment() { vs_st.y < borderWidth.y || vs_st.y > 1 - borderWidth.y) { frag.color = vec4(borderColor, opacity); + if (borderFeather == 1) { + vec2 f1 = vs_st / borderWidth; + float g1 = min(f1.x, f1.y); + vec2 f2 = (vec2(1) - vs_st) / borderWidth; + float g2 = min(f2.x, f2.y); + frag.color *= min(g1, g2); + } } if (frag.color.a == 0.0) { diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 5e7e7ccb78..c2fc14d38a 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -169,6 +169,13 @@ namespace { openspace::properties::Property::Visibility::NoviceUser }; + constexpr openspace::properties::Property::PropertyInfo BorderFeatherInfo = { + "BorderFeather", + "Border Feather", + "If this value is enabled and a border width is set, the border will be rendered " + "as a feathered border rather than a hard corner." + }; + float wrap(float value, float min, float max) { return glm::mod(value - min, max - min) + min; } @@ -222,6 +229,9 @@ namespace { // [[codegen::verbatim(BorderColorInfo.description)]] std::optional borderColor [[codegen::color()]]; + // [[codegen::verbatim(BorderFeatherInfo.description)]] + std::optional borderFeather; + // [[codegen::verbatim(ScaleInfo.description)]] std::optional scale; @@ -318,6 +328,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary ) , _borderWidth(BorderWidthInfo, 0.f, 0.f, 1000.f) , _borderColor(BorderColorInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) + , _borderFeather(BorderFeatherInfo, false) , _scale(ScaleInfo, 0.25f, 0.f, 2.f) , _gammaOffset(GammaOffsetInfo, 0.f, -1.f, 10.f) , _multiplyColor(MultiplyColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) @@ -368,6 +379,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary addProperty(_borderColor); addProperty(_borderWidth); + addProperty(_borderFeather); _borderWidth = p.borderWidth.value_or(_borderWidth); @@ -667,6 +679,7 @@ void ScreenSpaceRenderable::draw(const glm::mat4& modelTransform, _shader->setUniform(_uniformCache.backgroundColor, _backgroundColor); _shader->setUniform(_uniformCache.borderWidth, borderUV); _shader->setUniform(_uniformCache.borderColor, _borderColor); + _shader->setUniform(_uniformCache.borderFeather, _borderFeather); _shader->setUniform( _uniformCache.mvpMatrix, global::renderEngine->scene()->camera()->viewProjectionMatrix() * modelTransform