blur path to avoid sharp edges

This commit is contained in:
Joakim Kilby
2023-07-21 14:12:09 +02:00
parent 536ac29c94
commit 4a489fdae5
6 changed files with 312 additions and 10 deletions

View File

@@ -0,0 +1,87 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include "fragment.glsl"
uniform sampler2D tex0;
uniform vec2 resolution;
uniform vec2 direction;
uniform int kernelSize;
in vec2 uv;
vec4 blur5(sampler2D tex, vec2 uv, vec2 res, vec2 dir) {
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.3333333333333333) * dir;
color += texture2D(tex, uv) * 0.29411764705882354;
color += texture2D(tex, uv + (off1 / res)) * 0.35294117647058826;
color += texture2D(tex, uv - (off1 / res)) * 0.35294117647058826;
return color;
}
vec4 blur9(sampler2D tex, vec2 uv, vec2 res, vec2 dir) {
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.3846153846) * dir;
vec2 off2 = vec2(3.2307692308) * dir;
color += texture2D(tex, uv) * 0.2270270270;
color += texture2D(tex, uv + (off1 / res)) * 0.3162162162;
color += texture2D(tex, uv - (off1 / res)) * 0.3162162162;
color += texture2D(tex, uv + (off2 / res)) * 0.0702702703;
color += texture2D(tex, uv - (off2 / res)) * 0.0702702703;
return color;
}
vec4 blur13(sampler2D tex, vec2 uv, vec2 res, vec2 dir) {
vec4 color;
vec2 off1 = vec2(1.3846153846) * dir;
vec2 off2 = vec2(3.2307692308) * dir;
vec2 off3 = vec2(5.176470588235294) * dir;
color += texture2D(tex, uv) * 0.1964825501511404;
color += texture2D(tex, uv + (off1 / res)) * 0.2969069646728344;
color += texture2D(tex, uv - (off1 / res)) * 0.2969069646728344;
color += texture2D(tex, uv + (off2 / res)) * 0.09447039785044732;
color += texture2D(tex, uv - (off2 / res)) * 0.09447039785044732;
color += texture2D(tex, uv + (off3 / res)) * 0.010381362401148057;
color += texture2D(tex, uv - (off3 / res)) * 0.010381362401148057;
return color;
}
Fragment getFragment() {
Fragment frag;
frag.disableLDR2HDR = true;
if (kernelSize == 0) {
frag.color = texture(tex0, uv);
}
if (kernelSize == 5) {
frag.color = blur5(tex0, uv, resolution, direction);
}
if (kernelSize == 9) {
frag.color = blur9(tex0, uv, resolution, direction);
}
if (kernelSize == 13) {
frag.color = blur13(tex0, uv, resolution, direction);
}
return frag;
}

View File

@@ -0,0 +1,35 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2023 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(location=0) in vec2 vertex_position;
out vec2 uv;
void main()
{
uv = (vertex_position + 1) * 0.5;
gl_Position = vec4(vertex_position, 0.0, 1.0);
}

View File

