Kitware / vtk-js

Visualization Toolkit for the Web
https://kitware.github.io/vtk-js/
BSD 3-Clause "New" or "Revised" License
1.24k stars 373 forks source link

XR Volume Rendering #2322

Closed tbirdso closed 2 years ago

tbirdso commented 2 years ago

Need

WebXR examples currently only encompass surface rendering. It would be useful to add an example demonstrating volume rendering as well.

Feature

Two changes are needed:

AR volume rendering was previously observed to work in the WebXR Emulator but the vtk.js scene did not appear when viewing on mobile.

tbirdso commented 2 years ago

Investigation results:

tbirdso commented 2 years ago

@floryst Reminder that this exists, no particular rush though. Would be helpful to have 1) any console printouts from volume rendering on Android and 2) your thoughts on parameters that might affect the clipping plane, which seems to be set to the default (far plane 1000.0)

floryst commented 2 years ago

I got the "Start AR" button to work with some CSS modification, and got a volume to show up in AR on the ar-apps branch.

Touching the screen did throw the following error (index.js:437):

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'buttons')
    at index.js:437:62
    at XRInputSourceArray.forEach (<anonymous>)
    at Object.publicAPI.updateXRGamepads (index.js:422:28)
    at _callee3$ (index.js:418:8)
    at tryCatch (polyfill.js:5901:40)
    at Generator.invoke [as _invoke] (polyfill.js:6135:22)
    at Generator.prototype.<computed> [as next] (polyfill.js:5953:21)
    at asyncGeneratorStep (Volume.js:11:1)
    at _next (Volume.js:11:1)
    at Volume.js:11:1

I'm also experiencing the clipping plane issue. The range should be much wider in order, otherwise it's difficult to use.

floryst commented 2 years ago

If I invoke pipeline.renderer.getActiveCamera().setClippingRange(10, 1200), the visualization is far more acceptable. The standard resetCamera() works well for 2D views, but not so well with AR. One idea is to get the scene's bounding box, inflate it a bunch, and then pass it into resetCamera(bounds).

floryst commented 2 years ago

FYI @tbirdso to fix the clipping issue, we can add conditionals for the VR version of resetCamera and resetCameraClippingRange, as seen here: https://github.com/Kitware/VTK/blob/master/Rendering/VR/vtkVRRenderer.cxx

tbirdso commented 2 years ago

I experimented a bit with resetting clipping planes for AR last Friday. Increasing the far clip plane helped significantly and seemed to correspond neatly to real-world distances. However, the near clipping plane to anything farther than 0.1 or so seemed to reduce the far clip distance rather than moving the near clip plane outward, which was unexpected. Unclear if this is an issue specific to WebXR, need to experiment further.

Do we have an example for adjusting a camera's clipping planes without XR that I could use as a baseline?

floryst commented 2 years ago

There isn't any example that adjusts the clipping range IIRC. You can take the volume rendering example and adjust the camera clipping range manually via devtools, or add a small slider UI for near/far.

floryst commented 2 years ago

I'm not familiar with any behavior that would force the far clipping range to move closer if you reduce the near clipping plane to below 0.1. I would be interested to know if that occurs with the regular renderer.

tbirdso commented 2 years ago

I was not able to reproduce the clipping issue by playing around with the Cone example, the near and far clip planes were adjustable with setClippingRange as expected. That is a bit of a relief.

I will investigate whether something strange might be happening with our physical-to-view transformation in XR rendering.

EDIT: I also get expected near clipping behavior when experimenting with data in VolumeViewer without XR. I continue to get strange behavior in XR where I cannot adjust the near clipping plane to clip through volume data. Have not been able to pin down any underlying behavior that would lead to this.

tbirdso commented 2 years ago

@floryst I am getting a bit confused on this one. From what I can tell getClippingRange is being called in VolumeMapper using parameters from openGLCamera. Those camera parameters do not seem to reflect the view-to-physical and physical-to-world adjustments made in Core/Camera. As far as I can tell OpenGLCamera and Camera are being treated as completely separate objects.

Could you please comment on how OpenGLCamera is being used in VolumeMapper? Am I missing something obvious as to how OpenGLCamera should be composed with / inherit from Camera?

floryst commented 2 years ago

model.openGLCamera.getRenderable() should return a vtkCamera. The OpenGLCamera represents the opengl scene-graph node for the camera, so getRenderable() returns the vtk.js abstraction for the camera with which we interact.

tbirdso commented 2 years ago

Thanks, I think that makes sense. Maybe the problem does not lie there then. Will keep digging.

tbirdso commented 2 years ago

Collecting thoughts so far:

tbirdso commented 2 years ago

@floryst I am switching gears to focus on #2442. If you have the time I think I need more help to make progress on this issue, my knowledge of VTK's volume clipping procedures is limited and I'm hitting a wall on what I know to investigate. Would appreciate input from someone else who is more familiar with what could be causing the behavior I've described above.

github-actions[bot] commented 2 years ago

:tada: This issue has been resolved in version 24.16.4 :tada:

The release is available on:

Your semantic-release bot :package::rocket: