mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-23 04:48:53 -05:00
Fix image dilation (closing #108)
- Using pixel(=texel) coordinates and integer offsets - Using a single channel stencil texture instead of a 4-channel one
This commit is contained in:
@@ -30,6 +30,8 @@ out vec4 color;
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D stencil;
|
||||
|
||||
// We conside the 8-neighborhood of a texel, so going a stepsize of '1' in both
|
||||
// directions
|
||||
vec2 offsets[8] = {
|
||||
vec2(-1.0, -1.0),
|
||||
vec2(-1.0, 0.0),
|
||||
@@ -41,38 +43,52 @@ vec2 offsets[8] = {
|
||||
vec2(1.0, 1.0)
|
||||
};
|
||||
|
||||
vec3 gatherColors(vec2 position) {
|
||||
// Collect the contributing colors from the neighboring texels and return the
|
||||
// averaged value of all texels that passed the masking test based on 'stencil'
|
||||
vec3 gatherNeighboringColors() {
|
||||
vec2 texSize = textureSize(tex, 0);
|
||||
|
||||
// The total number of contributing texels
|
||||
int nContributions = 0;
|
||||
|
||||
// The summed color of all contributing texels
|
||||
vec3 totalColor = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// gl_FragCoord is in pixel coordinates; the ProjectionComponent sets
|
||||
// the viewport such that pixels=texels, so we can use gl_FragCoord as an
|
||||
// integer texel coordinate
|
||||
// First offsetting them, then dividing by the texture size to get to [0,1]
|
||||
vec2 samplePosition = (gl_FragCoord.xy + offsets[i]) / texSize;
|
||||
|
||||
// The stencelling determines the areas that we have to enlarge, such that we
|
||||
// do not enlarge a previously enlarged area
|
||||
if (texture(stencil, samplePosition).r != 0.0) {
|
||||
vec3 c = texture(tex, samplePosition).rgb;
|
||||
totalColor += c;
|
||||
totalColor += texture(tex, samplePosition).rgb;
|
||||
nContributions++;
|
||||
}
|
||||
}
|
||||
|
||||
return totalColor / nContributions;
|
||||
// GLSL normally doesn't have a problem taking vec3(0.0)/0.0 but we don't want to
|
||||
// tempt the compiler gods
|
||||
if (nContributions > 0) {
|
||||
return totalColor / nContributions;
|
||||
}
|
||||
else {
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 c = texture(tex, vs_uv);
|
||||
float s = texture(stencil, vs_uv).r;
|
||||
|
||||
if (s == 0.0) {
|
||||
if (texture(stencil, vs_uv).r == 0.0) {
|
||||
// This means that the current fragment/texel we are looking at has not been
|
||||
// projected on and we only want to do the dilation into these texels
|
||||
|
||||
color = vec4(gatherColors(vs_uv), 1.0);
|
||||
color = vec4(gatherNeighboringColors(), 1.0);
|
||||
}
|
||||
else {
|
||||
// We are in a region where an image has been projected, so we can reuse the
|
||||
// already sampled version
|
||||
color = c;
|
||||
color = texture(tex, vs_uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
in vec4 vs_position;
|
||||
in vec4 vs_normal;
|
||||
in vec2 vs_uv;
|
||||
in vec4 ProjTexCoord;
|
||||
|
||||
layout (location = 0) out vec4 color;
|
||||
layout (location = 0) out vec4 color;
|
||||
// Even though the stencel texture is only a single channel, we still need to
|
||||
// output a vec4, or the result will disappear
|
||||
layout (location = 1) out vec4 stencil;
|
||||
|
||||
uniform sampler2D projectionTexture;
|
||||
|
||||
@@ -558,7 +558,8 @@ bool ProjectionComponent::generateProjectionLayerTexture() {
|
||||
|
||||
_dilation.stencilTexture = std::make_unique<ghoul::opengl::Texture>(
|
||||
glm::uvec3(maxSize, maxSize / 2, 1),
|
||||
ghoul::opengl::Texture::Format::RGBA
|
||||
ghoul::opengl::Texture::Format::Red,
|
||||
ghoul::opengl::Texture::Format::Red
|
||||
);
|
||||
|
||||
if (_dilation.stencilTexture) {
|
||||
|
||||
Reference in New Issue
Block a user