google / neuroglancer

WebGL-based viewer for volumetric data
Apache License 2.0
1.03k stars 287 forks source link

Max projection volume rendering with picking #552

Closed seankmartin closed 3 months ago

seankmartin commented 4 months ago

Min and max projection VR modes with picking

Adds:

  1. Min and Max projection modes to the volume rendering. Both of these work by computing the min/max over rays within single chunks in the shader, and then combining across chunks via depth testing.
  2. Experimental picking works in Min and Max mode because we know the depth of the max/min sample.
  3. First pass documentation about volume rendering.

Experimental change, open to thoughts:

Moved the axis helper visualisation to draw after volume rendering, so that it draws on top of it. Previously the axis helper was getting occluded in high-opacity volume rendering.

Possible future changes

fcollman commented 3 months ago

The max mode does not appear to work for RGB or RGBA emitters. Can we make it work for those? Or make picking also work for non max projection ?

seankmartin commented 3 months ago

Hi @fcollman,

There is a bit of an admittedly unfortunate pattern needed for RGB and RGBA emitters. There needs to be an emitIntensity(float_in_0_1_range) call before the color emission. For example, in the shader:

#uicontrol invlerp normalized
void main() {
  float val = normalized();
  emitIntensity(val);
  emitRGB(colormapJet(val));
}

It's possible we could do something like having a default intensity in RGB mode which is the max(color) or a normalized sum of the color, and in RGBA, the opacity is used. In that case, emitIntensity would override the default intensity. In that way, the RGB and RGBA modes would still work without needing to call emitIntensity - but could still be overwritten.

For the picking in non-max mode, that's a little trickier. We could provide a dropdown in the UI, with modes "off", "max" and "min", something like "picking in non-max VR" (probably a better name). This dropdown would enable performing a second rendering pass if volume_rendering="on" which does a max/min projection in the background for picking purposes.

What do you think of these? (also for @jbms)

fcollman commented 3 months ago

I think as long as there is a route to rendering that has picking and supports RGB and RGBA that would be good… I would support an automatic fallback for RGB and RGBA intensities.

seankmartin commented 3 months ago

Hi @jbms,

I implemented something along the lines of the heuristic we discussed for the default max projection intensity. The value of the first invlerp called is used as the default intensity, if there is an invlerp call. It should work with transfer functions too, because they call an invlerp.

Currently, for emitTransparent - emitIntensity(0.0) is called, and for emitGrayscale(val) - emitIntensity(val) is called, so those would both work without an invlerp call.

Please let me know if you had something else mind, either in the heuristic used, or the implementation.

seankmartin commented 3 months ago

For consistency with other emission modes, I've removed the call to emitIntensity(value) for emitGrayscale(value). Now only for emitTransparent(), emitIntensity(0.0) is called.