iridescence icon indicating copy to clipboard operation
iridescence copied to clipboard

pointcloud buffer update_color_with_indices does not apply alpha value into color

Open Seekerzero opened this issue 1 year ago • 12 comments

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!

Seekerzero avatar Sep 30 '24 19:09 Seekerzero

Would love to hear about this too. I also couldn’t adjust alpha for mesh as well.

n-patiphon avatar Sep 30 '24 23:09 n-patiphon

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.

koide3 avatar Oct 01 '24 06:10 koide3

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!

Seekerzero avatar Oct 01 '24 15:10 Seekerzero

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:

  1. guik::ShaderSetting::transparent, which is enabled by calling make_transparent() or set_alpha(). If this is false, the object is rendered as opaque regardless of the alpha value.
  2. The alpha value, which is determined by vertex colors if the coloring scheme is guik::VertexColor, otherwise determined by the material_color shader 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;
}

koide3 avatar Oct 07 '24 12:10 koide3

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 :)

Seekerzero avatar Oct 07 '24 18:10 Seekerzero

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?

n-patiphon avatar Dec 06 '24 01:12 n-patiphon

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 avatar Dec 07 '24 00:12 koide3

@koide3 Thank you very much for your suggestion. I will give it a try.

n-patiphon avatar Dec 07 '24 10:12 n-patiphon

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:

Image

When alpha is set to 0.5f:

Image

Even when alpha is set to 0.0f:

Image

Did I miss something? I checked the partial rendering, which is also disabled. Thanks!

Seekerzero avatar May 12 '25 22:05 Seekerzero

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!

Seekerzero avatar May 13 '25 22:05 Seekerzero

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).

koide3 avatar May 29 '25 00:05 koide3

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.

Seekerzero avatar May 29 '25 17:05 Seekerzero