@@ -29,6 +29,7 @@ layout (triangle_strip, max_vertices = 6) out;
uniform vec2 viewport;
uniform float lineWidth;
uniform int nPoints;
void main()
{
@@ -98,12 +99,14 @@ void main()
gl_Position = pos;
EmitVertex();
pos = p2;
pos.xy -= nn * lineWidth * 0.5;
pos.xy = 2 * pos.xy / viewport - 1;
pos.xyz *= pos.w;
gl_Position = pos;
EmitVertex();
if (gl_PrimitiveIDIn < nPoints - 3) {
pos = p2;
pos.xy -= nn * lineWidth * 0.5;
pos.xy = 2 * pos.xy / viewport - 1;
pos.xyz *= pos.w;
gl_Position = pos;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -69,7 +69,6 @@ namespace {
// Global flags to modify the RenderableGlobe
constexpr bool LimitLevelByAvailableData = true;
constexpr bool PerformFrustumCulling = false;
constexpr bool PreformHorizonCulling = true;
// Shadow structure

View File

@@ -48,6 +48,13 @@ namespace {
Points,
};
enum class KernelSize {
Disabled = 0,
Five = 5,
Nine = 9,
Thirteen = 13
};
constexpr openspace::properties::Property::PropertyInfo JSONPathInfo = {
"JSON",
"JSON",
@@ -83,6 +90,14 @@ namespace {
openspace::properties::Property::Visibility::User
};
constexpr openspace::properties::Property::PropertyInfo KernelSizeInfo = {
"KernelSize",
"Kernel size",
"Specifies the kernel size of the gaussian blur filter used to smooth out"
"the edges of rendered path.",
openspace::properties::Property::Visibility::User
};
constexpr openspace::properties::Property::PropertyInfo RenderFullAsdfInfo = {
"RenderFullAsdf",
"Render Full Asdf",
@@ -126,6 +141,15 @@ namespace {
// [[codegen::verbatim(RenderingModeInfo.description)]]
std::optional<RenderingMode> renderingMode;
enum class [[codegen::map(KernelSize)]] KernelSize {
Disabled = 0,
Five = 5,
Nine = 9,
Thirteen = 13
};
// [[codegen::verbatim(KernelSizeInfo.description)]]
std::optional<KernelSize> kernelSize;
};
#include "asdftileprovider_codegen.cpp"
@@ -142,6 +166,8 @@ AsdfTileProvider::AsdfTileProvider(const ghoul::Dictionary& dictionary) :
_renderFullAsdf(RenderFullAsdfInfo, false),
_renderingMode(RenderingModeInfo,
openspace::properties::OptionProperty::DisplayType::Dropdown),
_kernelSize(KernelSizeInfo,
openspace::properties::OptionProperty::DisplayType::Dropdown),
_start(0.0),
_fbo(0),
_vao(0),
@@ -173,6 +199,14 @@ AsdfTileProvider::AsdfTileProvider(const ghoul::Dictionary& dictionary) :
});
addProperty(_renderingMode);
_kernelSize.addOptions({
{ static_cast<int>(KernelSize::Disabled), "Disabled" },
{ static_cast<int>(KernelSize::Five), "5" },
{ static_cast<int>(KernelSize::Nine), "9" },
{ static_cast<int>(KernelSize::Thirteen), "13" },
});
addProperty(_kernelSize);
const Parameters p = codegen::bake<Parameters>(dictionary);
_JSONPath = p.JSON;
_startTime = p.startTime;
@@ -183,6 +217,9 @@ AsdfTileProvider::AsdfTileProvider(const ghoul::Dictionary& dictionary) :
if (p.renderingMode.has_value()) {
_renderingMode = static_cast<int>(codegen::map<RenderingMode>(*p.renderingMode));
}
if (p.kernelSize.has_value()) {
_kernelSize = static_cast<int>(codegen::map<KernelSize>(*p.kernelSize));
}
}
AsdfTileProvider::~AsdfTileProvider() {}
@@ -276,6 +313,17 @@ void AsdfTileProvider::internalInitialize() {
GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_BORDER
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR
);
glTexImage2D(
GL_TEXTURE_2D,
0,
@@ -289,6 +337,70 @@ void AsdfTileProvider::internalInitialize() {
);
glBindTexture(GL_TEXTURE_2D, 0);
static constexpr GLfloat vertices[] = {
-1.f, -1.f,
1.f, -1.f,
-1.f, 1.f,
-1.f, 1.f,
1.f, -1.f,
1.f, 1.f,
};
glGenVertexArrays(1, &_quadVao);
glBindVertexArray(_quadVao);
glGenBuffers(1, &_quadVbo);
glBindBuffer(GL_ARRAY_BUFFER, _quadVbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
2 * sizeof(GL_FLOAT),
reinterpret_cast<void*>(0)
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
_texture2 = std::make_unique<ghoul::opengl::Texture>(
glm::uvec3(_rendertargetDimensions.x, _rendertargetDimensions.y, 1),
GL_TEXTURE_2D
);
glBindTexture(GL_TEXTURE_2D, *_texture2);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR
);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
static_cast<GLsizei>(_rendertargetDimensions.x),
static_cast<GLsizei>(_rendertargetDimensions.y),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr
);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &_fbo2);
_program2 = global::renderEngine->buildRenderProgram(
"AsdfProgram2",
absPath("${MODULE_GLOBEBROWSING}/shaders/asdf_blur_vs.glsl"),
absPath("${MODULE_GLOBEBROWSING}/shaders/asdf_blur_fs.glsl")
);
update();
}
@@ -433,7 +545,6 @@ void AsdfTileProvider::update() {
static_cast<GLsizei>(_rendertargetDimensions.y)
);
//glClearColor(.2f, .2f, .2f, 0.f);
glClearColor(.0f, .0f, .0f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
@@ -441,8 +552,7 @@ void AsdfTileProvider::update() {
_program->setUniform("viewport",
glm::vec2(_rendertargetDimensions.x, _rendertargetDimensions.y));
_program->setUniform("lineWidth", _lineWidth);
const float blend = 2.0;
//_program->setUniform("blendFactor", blend);
_program->setUniform("nPoints", static_cast<GLint>(points.size()-1));
_program->setUniform("color", _color);
_program->setUniform("projectionMatrix", projection);
@@ -464,6 +574,68 @@ void AsdfTileProvider::update() {
glDrawArrays(GL_POINTS, 0, points.size());
}
if (_kernelSize.value() != static_cast<int>(KernelSize::Disabled)) {
// Two-pass blur
// First pass - horizontally
glBindFramebuffer(GL_FRAMEBUFFER, _fbo2);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*_texture2.get(),
0
);
glViewport(
0,
0,
static_cast<GLsizei>(_rendertargetDimensions.x),
static_cast<GLsizei>(_rendertargetDimensions.y)
);
glClear(GL_COLOR_BUFFER_BIT);
_program2->activate();
_program2->setUniform("resolution",
glm::vec2(_rendertargetDimensions.x, _rendertargetDimensions.y));
_program2->setUniform("direction", glm::vec2(1, 0));
_program2->setUniform("kernelSize", _kernelSize.value());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *_texture.get());
glBindVertexArray(_quadVao);
glDrawArrays(GL_TRIANGLES, 0, 6);
// First pass - vertically
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
*_texture.get(),
0
);
glViewport(
0,
0,
static_cast<GLsizei>(_rendertargetDimensions.x),
static_cast<GLsizei>(_rendertargetDimensions.y)
);
glClear(GL_COLOR_BUFFER_BIT);
_program2->activate();
_program2->setUniform("resolution",
glm::vec2(_rendertargetDimensions.x, _rendertargetDimensions.y));
_program2->setUniform("direction", glm::vec2(0, 1));
_program2->setUniform("kernelSize", _kernelSize.value());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *_texture2.get());
glBindVertexArray(_quadVao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
// Reset FBO, shader program and viewport
glUseProgram(prevProgram);
glBindFramebuffer(GL_FRAMEBUFFER, prevFBO);

View File

@@ -62,6 +62,7 @@ private:
properties::FloatProperty _lineWidth;
properties::BoolProperty _renderFullAsdf;
properties::OptionProperty _renderingMode;
properties::OptionProperty _kernelSize;
struct Feature {
double _lat, _lon;
@@ -70,12 +71,17 @@ private:
double _start = 0.0;
GLuint _fbo = 0;
GLuint _fbo2 = 0;
GLuint _vao = 0;
GLuint _vbo = 0;
GLuint _quadVao = 0;
GLuint _quadVbo = 0;
GeodeticPatch _bounds;
glm::ivec2 _rendertargetDimensions;
std::unique_ptr<ghoul::opengl::ProgramObject> _program;
std::unique_ptr<ghoul::opengl::ProgramObject> _program2;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::unique_ptr<ghoul::opengl::Texture> _texture2;
std::vector<Feature> _features;
};