Add fading to tube

This commit is contained in:
Malin E
2024-07-12 15:25:22 +02:00
parent d02f30002d
commit 41822e5160
6 changed files with 163 additions and 20 deletions

View File

@@ -101,7 +101,7 @@ namespace {
"Line Fade Amount",
"The amount of the trail that should be faded. If the value is 0 then the "
"trail will have no fading applied. A value of 0.6 will result in a trail "
"where 60% of the extent of the trail will have fading applied to it. In other"
"where 60% of the extent of the trail will have fading applied to it. In other "
"words, the 40% closest to the head of the trail will be solid and the rest "
"will fade until completely transparent at the end of the trail. A value of 1 "
"will result in a trail that starts fading immediately, becoming fully "

View File

@@ -210,6 +210,39 @@ namespace {
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo EnableFadeInfo = {
"EnableFade",
"Enable tube fading of old data",
"Toggles whether the tube should fade older data out. If this value is "
"true, the 'Fade' parameter determines the speed of fading. If this value is "
"false, the entire tube is rendered at full opacity and color.",
openspace::properties::Property::Visibility::NoviceUser
};
constexpr openspace::properties::Property::PropertyInfo TubeLengthInfo = {
"TubeLength",
"Tube Length",
"The extent of the rendered tube. A value of 0 will result in no tube and a "
"value of 1 will result in a tube that covers the entire extent. The setting "
"only applies if 'EnableFade' is true. If it is false, this setting has "
"no effect.",
openspace::properties::Property::Visibility::User
};
constexpr openspace::properties::Property::PropertyInfo TubeFadeAmountInfo = {
"TubeFadeAmount",
"Tube Fade Amount",
"The amount of the tube that should be faded. If the value is 0 then the "
"tube will have no fading applied. A value of 0.6 will result in a tube "
"where 60% of the extent of the tube will have fading applied to it. In other "
"words, the 40% closest to the head of the tube will be solid and the rest "
"will fade until completely transparent at the end of the tube. A value of 1 "
"will result in a tube that starts fading immediately, becoming fully "
"transparent by the end of the tube. This setting only applies if the "
"'EnableFade' value is true. If it is false, this setting has no effect.",
openspace::properties::Property::Visibility::User
};
struct [[codegen::Dictionary(RenderableTube)]] Parameters {
// The input file with data for the tube
std::string file;
@@ -278,6 +311,15 @@ namespace {
// [[codegen::verbatim(ShowAllTubeInfo.description)]]
std::optional<bool> showAllTube;
// [[codegen::verbatim(EnableFadeInfo.description)]]
std::optional<bool> enableFade;
// [[codegen::verbatim(TubeLengthInfo.description)]]
std::optional<float> tubeLength;
// [[codegen::verbatim(TubeFadeAmountInfo.description)]]
std::optional<float> tubeFadeAmount;
// [[codegen::verbatim(KernelDirectoryInfo.description)]]
std::optional<std::string> kernelsDirectory;
};
@@ -365,6 +407,9 @@ RenderableTube::RenderableTube(const ghoul::Dictionary& dictionary)
, _selectedSample(SelectedSampleInfo)
, _sampleLineWidth(SampleLineWidthInfo, 3.f, 1.f, 10.f)
, _sampleColor(SampleColorInfo, glm::vec3(0.f, 0.8f, 0.f), glm::vec3(0.f), glm::vec3(1.f))
, _useTubeFade(EnableFadeInfo, true)
, _tubeLength(TubeLengthInfo, 1.f, 0.f, 1.f)
, _tubeFadeAmount(TubeFadeAmountInfo, 1.f, 0.f, 1.f)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
_dataFile = p.file;
@@ -482,6 +527,15 @@ RenderableTube::RenderableTube(const ghoul::Dictionary& dictionary)
std::filesystem::path folder = absPath(*p.kernelsDirectory);
_kernelsDirectory = absPath(folder).string();
}
_useTubeFade = p.enableFade.value_or(_useTubeFade);
addProperty(_useTubeFade);
_tubeLength = p.tubeLength.value_or(_tubeLength);
addProperty(_tubeLength);
_tubeFadeAmount = p.tubeFadeAmount.value_or(_tubeFadeAmount);
addProperty(_tubeFadeAmount);
}
bool RenderableTube::isReady() const {
@@ -515,6 +569,11 @@ void RenderableTube::initializeGL() {
absPath("${MODULE_BASE}/shaders/tube_cutplane_fs.glsl")
);
// Some uniforms are not used while rendering the cutplane
_shaderCutplane->setIgnoreUniformLocationError(
ghoul::opengl::ProgramObject::IgnoreError::Yes
);
if (_hasColorMapFile) {
_colorSettings.colorMapping->initializeTexture();
_colorSettingsCutplane.colorMapping->initializeTexture();
@@ -538,6 +597,16 @@ void RenderableTube::initializeGL() {
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
1,
GL_UNSIGNED_INT,
GL_FALSE,
sizeof(PolygonVertex),
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, polyId))
);
glEnableVertexAttribArray(2);
glVertexAttribPointer(
2,
3,
GL_FLOAT,
GL_FALSE,
@@ -545,9 +614,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, normal))
);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(
2,
3,
1,
GL_FLOAT,
GL_FALSE,
@@ -555,9 +624,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, value))
);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glVertexAttribPointer(
3,
4,
2,
GL_FLOAT,
GL_FALSE,
@@ -565,9 +634,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, tex))
);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribPointer(
4,
5,
2,
GL_FLOAT,
GL_FALSE,
@@ -590,6 +659,16 @@ void RenderableTube::initializeGL() {
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
1,
GL_UNSIGNED_INT,
GL_FALSE,
sizeof(PolygonVertex),
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, polyId))
);
glEnableVertexAttribArray(2);
glVertexAttribPointer(
2,
3,
GL_FLOAT,
GL_FALSE,
@@ -597,9 +676,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, normal))
);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glVertexAttribPointer(
2,
3,
1,
GL_FLOAT,
GL_FALSE,
@@ -607,9 +686,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, value))
);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glVertexAttribPointer(
3,
4,
2,
GL_FLOAT,
GL_FALSE,
@@ -617,9 +696,9 @@ void RenderableTube::initializeGL() {
reinterpret_cast<const GLvoid*>(offsetof(PolygonVertex, tex))
);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribPointer(
4,
5,
2,
GL_FLOAT,
GL_FALSE,
@@ -1187,6 +1266,8 @@ void RenderableTube::addEdge(int polygonIndex, const TimePolygon const* polygon,
centerPoint.position[1] = polygon->center.y;
centerPoint.position[2] = polygon->center.z;
centerPoint.polyId = polygonIndex;
// Calculate the normal, we know there are at least 3 point in the polygon
glm::dvec3 v0 = polygon->center;
glm::dvec3 v1 = polygon->points[0].coordinate;
@@ -1224,6 +1305,8 @@ void RenderableTube::addEdge(int polygonIndex, const TimePolygon const* polygon,
sidePoint.position[1] = polygon->points[pointIndex].coordinate.y;
sidePoint.position[2] = polygon->points[pointIndex].coordinate.z;
sidePoint.polyId = polygonIndex;
sidePoint.normal[0] = normal.x;
sidePoint.normal[1] = normal.y;
sidePoint.normal[2] = normal.z;
@@ -1297,6 +1380,8 @@ void RenderableTube::addSmoothSection(int polygonIndex, const TimePolygon const*
sidePoint.position[1] = polygon->points[pointIndex].coordinate.y;
sidePoint.position[2] = polygon->points[pointIndex].coordinate.z;
sidePoint.polyId = polygonIndex;
// Calculate normal
glm::dvec3 normal =
polygon->points[pointIndex].coordinate - polygon->center;
@@ -1401,6 +1486,12 @@ void RenderableTube::addLowPolySection(int polygonIndex, const TimePolygon const
sidePointV3.position[1] = v3.coordinate.y;
sidePointV3.position[2] = v3.coordinate.z;
// Polygon Index
sidePointV0.polyId = polygonIndex;
sidePointV1.polyId = polygonIndex + 1;
sidePointV2.polyId = polygonIndex + 1;
sidePointV3.polyId = polygonIndex;
// Normal
glm::dvec3 toNextPoly = glm::normalize(v1.coordinate - v0.coordinate);
glm::dvec3 toNextPoint = glm::normalize(v3.coordinate - v0.coordinate);
@@ -1776,6 +1867,18 @@ void RenderableTube::setCommonUniforms(ghoul::opengl::ProgramObject* shader, con
shader->setUniform("diffuseIntensity", _shading.diffuseIntensity);
shader->setUniform("specularIntensity", _shading.specularIntensity);
}
// Fade calculation and settings
shader->setUniform("useTubeFade", _useTubeFade);
if (_useTubeFade) {
const float startPoint = 1.f - _tubeLength;
const float remainingRange = 1.f - startPoint;
const float delta = remainingRange * _tubeFadeAmount;
const float endPoint = std::min(startPoint + delta, 1.f);
shader->setUniform("tubeLength", startPoint);
shader->setUniform("tubeFadeAmount", endPoint);
shader->setUniform("nVisiblePoly", static_cast<int>(_firstPolygonAfterNow));
}
}
void RenderableTube::render(const RenderData& data, RendererTasks&) {

View File

@@ -64,6 +64,7 @@ public:
private:
struct PolygonVertex {
GLdouble position[3];
GLuint polyId;
GLfloat normal[3];
GLfloat value;
GLfloat tex[2];
@@ -157,6 +158,9 @@ private:
properties::StringProperty _selectedSample;
properties::FloatProperty _sampleLineWidth;
properties::Vec3Property _sampleColor;
properties::BoolProperty _useTubeFade;
properties::FloatProperty _tubeLength;
properties::FloatProperty _tubeFadeAmount;
std::vector<float> _lightIntensitiesBuffer;
std::vector<glm::vec3> _lightDirectionsViewSpaceBuffer;

View File

@@ -25,10 +25,11 @@
#version __CONTEXT__
layout (location = 0) in dvec3 in_position;
layout (location = 1) in vec3 in_normal;
layout (location = 2) in float in_value;
layout (location = 3) in vec2 in_st_prev;
layout (location = 4) in vec2 in_st_next;
layout (location = 1) in vec3 in_polyId;
layout (location = 2) in vec3 in_normal;
layout (location = 3) in float in_value;
layout (location = 4) in vec2 in_st_prev;
layout (location = 5) in vec2 in_st_next;
out float vs_depth;
out vec3 vs_normal;

View File

@@ -28,6 +28,7 @@ in float vs_depth;
in vec3 vs_normal;
in vec4 vs_positionViewSpace;
in float vs_value;
in float fade;
uniform float opacity;
uniform vec3 color;
@@ -135,7 +136,7 @@ Fragment getFragment() {
frag.gPosition = vs_positionViewSpace;
frag.gNormal = vec4(vs_normal, 0.0);
frag.disableLDR2HDR = true;
frag.color.a = opacity;
frag.color.a = fade * opacity;
return frag;
}

View File

@@ -25,18 +25,26 @@
#version __CONTEXT__
layout (location = 0) in dvec3 in_position;
layout (location = 1) in vec3 in_normal;
layout (location = 2) in float in_value;
layout (location = 1) in vec3 in_polyId;
layout (location = 2) in vec3 in_normal;
layout (location = 3) in float in_value;
out float vs_depth;
out uint vs_polyId;
out vec3 vs_normal;
out vec4 vs_positionViewSpace;
out float vs_value;
out float fade;
uniform dmat4 modelViewTransform;
uniform dmat4 projectionTransform;
uniform mat3 normalTransform;
uniform int nVisiblePoly;
uniform bool useTubeFade;
uniform float tubeLength;
uniform float tubeFadeAmount;
void main() {
vs_value = in_value;
vs_normal = normalize(normalTransform * in_normal);
@@ -48,6 +56,32 @@ void main() {
dvec4 positionScreenSpace = positionClipSpace;
positionScreenSpace.z = 0.0;
// Calculate the tube fade
if (useTubeFade) {
// Convert the index to a [0,1] range
float current = float(in_polyId) / float(nVisiblePoly);
float fadeEnd = tubeLength;
float fadeStart = tubeFadeAmount;
float fadeValue = 0.0;
if (current <= fadeEnd) {
fadeValue = 0.0;
}
else if (current > fadeEnd && current < fadeStart) {
float delta = fadeStart - fadeEnd;
fadeValue = (current - fadeEnd) / delta;
}
else {
fadeValue = 1.0;
}
fade = clamp(fadeValue, 0.0, 1.0);
}
else {
fade = 1.0;
}
gl_Position = vec4(positionScreenSpace);
vs_depth = float(positionScreenSpace.w);
}