pointcloud buffer update_color_with_indices does not apply alpha value into color
Hi Koide,
I just found that the alpha value (transparent) value was not correctly rendering (can't change the transparency). Did I miss any setup? If not, can you test it on your end?
Thanks!
Would love to hear about this too. I also couldn’t adjust alpha for mesh as well.
What coloring scheme are you using?
If you are using guik::VertexColor, the alpha values of vertex colors are prioritized over the material alpha value (value of set_alpha). So, if vertices have alpha=1, they will not be transparent. For other coloring schemes (guik::Rainbow and guik::FlatColor), set_alpha should work.
I think I should add documentation about the transparency handling.
Hi Koide, Thanks for your quick response!
If I understand this correctly, does that mean that the alpha value of guik::VertexColor can't be changed once it is set? Since I created the color point cloud buffer with color and then use the update_color_with_indices (basically all indices) with a vector of Eigen::Vector4f (with a same transparent color), and it didn't work. I remember this function does change the vertex color of the point cloud, right?
Thanks again!
You can still change the transparency of objects registered with guik::VertexColor by changing vertex colors using update_color_with_indices(). For example, in the following code, we can see the transparency is changed with update_color_with_indices().
I think a confusing point is that there are several states to control the object transparency. To clarify:
-
guik::ShaderSetting::transparent, which is enabled by callingmake_transparent()orset_alpha(). If this isfalse, the object is rendered as opaque regardless of the alpha value. - The alpha value, which is determined by vertex colors if the coloring scheme is
guik::VertexColor, otherwise determined by thematerial_colorshader variable (set_alpha()overrides the alpha of the material color).
#include <numeric>
#include <iostream>
#include <glk/pointcloud_buffer.hpp>
#include <glk/primitives/icosahedron.hpp>
#include <guik/viewer/light_viewer.hpp>
int main(int argc, char** argv) {
auto viewer = guik::viewer();
viewer->disable_xy_grid();
viewer->update_cube("bg_plate", guik::FlatBlue().translate(0.0f, 0.0f, -5.0f).scale(5.0f, 5.0f, 0.1f));
// Random vertices
glk::Icosahedron icosa;
icosa.subdivide();
icosa.subdivide();
// Green vertices with alpha = 0.25
float vertex_alpha = 0.25f;
std::vector<Eigen::Vector4f> colors(icosa.vertices.size());
std::fill(colors.begin(), colors.end(), Eigen::Vector4f(0.0f, 1.0f, 0.0f, vertex_alpha));
auto cloud_buffer = std::make_shared<glk::PointCloudBuffer>(icosa.vertices);
cloud_buffer->add_color(colors);
// 2. Draw the vertices without transparency (without make_transparent())
viewer->update_drawable("points", cloud_buffer, guik::VertexColor());
viewer->spin_until_click();
// 3. Draw the vertices with transparency (with make_transparent())
viewer->update_drawable("points", cloud_buffer, guik::VertexColor().make_transparent());
viewer->spin_until_click();
// 2. Update the color of the vertices with alpha = 0.95
vertex_alpha = 0.95f;
std::fill(colors.begin(), colors.end(), Eigen::Vector4f(0.0f, 1.0f, 0.0f, vertex_alpha));
std::vector<unsigned int> indices(colors.size());
std::iota(indices.begin(), indices.end(), 0);
cloud_buffer->update_color_with_indices(colors, indices);
viewer->spin_until_click();
// 3. set_alpha() doesn't change the object transparency here because guik::VertexColor prioritizes vertex alpha
viewer->update_drawable("points", cloud_buffer, guik::VertexColor().set_alpha(0.2f));
viewer->spin_until_click();
// 4. guik::FlatColor prioritizes material alpha (set_alpha) over vertex alpha
viewer->update_drawable("points", cloud_buffer, guik::FlatGreen().set_alpha(0.2f));
viewer->spin_until_click();
return 0;
}
Thanks for your detailed instructions! Now, it works on my end. I think it would be helpful if you could put this in the shader setting section for more people to get reference :)
Thank you for sharing the instructions! How about point cloud buffer that's colored with add_intensity? Is there a way to get the colors vector and adjust alpha?
add_intensity converts intensity data to colors via colormap. I think directly using the colormap function (like below) is easier to fine control the appearance rather than using add_intensity.
double intensity = 0.5; // normalized intensity in [0, 1]
double alpha = 0.5;
Eigen::Vector4f color = glk::colormapf(glk::COLORMAP::TURBO, intensity);
color[3] = alpha;
https://github.com/koide3/iridescence/blob/675f87c38c2c68e522f8f84457dbaa3dc4831222/include/glk/colormap.hpp#L12
@koide3 Thank you very much for your suggestion. I will give it a try.
Hi @koide3 ,
I was re-implementing your cookbook demo for cropping the point cloud. I found that the cube transparency is not correctly displayed. The render cube will cover the point cloud inside it, whatever the transparency value is.
The code implementation is
guik::FlatColor({1.0f, 0.5f, 0.0f, 1.0f}, box_matrix->model_matrix()).make_transparent()cpp
Please check the following screenshots. The cube covers the display of the teapot point cloud with any value set to alpha.
When alpha is set to 1.0f:
When alpha is set to 0.5f:
Even when alpha is set to 0.0f:
Did I miss something? I checked the partial rendering, which is also disabled. Thanks!
Hi @koide3,
I figured out the issue; the problem is coming from the order of creating the drawables.
In my implementation, I initialize the cube after creating the point buffer, which differs from your example, which creates the cube first.
I verified my thought by creating the cube at the start of the program and then grepping it back using its drawable name in a later operation. And it works.
Do you think there is a way to solve this issue?
One dumb way I can do it is to create the cube first, but translate it to a place that can't be seen (just like some old game engine did). And then translate it back when needed.
Many thanks!
Hi @Seekerzero ,
I guess the teapot was marked as a transparent object? If so, it may be hidden by the foreground transparent object (i.e., the cube) depending on the rendering order (https://learnopengl.com/Advanced-OpenGL/Blending). In that case, explicitly setting alpha=1.0 (setting.set_alpha(1.0)) would resolve the issue (iridescence first draws opaque objects and then transparent objects).
Hello @koide3, Thanks for the explanation, the materials also help a lot! I can try disabling the transparency of the point cloud to see if that solves the issue.