koide3 / iridescence

3D visualization library for rapid prototyping of 3D algorithms
https://koide3.github.io/iridescence/
MIT License
296 stars 32 forks source link

pointcloud buffer update_color_with_indices does not apply alpha value into color #141

Open Seekerzero opened 1 week ago

Seekerzero commented 1 week ago

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!

n-patiphon commented 1 week ago

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

koide3 commented 1 week ago

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.

Seekerzero commented 1 week ago

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!

koide3 commented 5 days ago

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;
}
Seekerzero commented 5 days ago

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