@kitware/vtk.js 28.10.1 → 28.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/Core/Base64.js +53 -82
- package/Common/Core/CellArray.js +52 -60
- package/Common/Core/ClassHierarchy.js +8 -36
- package/Common/Core/DataArray/Constants.js +6 -6
- package/Common/Core/DataArray.js +185 -270
- package/Common/Core/Endian.js +14 -17
- package/Common/Core/HalfFloat.js +17 -34
- package/Common/Core/ImageHelper.js +17 -25
- package/Common/Core/LookupTable.js +131 -144
- package/Common/Core/Math/Constants.js +8 -8
- package/Common/Core/Math/index.js +778 -903
- package/Common/Core/Math.d.ts +14 -0
- package/Common/Core/Math.js +2 -4
- package/Common/Core/MatrixBuilder.js +99 -151
- package/Common/Core/Points.js +43 -43
- package/Common/Core/PriorityQueue.js +30 -28
- package/Common/Core/ProgressHandler.js +31 -32
- package/Common/Core/ScalarsToColors/Constants.js +4 -4
- package/Common/Core/ScalarsToColors.js +196 -253
- package/Common/Core/StringArray.js +48 -73
- package/Common/Core/URLExtract.js +10 -29
- package/Common/Core/VariantArray.js +48 -73
- package/Common/Core.js +11 -11
- package/Common/DataModel/AbstractPointLocator.js +19 -17
- package/Common/DataModel/BoundingBox.js +322 -490
- package/Common/DataModel/Box.js +46 -63
- package/Common/DataModel/CardinalSpline1D.js +92 -102
- package/Common/DataModel/Cell.js +41 -61
- package/Common/DataModel/CellLinks.js +91 -127
- package/Common/DataModel/CellTypes/Constants.js +7 -6
- package/Common/DataModel/CellTypes.js +55 -74
- package/Common/DataModel/Collection.js +45 -61
- package/Common/DataModel/Cone.js +28 -20
- package/Common/DataModel/Cylinder.js +41 -35
- package/Common/DataModel/DataSet/Constants.js +11 -5
- package/Common/DataModel/DataSet.js +37 -25
- package/Common/DataModel/DataSetAttributes/Constants.js +18 -18
- package/Common/DataModel/DataSetAttributes/FieldData.js +103 -194
- package/Common/DataModel/DataSetAttributes.js +96 -138
- package/Common/DataModel/EdgeLocator.js +45 -70
- package/Common/DataModel/ITKHelper.js +67 -137
- package/Common/DataModel/ImageData.js +115 -172
- package/Common/DataModel/ImplicitBoolean/Constants.js +2 -2
- package/Common/DataModel/ImplicitBoolean.js +66 -96
- package/Common/DataModel/IncrementalOctreeNode.js +201 -231
- package/Common/DataModel/IncrementalOctreePointLocator.js +160 -198
- package/Common/DataModel/KochanekSpline1D.js +78 -81
- package/Common/DataModel/Line/Constants.js +2 -2
- package/Common/DataModel/Line.js +82 -105
- package/Common/DataModel/Locator.js +17 -10
- package/Common/DataModel/Molecule.js +26 -17
- package/Common/DataModel/PiecewiseFunction.js +218 -239
- package/Common/DataModel/Plane.js +90 -113
- package/Common/DataModel/PointSet.js +30 -26
- package/Common/DataModel/PolyData/Constants.js +2 -2
- package/Common/DataModel/PolyData.js +95 -120
- package/Common/DataModel/PolyLine.js +44 -61
- package/Common/DataModel/Polygon/Constants.js +4 -4
- package/Common/DataModel/Polygon.js +128 -169
- package/Common/DataModel/Quad/Constants.js +2 -2
- package/Common/DataModel/Quad.js +61 -100
- package/Common/DataModel/SelectionNode/Constants.js +5 -4
- package/Common/DataModel/SelectionNode.js +25 -21
- package/Common/DataModel/Sphere.js +40 -35
- package/Common/DataModel/Spline1D/Constants.js +3 -2
- package/Common/DataModel/Spline1D.js +34 -18
- package/Common/DataModel/Spline3D/Constants.js +2 -2
- package/Common/DataModel/Spline3D.js +46 -41
- package/Common/DataModel/StructuredData/Constants.js +2 -2
- package/Common/DataModel/StructuredData.js +9 -20
- package/Common/DataModel/Triangle.js +207 -250
- package/Common/DataModel.js +19 -19
- package/Common/System/MobileVR.js +56 -61
- package/Common/System/TimerLog.js +1 -1
- package/Common/System.js +2 -2
- package/Common/Transform/LandmarkTransform/Constants.js +2 -2
- package/Common/Transform/LandmarkTransform.js +133 -117
- package/Common/Transform/Transform.js +42 -57
- package/Common/Transform.js +2 -2
- package/Common/index.js +4 -4
- package/Filters/Core/Cutter.js +134 -146
- package/Filters/Core/PolyDataNormals.js +44 -50
- package/Filters/Core.js +2 -2
- package/Filters/Cornerstone/ImageDataToCornerstoneImage.js +45 -33
- package/Filters/Cornerstone.js +1 -1
- package/Filters/General/AppendPolyData.js +84 -100
- package/Filters/General/Calculator.js +95 -163
- package/Filters/General/ClipClosedSurface/Constants.js +2 -2
- package/Filters/General/ClipClosedSurface.js +341 -416
- package/Filters/General/ClosedPolyLineToSurfaceFilter.js +141 -156
- package/Filters/General/ContourTriangulator/Constants.js +2 -2
- package/Filters/General/ContourTriangulator/helper.js +684 -812
- package/Filters/General/ContourTriangulator.js +92 -89
- package/Filters/General/ImageCropFilter.js +77 -78
- package/Filters/General/ImageDataOutlineFilter.js +42 -36
- package/Filters/General/ImageMarchingCubes/caseTable.js +9 -521
- package/Filters/General/ImageMarchingCubes.js +99 -112
- package/Filters/General/ImageMarchingSquares/caseTable.js +9 -41
- package/Filters/General/ImageMarchingSquares.js +93 -118
- package/Filters/General/ImageOutlineFilter.js +53 -54
- package/Filters/General/ImageSliceFilter.js +39 -30
- package/Filters/General/ImageStreamline.js +107 -124
- package/Filters/General/LineFilter.js +26 -15
- package/Filters/General/MoleculeToRepresentation.js +136 -149
- package/Filters/General/OBBTree/OBBNode.js +36 -34
- package/Filters/General/OBBTree/helper.js +19 -24
- package/Filters/General/OBBTree.js +396 -488
- package/Filters/General/OutlineFilter.js +52 -34
- package/Filters/General/PaintFilter/PaintFilter.worker.js +93 -130
- package/Filters/General/PaintFilter.js +150 -162
- package/Filters/General/ScalarToRGBA.js +38 -33
- package/Filters/General/TriangleFilter.js +65 -62
- package/Filters/General/TubeFilter/Constants.js +4 -4
- package/Filters/General/TubeFilter.js +376 -496
- package/Filters/General/WarpScalar.js +58 -60
- package/Filters/General/WindowedSincPolyDataFilter.js +258 -330
- package/Filters/General.js +21 -21
- package/Filters/Sources/Arrow2DSource/Constants.js +2 -2
- package/Filters/Sources/Arrow2DSource.js +56 -56
- package/Filters/Sources/ArrowSource.js +39 -29
- package/Filters/Sources/CircleSource.js +43 -43
- package/Filters/Sources/ConcentricCylinderSource.js +151 -174
- package/Filters/Sources/ConeSource.js +51 -42
- package/Filters/Sources/CubeSource.js +75 -96
- package/Filters/Sources/Cursor3D.js +94 -109
- package/Filters/Sources/CylinderSource.js +90 -90
- package/Filters/Sources/ImageGridSource.js +43 -43
- package/Filters/Sources/LineSource.js +49 -39
- package/Filters/Sources/PlaneSource.js +97 -104
- package/Filters/Sources/PointSource.js +46 -37
- package/Filters/Sources/RTAnalyticSource.js +50 -48
- package/Filters/Sources/SLICSource.js +63 -73
- package/Filters/Sources/SphereSource.js +88 -78
- package/Filters/Sources/ViewFinderSource.js +26 -23
- package/Filters/Sources.js +14 -14
- package/Filters/Texture/TextureMapToPlane.js +95 -97
- package/Filters/Texture/TextureMapToSphere.js +46 -54
- package/Filters/Texture.js +2 -2
- package/Filters/index.js +5 -5
- package/IO/Core/BinaryHelper.js +12 -18
- package/IO/Core/DataAccessHelper/HtmlDataAccessHelper.js +43 -59
- package/IO/Core/DataAccessHelper/HttpDataAccessHelper.js +76 -113
- package/IO/Core/DataAccessHelper/JSZipDataAccessHelper.js +62 -112
- package/IO/Core/DataAccessHelper/LiteHttpDataAccessHelper.js +76 -113
- package/IO/Core/DataAccessHelper.js +6 -6
- package/IO/Core/HttpDataSetReader.js +136 -139
- package/IO/Core/HttpDataSetSeriesReader.js +64 -75
- package/IO/Core/HttpSceneLoader.js +130 -179
- package/IO/Core/ImageStream/DefaultProtocol.js +29 -43
- package/IO/Core/ImageStream/ViewStream.js +100 -103
- package/IO/Core/ImageStream.js +62 -54
- package/IO/Core/ResourceLoader.js +10 -9
- package/IO/Core/Serializer/ArraySerializer.js +40 -40
- package/IO/Core/Serializer/FieldDataSerializer.js +18 -28
- package/IO/Core/Serializer/ImageDataSerializer.js +22 -23
- package/IO/Core/Serializer/PolyDataSerializer.js +17 -21
- package/IO/Core/Serializer.js +6 -13
- package/IO/Core/WSLinkClient.js +90 -76
- package/IO/Core/ZipMultiDataSetReader.js +46 -44
- package/IO/Core/ZipMultiDataSetWriter.js +43 -34
- package/IO/Core.js +7 -7
- package/IO/Geometry/DracoReader.js +118 -121
- package/IO/Geometry/PLYReader.js +163 -223
- package/IO/Geometry/PLYWriter/Constants.js +5 -5
- package/IO/Geometry/PLYWriter.js +139 -154
- package/IO/Geometry/STLReader.js +123 -146
- package/IO/Geometry/STLWriter/Constants.js +2 -2
- package/IO/Geometry/STLWriter.js +83 -82
- package/IO/Geometry.js +5 -5
- package/IO/Legacy/LegacyAsciiParser.js +78 -139
- package/IO/Legacy/PolyDataReader.js +48 -36
- package/IO/Legacy.js +2 -2
- package/IO/Misc/ElevationReader.js +67 -60
- package/IO/Misc/HttpDataSetLODsLoader.js +41 -38
- package/IO/Misc/ITKImageReader.js +58 -45
- package/IO/Misc/ITKPolyDataReader.js +50 -38
- package/IO/Misc/JSONNucleoReader.js +49 -42
- package/IO/Misc/JSONReader.js +38 -33
- package/IO/Misc/MTLReader.js +74 -119
- package/IO/Misc/OBJReader.js +153 -206
- package/IO/Misc/PDBReader.js +70 -68
- package/IO/Misc/SkyboxReader.js +77 -82
- package/IO/Misc.js +9 -9
- package/IO/XML/XMLImageDataReader.js +36 -38
- package/IO/XML/XMLImageDataWriter.js +28 -21
- package/IO/XML/XMLPolyDataReader.js +49 -46
- package/IO/XML/XMLPolyDataWriter.js +43 -42
- package/IO/XML/XMLReader.js +262 -304
- package/IO/XML/XMLWriter/Constants.js +3 -3
- package/IO/XML/XMLWriter.js +70 -84
- package/IO/XML.js +6 -6
- package/IO/index.js +5 -5
- package/Imaging/Core/AbstractImageInterpolator/Constants.js +4 -4
- package/Imaging/Core/AbstractImageInterpolator/InterpolationInfo.js +30 -27
- package/Imaging/Core/AbstractImageInterpolator.js +74 -87
- package/Imaging/Core/ImageInterpolator.js +201 -252
- package/Imaging/Core/ImagePointDataIterator.js +96 -122
- package/Imaging/Core/ImageReslice/Constants.js +2 -2
- package/Imaging/Core/ImageReslice.js +327 -464
- package/Imaging/Core.js +4 -4
- package/Imaging/Hybrid/SampleFunction.js +58 -51
- package/Imaging/Hybrid.js +1 -1
- package/Imaging/index.js +2 -2
- package/Interaction/Animations/TimeStepBasedAnimationHandler.js +39 -54
- package/Interaction/Manipulators/CompositeCameraManipulator.js +22 -13
- package/Interaction/Manipulators/CompositeGestureManipulator.js +31 -43
- package/Interaction/Manipulators/CompositeKeyboardManipulator.js +15 -11
- package/Interaction/Manipulators/CompositeMouseManipulator.js +27 -33
- package/Interaction/Manipulators/CompositeVRManipulator.js +22 -15
- package/Interaction/Manipulators/GestureCameraManipulator.js +54 -36
- package/Interaction/Manipulators/KeyboardCameraManipulator.js +95 -97
- package/Interaction/Manipulators/MouseBoxSelectorManipulator.js +70 -89
- package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +67 -54
- package/Interaction/Manipulators/MouseCameraSliceManipulator.js +40 -38
- package/Interaction/Manipulators/MouseCameraTrackballFirstPersonManipulator.js +83 -68
- package/Interaction/Manipulators/MouseCameraTrackballMultiRotateManipulator.js +32 -28
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +47 -40
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +55 -43
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +56 -46
- package/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.js +41 -46
- package/Interaction/Manipulators/MouseCameraTrackballZoomToMouseManipulator.js +29 -27
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +123 -146
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +144 -166
- package/Interaction/Manipulators/MouseRangeManipulator.js +127 -132
- package/Interaction/Manipulators/VRButtonPanManipulator.js +33 -23
- package/Interaction/Manipulators.js +21 -21
- package/Interaction/Misc/DeviceOrientationToCamera.js +25 -47
- package/Interaction/Misc.js +1 -1
- package/Interaction/Style/InteractorStyleImage.js +101 -121
- package/Interaction/Style/InteractorStyleMPRSlice.js +111 -128
- package/Interaction/Style/InteractorStyleManipulator/Presets.js +9 -17
- package/Interaction/Style/InteractorStyleManipulator.js +254 -329
- package/Interaction/Style/InteractorStyleRemoteMouse.js +195 -180
- package/Interaction/Style/InteractorStyleTrackballCamera.js +154 -157
- package/Interaction/Style/InteractorStyleUnicam.js +30 -38
- package/Interaction/Style.js +5 -5
- package/Interaction/UI/CornerAnnotation/CornerAnnotation.module.css.js +1 -1
- package/Interaction/UI/CornerAnnotation.js +65 -48
- package/Interaction/UI/FPSMonitor.js +104 -105
- package/Interaction/UI/Icons.js +1 -1
- package/Interaction/UI/Slider/Constants.js +2 -2
- package/Interaction/UI/Slider.js +78 -95
- package/Interaction/UI/VolumeController.js +104 -97
- package/Interaction/UI.js +5 -5
- package/Interaction/Widgets/OrientationMarkerWidget/Constants.js +2 -2
- package/Interaction/Widgets/OrientationMarkerWidget.js +90 -135
- package/Interaction/Widgets/PiecewiseGaussianWidget/ComputeHistogram.worker.js +0 -3
- package/Interaction/Widgets/PiecewiseGaussianWidget.js +381 -498
- package/Interaction/Widgets.js +2 -2
- package/Interaction/index.js +5 -5
- package/Proxy/Animation/AbstractAnimationProxy.js +22 -15
- package/Proxy/Animation/AnimationProxyManager.js +43 -51
- package/Proxy/Animation/TimeStepBasedAnimationHandlerProxy.js +26 -19
- package/Proxy/Core/AbstractRepresentationProxy.js +97 -151
- package/Proxy/Core/LookupTableProxy/Constants.js +4 -4
- package/Proxy/Core/LookupTableProxy.js +49 -52
- package/Proxy/Core/PiecewiseFunctionProxy/Constants.js +4 -4
- package/Proxy/Core/PiecewiseFunctionProxy.js +63 -72
- package/Proxy/Core/ProxyManager/core.js +83 -106
- package/Proxy/Core/ProxyManager/properties.js +53 -76
- package/Proxy/Core/ProxyManager/state.js +100 -110
- package/Proxy/Core/ProxyManager/view.js +45 -55
- package/Proxy/Core/ProxyManager.js +16 -8
- package/Proxy/Core/SourceProxy.js +41 -38
- package/Proxy/Core/View2DProxy.js +143 -199
- package/Proxy/Core/ViewProxy.js +223 -269
- package/Proxy/Core.js +7 -7
- package/Proxy/Representations/GeometryRepresentationProxy.js +34 -20
- package/Proxy/Representations/GlyphRepresentationProxy.js +42 -41
- package/Proxy/Representations/MoleculeRepresentationProxy.js +32 -22
- package/Proxy/Representations/ResliceRepresentationProxy.js +48 -32
- package/Proxy/Representations/SkyboxRepresentationProxy.js +30 -29
- package/Proxy/Representations/SliceRepresentationProxy.js +93 -112
- package/Proxy/Representations/SlicedGeometryRepresentationProxy.js +46 -42
- package/Proxy/Representations/VolumeRepresentationProxy.js +108 -133
- package/Proxy/Representations.js +7 -7
- package/Proxy/index.js +2 -2
- package/Rendering/Core/AbstractImageMapper/helper.js +44 -49
- package/Rendering/Core/AbstractImageMapper.js +18 -19
- package/Rendering/Core/AbstractMapper.js +39 -55
- package/Rendering/Core/AbstractMapper3D.js +26 -31
- package/Rendering/Core/AbstractPicker.js +25 -21
- package/Rendering/Core/Actor.js +71 -93
- package/Rendering/Core/Actor2D.js +64 -78
- package/Rendering/Core/AnnotatedCubeActor/Presets.js +5 -11
- package/Rendering/Core/AnnotatedCubeActor.js +94 -79
- package/Rendering/Core/AxesActor.js +65 -87
- package/Rendering/Core/Camera.js +246 -271
- package/Rendering/Core/CellPicker.js +125 -148
- package/Rendering/Core/ColorTransferFunction/ColorMaps.js +20 -21
- package/Rendering/Core/ColorTransferFunction/ColorMapsLite.js +20 -21
- package/Rendering/Core/ColorTransferFunction/Constants.js +4 -4
- package/Rendering/Core/ColorTransferFunction.js +460 -546
- package/Rendering/Core/Coordinate/Constants.js +2 -2
- package/Rendering/Core/Coordinate.js +119 -198
- package/Rendering/Core/CubeAxesActor.js +294 -320
- package/Rendering/Core/Follower.js +46 -45
- package/Rendering/Core/Glyph3DMapper/Constants.js +4 -4
- package/Rendering/Core/Glyph3DMapper.js +96 -148
- package/Rendering/Core/HardwareSelector.js +36 -69
- package/Rendering/Core/ImageArrayMapper.js +87 -126
- package/Rendering/Core/ImageCPRMapper.js +134 -209
- package/Rendering/Core/ImageMapper/Constants.js +2 -2
- package/Rendering/Core/ImageMapper.js +92 -170
- package/Rendering/Core/ImageProperty/Constants.js +2 -2
- package/Rendering/Core/ImageProperty.js +66 -81
- package/Rendering/Core/ImageResliceMapper/Constants.js +2 -2
- package/Rendering/Core/ImageResliceMapper.js +36 -29
- package/Rendering/Core/ImageSlice.js +85 -127
- package/Rendering/Core/InteractorObserver.js +82 -73
- package/Rendering/Core/InteractorStyle/Constants.js +2 -2
- package/Rendering/Core/InteractorStyle.js +56 -58
- package/Rendering/Core/Light.js +43 -49
- package/Rendering/Core/Mapper/CoincidentTopologyHelper.js +37 -48
- package/Rendering/Core/Mapper/Constants.js +6 -6
- package/Rendering/Core/Mapper/Static.js +15 -12
- package/Rendering/Core/Mapper.js +194 -259
- package/Rendering/Core/Mapper2D.js +61 -100
- package/Rendering/Core/Picker.js +124 -143
- package/Rendering/Core/PixelSpaceCallbackMapper.js +40 -37
- package/Rendering/Core/PointPicker.js +68 -79
- package/Rendering/Core/Prop/Constants.js +2 -2
- package/Rendering/Core/Prop.js +58 -106
- package/Rendering/Core/Prop3D.js +54 -83
- package/Rendering/Core/Property/Constants.js +6 -6
- package/Rendering/Core/Property.js +45 -74
- package/Rendering/Core/Property2D/Constants.js +2 -2
- package/Rendering/Core/Property2D.js +33 -42
- package/Rendering/Core/RenderWindow.js +70 -82
- package/Rendering/Core/RenderWindowInteractor/Constants.js +7 -7
- package/Rendering/Core/RenderWindowInteractor.js +324 -439
- package/Rendering/Core/Renderer.js +193 -257
- package/Rendering/Core/ScalarBarActor.js +267 -272
- package/Rendering/Core/Skybox.js +26 -24
- package/Rendering/Core/SphereMapper.js +22 -12
- package/Rendering/Core/StickMapper.js +22 -12
- package/Rendering/Core/SurfaceLICInterface/Constants.js +6 -6
- package/Rendering/Core/SurfaceLICInterface.js +13 -9
- package/Rendering/Core/SurfaceLICMapper.js +23 -15
- package/Rendering/Core/Texture.js +99 -141
- package/Rendering/Core/Viewport.js +60 -88
- package/Rendering/Core/Volume.js +55 -77
- package/Rendering/Core/VolumeMapper/Constants.js +4 -4
- package/Rendering/Core/VolumeMapper.js +59 -91
- package/Rendering/Core/VolumeProperty/Constants.js +4 -4
- package/Rendering/Core/VolumeProperty.js +78 -115
- package/Rendering/Core.js +47 -49
- package/Rendering/Misc/CanvasView.js +62 -61
- package/Rendering/Misc/FullScreenRenderWindow.js +60 -62
- package/Rendering/Misc/GenericRenderWindow.js +48 -37
- package/Rendering/Misc/RemoteView.js +86 -80
- package/Rendering/Misc/RenderWindowWithControlBar.js +54 -48
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +43 -51
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager.js +52 -82
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.js +258 -308
- package/Rendering/Misc/SynchronizableRenderWindow.js +133 -163
- package/Rendering/Misc/TextureLODsDownloader.js +72 -74
- package/Rendering/Misc.js +7 -7
- package/Rendering/OpenGL/Actor.js +57 -68
- package/Rendering/OpenGL/Actor2D.js +56 -56
- package/Rendering/OpenGL/BufferObject/Constants.js +2 -2
- package/Rendering/OpenGL/BufferObject.js +50 -65
- package/Rendering/OpenGL/Camera.js +35 -29
- package/Rendering/OpenGL/CellArrayBufferObject.js +119 -149
- package/Rendering/OpenGL/Convolution2DPass.js +87 -81
- package/Rendering/OpenGL/CubeAxesActor.js +28 -21
- package/Rendering/OpenGL/ForwardPass.js +53 -64
- package/Rendering/OpenGL/Framebuffer.js +61 -101
- package/Rendering/OpenGL/Glyph3DMapper.js +165 -196
- package/Rendering/OpenGL/HardwareSelector/Constants.js +2 -2
- package/Rendering/OpenGL/HardwareSelector.js +272 -397
- package/Rendering/OpenGL/Helper.js +58 -73
- package/Rendering/OpenGL/ImageCPRMapper.js +339 -421
- package/Rendering/OpenGL/ImageMapper.js +268 -361
- package/Rendering/OpenGL/ImageResliceMapper.js +306 -438
- package/Rendering/OpenGL/ImageSlice.js +48 -54
- package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +102 -84
- package/Rendering/OpenGL/PixelSpaceCallbackMapper.js +43 -42
- package/Rendering/OpenGL/PolyDataMapper.js +358 -492
- package/Rendering/OpenGL/PolyDataMapper2D.js +153 -205
- package/Rendering/OpenGL/RadialDistortionPass.js +86 -89
- package/Rendering/OpenGL/RenderWindow/Constants.js +2 -2
- package/Rendering/OpenGL/RenderWindow/ContextProxy.js +20 -29
- package/Rendering/OpenGL/RenderWindow.js +356 -510
- package/Rendering/OpenGL/Renderer.js +77 -89
- package/Rendering/OpenGL/ReplacementShaderMapper.js +28 -46
- package/Rendering/OpenGL/ScalarBarActor.js +28 -21
- package/Rendering/OpenGL/Shader.js +37 -31
- package/Rendering/OpenGL/ShaderCache.js +67 -74
- package/Rendering/OpenGL/ShaderProgram.js +136 -248
- package/Rendering/OpenGL/Skybox.js +99 -60
- package/Rendering/OpenGL/SphereMapper.js +94 -108
- package/Rendering/OpenGL/StickMapper.js +110 -114
- package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D/pingpong.js +91 -157
- package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D.js +142 -151
- package/Rendering/OpenGL/SurfaceLIC/SurfaceLICInterface.js +142 -216
- package/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper.js +79 -100
- package/Rendering/OpenGL/SurfaceLIC.js +2 -2
- package/Rendering/OpenGL/Texture/Constants.js +4 -4
- package/Rendering/OpenGL/Texture.js +444 -609
- package/Rendering/OpenGL/TextureUnitManager.js +47 -43
- package/Rendering/OpenGL/VertexArrayObject.js +92 -131
- package/Rendering/OpenGL/ViewNodeFactory.js +25 -13
- package/Rendering/OpenGL/Volume.js +38 -34
- package/Rendering/OpenGL/VolumeMapper.js +437 -547
- package/Rendering/OpenGL.js +28 -28
- package/Rendering/SceneGraph/RenderPass.js +34 -31
- package/Rendering/SceneGraph/RenderWindowViewNode.js +68 -94
- package/Rendering/SceneGraph/ViewNode.js +82 -111
- package/Rendering/SceneGraph/ViewNodeFactory.js +31 -26
- package/Rendering/SceneGraph.js +4 -4
- package/Rendering/WebGPU/Actor.js +49 -49
- package/Rendering/WebGPU/Actor2D.js +45 -44
- package/Rendering/WebGPU/BindGroup.js +43 -50
- package/Rendering/WebGPU/Buffer.js +41 -50
- package/Rendering/WebGPU/BufferManager/Constants.js +4 -4
- package/Rendering/WebGPU/BufferManager.js +111 -141
- package/Rendering/WebGPU/Camera.js +65 -67
- package/Rendering/WebGPU/CellArrayMapper.js +621 -388
- package/Rendering/WebGPU/CubeAxesActor.js +28 -19
- package/Rendering/WebGPU/Device.js +78 -133
- package/Rendering/WebGPU/ForwardPass.js +75 -72
- package/Rendering/WebGPU/FullScreenQuad.js +25 -18
- package/Rendering/WebGPU/Glyph3DMapper.js +62 -74
- package/Rendering/WebGPU/HardwareSelectionPass.js +45 -38
- package/Rendering/WebGPU/HardwareSelector.js +200 -276
- package/Rendering/WebGPU/ImageMapper.js +180 -171
- package/Rendering/WebGPU/ImageSlice.js +45 -44
- package/Rendering/WebGPU/IndexBuffer.js +166 -200
- package/Rendering/WebGPU/OpaquePass.js +37 -36
- package/Rendering/WebGPU/OrderIndependentTranslucentPass.js +72 -45
- package/Rendering/WebGPU/Pipeline.js +37 -51
- package/Rendering/WebGPU/PixelSpaceCallbackMapper.js +27 -19
- package/Rendering/WebGPU/PolyDataMapper.js +50 -53
- package/Rendering/WebGPU/PolyDataMapper2D.js +39 -39
- package/Rendering/WebGPU/RenderEncoder.js +68 -88
- package/Rendering/WebGPU/RenderWindow.js +262 -376
- package/Rendering/WebGPU/Renderer.js +224 -208
- package/Rendering/WebGPU/Sampler.js +27 -21
- package/Rendering/WebGPU/ScalarBarActor.js +28 -19
- package/Rendering/WebGPU/ShaderCache.js +43 -41
- package/Rendering/WebGPU/ShaderDescription.js +52 -59
- package/Rendering/WebGPU/ShaderModule.js +26 -17
- package/Rendering/WebGPU/SimpleMapper.js +185 -121
- package/Rendering/WebGPU/SphereMapper.js +200 -130
- package/Rendering/WebGPU/StickMapper.js +289 -152
- package/Rendering/WebGPU/StorageBuffer.js +100 -115
- package/Rendering/WebGPU/Texture.js +79 -99
- package/Rendering/WebGPU/TextureManager.js +52 -54
- package/Rendering/WebGPU/TextureView.js +40 -43
- package/Rendering/WebGPU/Types.js +53 -70
- package/Rendering/WebGPU/UniformBuffer.js +158 -184
- package/Rendering/WebGPU/VertexInput.js +64 -90
- package/Rendering/WebGPU/ViewNodeFactory.js +25 -13
- package/Rendering/WebGPU/Volume.js +52 -51
- package/Rendering/WebGPU/VolumePass.js +218 -239
- package/Rendering/WebGPU/VolumePassFSQ.js +625 -306
- package/Rendering/WebGPU.js +1 -1
- package/Rendering/index.js +5 -5
- package/Widgets/Core/AbstractWidget/Constants.js +2 -2
- package/Widgets/Core/AbstractWidget.js +49 -58
- package/Widgets/Core/AbstractWidgetFactory.js +101 -122
- package/Widgets/Core/StateBuilder/boundsMixin.js +23 -28
- package/Widgets/Core/StateBuilder/color3Mixin.js +10 -7
- package/Widgets/Core/StateBuilder/colorMixin.js +10 -6
- package/Widgets/Core/StateBuilder/cornerMixin.js +16 -15
- package/Widgets/Core/StateBuilder/directionMixin.js +20 -18
- package/Widgets/Core/StateBuilder/manipulatorMixin.js +26 -18
- package/Widgets/Core/StateBuilder/nameMixin.js +10 -6
- package/Widgets/Core/StateBuilder/orientationMixin.js +19 -16
- package/Widgets/Core/StateBuilder/originMixin.js +25 -32
- package/Widgets/Core/StateBuilder/scale1Mixin.js +10 -6
- package/Widgets/Core/StateBuilder/scale3Mixin.js +10 -6
- package/Widgets/Core/StateBuilder/shapeMixin.js +12 -6
- package/Widgets/Core/StateBuilder/textMixin.js +10 -6
- package/Widgets/Core/StateBuilder/visibleMixin.js +10 -6
- package/Widgets/Core/StateBuilder.js +120 -149
- package/Widgets/Core/WidgetManager/Constants.js +7 -7
- package/Widgets/Core/WidgetManager.js +249 -421
- package/Widgets/Core/WidgetState.js +48 -57
- package/Widgets/Core.js +5 -5
- package/Widgets/Manipulators/AbstractManipulator.js +20 -14
- package/Widgets/Manipulators/CPRManipulator.js +55 -71
- package/Widgets/Manipulators/LineManipulator.js +31 -28
- package/Widgets/Manipulators/PickerManipulator.d.ts +48 -0
- package/Widgets/Manipulators/PickerManipulator.js +65 -0
- package/Widgets/Manipulators/PlaneManipulator.js +26 -23
- package/Widgets/Manipulators/TrackballManipulator.js +39 -35
- package/Widgets/Manipulators.js +4 -2
- package/Widgets/Representations/ArrowHandleRepresentation.js +148 -162
- package/Widgets/Representations/CircleContextRepresentation.js +44 -38
- package/Widgets/Representations/ContextRepresentation.js +17 -14
- package/Widgets/Representations/ConvexFaceContextRepresentation.js +50 -47
- package/Widgets/Representations/CroppingOutlineRepresentation.js +38 -27
- package/Widgets/Representations/CubeHandleRepresentation.js +21 -18
- package/Widgets/Representations/GlyphRepresentation.js +107 -152
- package/Widgets/Representations/HandleRepresentation.js +17 -14
- package/Widgets/Representations/ImplicitPlaneRepresentation.js +97 -91
- package/Widgets/Representations/LineHandleRepresentation.js +44 -41
- package/Widgets/Representations/OutlineContextRepresentation.js +42 -36
- package/Widgets/Representations/PolyLineRepresentation.js +60 -75
- package/Widgets/Representations/RectangleContextRepresentation.js +42 -37
- package/Widgets/Representations/SphereContextRepresentation.js +19 -27
- package/Widgets/Representations/SphereHandleRepresentation.js +31 -27
- package/Widgets/Representations/SplineContextRepresentation.js +46 -70
- package/Widgets/Representations/WidgetRepresentation/Constants.js +2 -2
- package/Widgets/Representations/WidgetRepresentation.js +99 -134
- package/Widgets/Representations.js +13 -13
- package/Widgets/Widgets3D/AngleWidget/behavior.js +41 -63
- package/Widgets/Widgets3D/AngleWidget.js +41 -39
- package/Widgets/Widgets3D/DistanceWidget/behavior.js +40 -61
- package/Widgets/Widgets3D/DistanceWidget.js +38 -36
- package/Widgets/Widgets3D/EllipseWidget/behavior.js +14 -19
- package/Widgets/Widgets3D/EllipseWidget/state.js +4 -2
- package/Widgets/Widgets3D/EllipseWidget.js +37 -26
- package/Widgets/Widgets3D/ImageCroppingWidget/behavior.js +26 -56
- package/Widgets/Widgets3D/ImageCroppingWidget/helpers.js +14 -17
- package/Widgets/Widgets3D/ImageCroppingWidget/state.js +20 -16
- package/Widgets/Widgets3D/ImageCroppingWidget.js +80 -98
- package/Widgets/Widgets3D/ImplicitPlaneWidget.js +55 -77
- package/Widgets/Widgets3D/InteractiveOrientationWidget/behavior.js +17 -18
- package/Widgets/Widgets3D/InteractiveOrientationWidget/state.js +15 -7
- package/Widgets/Widgets3D/InteractiveOrientationWidget.js +30 -29
- package/Widgets/Widgets3D/LabelWidget/behavior.js +37 -62
- package/Widgets/Widgets3D/LabelWidget.js +31 -25
- package/Widgets/Widgets3D/LineWidget/Constants.js +8 -8
- package/Widgets/Widgets3D/LineWidget/behavior.js +77 -114
- package/Widgets/Widgets3D/LineWidget/helpers.js +13 -20
- package/Widgets/Widgets3D/LineWidget/state.js +2 -1
- package/Widgets/Widgets3D/LineWidget.js +39 -35
- package/Widgets/Widgets3D/PaintWidget/behavior.js +24 -59
- package/Widgets/Widgets3D/PaintWidget.js +39 -37
- package/Widgets/Widgets3D/PolyLineWidget/behavior.js +44 -68
- package/Widgets/Widgets3D/PolyLineWidget.js +36 -31
- package/Widgets/Widgets3D/RectangleWidget/behavior.js +6 -11
- package/Widgets/Widgets3D/RectangleWidget/state.js +4 -2
- package/Widgets/Widgets3D/RectangleWidget.js +37 -25
- package/Widgets/Widgets3D/ResliceCursorWidget/Constants.js +35 -21
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +134 -210
- package/Widgets/Widgets3D/ResliceCursorWidget/cprBehavior.js +26 -41
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +90 -117
- package/Widgets/Widgets3D/ResliceCursorWidget/state.js +33 -40
- package/Widgets/Widgets3D/ResliceCursorWidget.js +186 -227
- package/Widgets/Widgets3D/SeedWidget/behavior.js +82 -0
- package/Widgets/Widgets3D/SeedWidget/state.js +18 -0
- package/Widgets/Widgets3D/SeedWidget.d.ts +44 -0
- package/Widgets/Widgets3D/SeedWidget.js +43 -0
- package/Widgets/Widgets3D/ShapeWidget/Constants.js +19 -19
- package/Widgets/Widgets3D/ShapeWidget/behavior.js +150 -252
- package/Widgets/Widgets3D/ShapeWidget.js +24 -27
- package/Widgets/Widgets3D/SphereWidget/behavior.js +35 -69
- package/Widgets/Widgets3D/SphereWidget/state.js +9 -5
- package/Widgets/Widgets3D/SphereWidget.js +34 -44
- package/Widgets/Widgets3D/SplineWidget/behavior.js +85 -120
- package/Widgets/Widgets3D/SplineWidget.js +43 -39
- package/Widgets/Widgets3D.js +15 -15
- package/Widgets/index.js +4 -4
- package/_virtual/rollup-plugin-worker-loader__module_Sources/Filters/General/PaintFilter/PaintFilter.worker.js +95 -207
- package/_virtual/rollup-plugin-worker-loader__module_Sources/Interaction/Widgets/PiecewiseGaussianWidget/ComputeHistogram.worker.js +0 -3
- package/favicon.js +5 -6
- package/index.d.ts +4 -2
- package/index.js +4 -3
- package/macros.js +4 -1931
- package/macros2.js +1684 -0
- package/package.json +6 -6
- package/vtk.js +18 -31
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import macro from '../../macros.js';
|
|
1
|
+
import { m as macro } from '../../macros2.js';
|
|
3
2
|
import { mat4 } from 'gl-matrix';
|
|
4
3
|
import vtkWebGPUFullScreenQuad from './FullScreenQuad.js';
|
|
5
4
|
import vtkWebGPUUniformBuffer from './UniformBuffer.js';
|
|
@@ -9,307 +8,643 @@ import vtkWebGPUSampler from './Sampler.js';
|
|
|
9
8
|
import vtkWebGPUTypes from './Types.js';
|
|
10
9
|
import { BlendMode } from '../Core/VolumeMapper/Constants.js';
|
|
11
10
|
|
|
12
|
-
var volFragTemplate = "\n//VTK::Renderer::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::Volume::TraverseDec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::IOStructs::Dec\n\nfn getTextureValue(vTex: texture_3d<f32>, tpos: vec4<f32>) -> f32\n{\n // todo multicomponent support\n return textureSampleLevel(vTex, clampSampler, tpos.xyz, 0.0).r;\n}\n\nfn getGradient(vTex: texture_3d<f32>, tpos: vec4<f32>, vNum: i32, scalar: f32) -> vec4<f32>\n{\n var result: vec4<f32>;\n\n var tstep: vec4<f32> = volumeSSBO.values[vNum].tstep;\n result.x = getTextureValue(vTex, tpos + vec4<f32>(tstep.x, 0.0, 0.0, 1.0)) - scalar;\n result.y = getTextureValue(vTex, tpos + vec4<f32>(0.0, tstep.y, 0.0, 1.0)) - scalar;\n result.z = getTextureValue(vTex, tpos + vec4<f32>(0.0, 0.0, tstep.z, 1.0)) - scalar;\n result.w = 0.0;\n\n // divide by spacing as that is our delta\n result = result / volumeSSBO.values[vNum].spacing;\n // now we have a gradient in unit tcoords\n\n var grad: f32 = length(result.xyz);\n if (grad > 0.0)\n {\n // rotate to View Coords, needed for lighting and shading\n var nMat: mat4x4<f32> = rendererUBO.SCVCMatrix * volumeSSBO.values[vNum].planeNormals;\n result = nMat * result;\n result = result / length(result);\n }\n\n // store gradient magnitude in .w\n result.w = grad;\n\n return result;\n}\n\nfn processVolume(vTex: texture_3d<f32>, vNum: i32, cNum: i32, posSC: vec4<f32>, tfunRows: f32) -> vec4<f32>\n{\n var outColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n\n // convert to tcoords and reject if outside the volume\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*posSC;\n if (tpos.x < 0.0 || tpos.y < 0.0 || tpos.z < 0.0 ||\n tpos.x > 1.0 || tpos.y > 1.0 || tpos.z > 1.0) { return outColor; }\n\n var scalar: f32 = getTextureValue(vTex, tpos);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n\n var gofactor: f32 = 1.0;\n var normal: vec4<f32> = vec4<f32>(0.0,0.0,0.0,0.0);\n if (componentSSBO.values[cNum].gomin < 1.0 || volumeSSBO.values[vNum].shade[0] > 0.0)\n {\n normal = getGradient(vTex, tpos, vNum, scalar);\n if (componentSSBO.values[cNum].gomin < 1.0)\n {\n gofactor = clamp(normal.a*componentSSBO.values[cNum].goScale + componentSSBO.values[cNum].goShift,\n componentSSBO.values[cNum].gomin, componentSSBO.values[cNum].gomax);\n }\n }\n\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n\n if (volumeSSBO.values[vNum].shade[0] > 0.0)\n {\n color = color*abs(normal.z);\n }\n\n outColor = vec4<f32>(color.rgb, gofactor * opacity);\n\n return outColor;\n}\n\n// adjust the start and end point of a raycast such that it intersects the unit cube.\n// This function is used to take a raycast starting point and step vector\n// and numSteps and return the startijng and ending steps for intersecting the\n// unit cube. Recall for a 3D texture, the unit cube is the range of texture coordsinates\n// that have valid values. So this funtion can be used to take a ray in texture coordinates\n// and bound it to intersecting the texture.\n//\nfn adjustBounds(tpos: vec4<f32>, tstep: vec4<f32>, numSteps: f32) -> vec2<f32>\n{\n var result: vec2<f32> = vec2<f32>(0.0, numSteps);\n var tpos2: vec4<f32> = tpos + tstep*numSteps;\n\n // move tpos to the start of the volume\n var adjust: f32 =\n min(\n max(tpos.x/tstep.x, (tpos.x - 1.0)/tstep.x),\n min(\n max((tpos.y - 1.0)/tstep.y, tpos.y/tstep.y),\n max((tpos.z - 1.0)/tstep.z, tpos.z/tstep.z)));\n if (adjust < 0.0)\n {\n result.x = result.x - adjust;\n }\n\n // adjust length to the end\n adjust =\n max(\n min(tpos2.x/tstep.x, (tpos2.x - 1.0)/tstep.x),\n max(\n min((tpos2.y - 1.0)/tstep.y, tpos2.y/tstep.y),\n min((tpos2.z - 1.0)/tstep.z, tpos2.z/tstep.z)));\n if (adjust > 0.0)\n {\n result.y = result.y - adjust;\n }\n\n return result;\n}\n\nfn getSimpleColor(scalar: f32, vNum: i32, cNum: i32) -> vec4<f32>\n{\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n return vec4<f32>(color.rgb, opacity);\n}\n\nfn traverseMax(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var maxVal: f32 = -1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar > maxVal)\n {\n maxVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(maxVal, vNum, cNum);\n}\n\nfn traverseMin(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var minVal: f32 = 1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar < minVal)\n {\n minVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(minVal, vNum, cNum);\n}\n\nfn traverseAverage(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var avgVal: f32 = 0.0;\n var sampleCount: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n avgVal = avgVal + sample;\n sampleCount = sampleCount + 1.0;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n if (sampleCount <= 0.0)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(avgVal/sampleCount, vNum, cNum);\n}\n\nfn traverseAdditive(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var sumVal: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n sumVal = sumVal + sample;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(sumVal, vNum, cNum);\n}\n\nfn composite(rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>) -> vec4<f32>\n{\n // initial ray position is at the beginning\n var rayPosSC: vec4<f32> = minPosSC;\n\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var curDist: f32 = 0.0;\n var computedColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n var sampleColor: vec4<f32>;\n//VTK::Volume::TraverseCalls\n\n loop\n {\n // for each volume, sample and accumulate color\n//VTK::Volume::CompositeCalls\n\n // increment position\n curDist = curDist + mapperUBO.SampleDistance;\n rayPosSC = rayPosSC + rayStepSC;\n\n // check if we have reached a terminating condition\n if (curDist > rayLengthSC) { break; }\n if (computedColor.a > 0.98) { break; }\n }\n return computedColor;\n}\n\n@fragment\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output: fragmentOutput;\n\n var rayMax: f32 = textureSampleLevel(maxTexture, clampSampler, input.tcoordVS, 0.0).r;\n var rayMin: f32 = textureSampleLevel(minTexture, clampSampler, input.tcoordVS, 0.0).r;\n\n // discard empty rays\n if (rayMax <= rayMin) { discard; }\n else\n {\n // compute start and end ray positions in view coordinates\n var minPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMax, 1.0);\n minPosSC = minPosSC * (1.0 / minPosSC.w);\n var maxPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMin, 1.0);\n maxPosSC = maxPosSC * (1.0 / maxPosSC.w);\n\n var rayLengthSC: f32 = distance(minPosSC.xyz, maxPosSC.xyz);\n var rayStepSC: vec4<f32> = (maxPosSC - minPosSC)*(mapperUBO.SampleDistance/rayLengthSC);\n rayStepSC.w = 0.0;\n\n var computedColor: vec4<f32>;\n\n//VTK::Volume::Loop\n\n//VTK::RenderEncoder::Impl\n }\n\n return output;\n}\n";
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const volFragTemplate = `
|
|
12
|
+
//VTK::Renderer::Dec
|
|
13
|
+
|
|
14
|
+
//VTK::Mapper::Dec
|
|
15
|
+
|
|
16
|
+
//VTK::TCoord::Dec
|
|
17
|
+
|
|
18
|
+
//VTK::Volume::TraverseDec
|
|
19
|
+
|
|
20
|
+
//VTK::RenderEncoder::Dec
|
|
21
|
+
|
|
22
|
+
//VTK::IOStructs::Dec
|
|
23
|
+
|
|
24
|
+
fn getTextureValue(vTex: texture_3d<f32>, tpos: vec4<f32>) -> f32
|
|
25
|
+
{
|
|
26
|
+
// todo multicomponent support
|
|
27
|
+
return textureSampleLevel(vTex, clampSampler, tpos.xyz, 0.0).r;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fn getGradient(vTex: texture_3d<f32>, tpos: vec4<f32>, vNum: i32, scalar: f32) -> vec4<f32>
|
|
31
|
+
{
|
|
32
|
+
var result: vec4<f32>;
|
|
33
|
+
|
|
34
|
+
var tstep: vec4<f32> = volumeSSBO.values[vNum].tstep;
|
|
35
|
+
result.x = getTextureValue(vTex, tpos + vec4<f32>(tstep.x, 0.0, 0.0, 1.0)) - scalar;
|
|
36
|
+
result.y = getTextureValue(vTex, tpos + vec4<f32>(0.0, tstep.y, 0.0, 1.0)) - scalar;
|
|
37
|
+
result.z = getTextureValue(vTex, tpos + vec4<f32>(0.0, 0.0, tstep.z, 1.0)) - scalar;
|
|
38
|
+
result.w = 0.0;
|
|
39
|
+
|
|
40
|
+
// divide by spacing as that is our delta
|
|
41
|
+
result = result / volumeSSBO.values[vNum].spacing;
|
|
42
|
+
// now we have a gradient in unit tcoords
|
|
43
|
+
|
|
44
|
+
var grad: f32 = length(result.xyz);
|
|
45
|
+
if (grad > 0.0)
|
|
46
|
+
{
|
|
47
|
+
// rotate to View Coords, needed for lighting and shading
|
|
48
|
+
var nMat: mat4x4<f32> = rendererUBO.SCVCMatrix * volumeSSBO.values[vNum].planeNormals;
|
|
49
|
+
result = nMat * result;
|
|
50
|
+
result = result / length(result);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// store gradient magnitude in .w
|
|
54
|
+
result.w = grad;
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fn processVolume(vTex: texture_3d<f32>, vNum: i32, cNum: i32, posSC: vec4<f32>, tfunRows: f32) -> vec4<f32>
|
|
60
|
+
{
|
|
61
|
+
var outColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);
|
|
62
|
+
|
|
63
|
+
// convert to tcoords and reject if outside the volume
|
|
64
|
+
var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*posSC;
|
|
65
|
+
if (tpos.x < 0.0 || tpos.y < 0.0 || tpos.z < 0.0 ||
|
|
66
|
+
tpos.x > 1.0 || tpos.y > 1.0 || tpos.z > 1.0) { return outColor; }
|
|
67
|
+
|
|
68
|
+
var scalar: f32 = getTextureValue(vTex, tpos);
|
|
69
|
+
|
|
70
|
+
var coord: vec2<f32> =
|
|
71
|
+
vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,
|
|
72
|
+
(0.5 + 2.0 * f32(vNum)) / tfunRows);
|
|
73
|
+
var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);
|
|
74
|
+
|
|
75
|
+
var gofactor: f32 = 1.0;
|
|
76
|
+
var normal: vec4<f32> = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
77
|
+
if (componentSSBO.values[cNum].gomin < 1.0 || volumeSSBO.values[vNum].shade[0] > 0.0)
|
|
78
|
+
{
|
|
79
|
+
normal = getGradient(vTex, tpos, vNum, scalar);
|
|
80
|
+
if (componentSSBO.values[cNum].gomin < 1.0)
|
|
81
|
+
{
|
|
82
|
+
gofactor = clamp(normal.a*componentSSBO.values[cNum].goScale + componentSSBO.values[cNum].goShift,
|
|
83
|
+
componentSSBO.values[cNum].gomin, componentSSBO.values[cNum].gomax);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);
|
|
88
|
+
var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;
|
|
89
|
+
|
|
90
|
+
if (volumeSSBO.values[vNum].shade[0] > 0.0)
|
|
91
|
+
{
|
|
92
|
+
color = color*abs(normal.z);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
outColor = vec4<f32>(color.rgb, gofactor * opacity);
|
|
96
|
+
|
|
97
|
+
return outColor;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// adjust the start and end point of a raycast such that it intersects the unit cube.
|
|
101
|
+
// This function is used to take a raycast starting point and step vector
|
|
102
|
+
// and numSteps and return the startijng and ending steps for intersecting the
|
|
103
|
+
// unit cube. Recall for a 3D texture, the unit cube is the range of texture coordsinates
|
|
104
|
+
// that have valid values. So this funtion can be used to take a ray in texture coordinates
|
|
105
|
+
// and bound it to intersecting the texture.
|
|
106
|
+
//
|
|
107
|
+
fn adjustBounds(tpos: vec4<f32>, tstep: vec4<f32>, numSteps: f32) -> vec2<f32>
|
|
108
|
+
{
|
|
109
|
+
var result: vec2<f32> = vec2<f32>(0.0, numSteps);
|
|
110
|
+
var tpos2: vec4<f32> = tpos + tstep*numSteps;
|
|
111
|
+
|
|
112
|
+
// move tpos to the start of the volume
|
|
113
|
+
var adjust: f32 =
|
|
114
|
+
min(
|
|
115
|
+
max(tpos.x/tstep.x, (tpos.x - 1.0)/tstep.x),
|
|
116
|
+
min(
|
|
117
|
+
max((tpos.y - 1.0)/tstep.y, tpos.y/tstep.y),
|
|
118
|
+
max((tpos.z - 1.0)/tstep.z, tpos.z/tstep.z)));
|
|
119
|
+
if (adjust < 0.0)
|
|
120
|
+
{
|
|
121
|
+
result.x = result.x - adjust;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// adjust length to the end
|
|
125
|
+
adjust =
|
|
126
|
+
max(
|
|
127
|
+
min(tpos2.x/tstep.x, (tpos2.x - 1.0)/tstep.x),
|
|
128
|
+
max(
|
|
129
|
+
min((tpos2.y - 1.0)/tstep.y, tpos2.y/tstep.y),
|
|
130
|
+
min((tpos2.z - 1.0)/tstep.z, tpos2.z/tstep.z)));
|
|
131
|
+
if (adjust > 0.0)
|
|
132
|
+
{
|
|
133
|
+
result.y = result.y - adjust;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
fn getSimpleColor(scalar: f32, vNum: i32, cNum: i32) -> vec4<f32>
|
|
140
|
+
{
|
|
141
|
+
// how many rows (tfuns) do we have in our tfunTexture
|
|
142
|
+
var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);
|
|
143
|
+
|
|
144
|
+
var coord: vec2<f32> =
|
|
145
|
+
vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,
|
|
146
|
+
(0.5 + 2.0 * f32(vNum)) / tfunRows);
|
|
147
|
+
var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);
|
|
148
|
+
coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);
|
|
149
|
+
var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;
|
|
150
|
+
return vec4<f32>(color.rgb, opacity);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
fn traverseMax(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)
|
|
154
|
+
{
|
|
155
|
+
// convert to tcoords and reject if outside the volume
|
|
156
|
+
var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;
|
|
157
|
+
var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;
|
|
158
|
+
var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);
|
|
159
|
+
var tstep: vec4<f32> = tpos2 - tpos;
|
|
160
|
+
|
|
161
|
+
var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);
|
|
162
|
+
|
|
163
|
+
// did we hit anything
|
|
164
|
+
if (rayBounds.x >= rayBounds.y)
|
|
165
|
+
{
|
|
166
|
+
traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
tpos = tpos + tstep*rayBounds.x;
|
|
171
|
+
var curDist: f32 = rayBounds.x;
|
|
172
|
+
var maxVal: f32 = -1.0e37;
|
|
173
|
+
loop
|
|
174
|
+
{
|
|
175
|
+
var scalar: f32 = getTextureValue(vTex, tpos);
|
|
176
|
+
if (scalar > maxVal)
|
|
177
|
+
{
|
|
178
|
+
maxVal = scalar;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// increment position
|
|
182
|
+
curDist = curDist + 1.0;
|
|
183
|
+
tpos = tpos + tstep;
|
|
184
|
+
|
|
185
|
+
// check if we have reached a terminating condition
|
|
186
|
+
if (curDist > rayBounds.y) { break; }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// process to get the color and opacity
|
|
190
|
+
traverseVals[vNum] = getSimpleColor(maxVal, vNum, cNum);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
fn traverseMin(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)
|
|
194
|
+
{
|
|
195
|
+
// convert to tcoords and reject if outside the volume
|
|
196
|
+
var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;
|
|
197
|
+
var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;
|
|
198
|
+
var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);
|
|
199
|
+
var tstep: vec4<f32> = tpos2 - tpos;
|
|
200
|
+
|
|
201
|
+
var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);
|
|
202
|
+
|
|
203
|
+
// did we hit anything
|
|
204
|
+
if (rayBounds.x >= rayBounds.y)
|
|
205
|
+
{
|
|
206
|
+
traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
tpos = tpos + tstep*rayBounds.x;
|
|
211
|
+
var curDist: f32 = rayBounds.x;
|
|
212
|
+
var minVal: f32 = 1.0e37;
|
|
213
|
+
loop
|
|
214
|
+
{
|
|
215
|
+
var scalar: f32 = getTextureValue(vTex, tpos);
|
|
216
|
+
if (scalar < minVal)
|
|
217
|
+
{
|
|
218
|
+
minVal = scalar;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// increment position
|
|
222
|
+
curDist = curDist + 1.0;
|
|
223
|
+
tpos = tpos + tstep;
|
|
224
|
+
|
|
225
|
+
// check if we have reached a terminating condition
|
|
226
|
+
if (curDist > rayBounds.y) { break; }
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// process to get the color and opacity
|
|
230
|
+
traverseVals[vNum] = getSimpleColor(minVal, vNum, cNum);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
fn traverseAverage(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)
|
|
234
|
+
{
|
|
235
|
+
// convert to tcoords and reject if outside the volume
|
|
236
|
+
var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;
|
|
237
|
+
var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;
|
|
238
|
+
var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);
|
|
239
|
+
var tstep: vec4<f32> = tpos2 - tpos;
|
|
240
|
+
|
|
241
|
+
var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);
|
|
242
|
+
|
|
243
|
+
// did we hit anything
|
|
244
|
+
if (rayBounds.x >= rayBounds.y)
|
|
245
|
+
{
|
|
246
|
+
traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;
|
|
251
|
+
tpos = tpos + tstep*rayBounds.x;
|
|
252
|
+
var curDist: f32 = rayBounds.x;
|
|
253
|
+
var avgVal: f32 = 0.0;
|
|
254
|
+
var sampleCount: f32 = 0.0;
|
|
255
|
+
loop
|
|
256
|
+
{
|
|
257
|
+
var sample: f32 = getTextureValue(vTex, tpos);
|
|
258
|
+
// right now leave filtering off until WebGL changes get merged
|
|
259
|
+
// if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)
|
|
260
|
+
// {
|
|
261
|
+
avgVal = avgVal + sample;
|
|
262
|
+
sampleCount = sampleCount + 1.0;
|
|
263
|
+
// }
|
|
264
|
+
|
|
265
|
+
// increment position
|
|
266
|
+
curDist = curDist + 1.0;
|
|
267
|
+
tpos = tpos + tstep;
|
|
268
|
+
|
|
269
|
+
// check if we have reached a terminating condition
|
|
270
|
+
if (curDist > rayBounds.y) { break; }
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (sampleCount <= 0.0)
|
|
274
|
+
{
|
|
275
|
+
traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// process to get the color and opacity
|
|
279
|
+
traverseVals[vNum] = getSimpleColor(avgVal/sampleCount, vNum, cNum);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
fn traverseAdditive(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)
|
|
283
|
+
{
|
|
284
|
+
// convert to tcoords and reject if outside the volume
|
|
285
|
+
var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;
|
|
286
|
+
var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;
|
|
287
|
+
var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);
|
|
288
|
+
var tstep: vec4<f32> = tpos2 - tpos;
|
|
289
|
+
|
|
290
|
+
var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);
|
|
291
|
+
|
|
292
|
+
// did we hit anything
|
|
293
|
+
if (rayBounds.x >= rayBounds.y)
|
|
294
|
+
{
|
|
295
|
+
traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;
|
|
300
|
+
tpos = tpos + tstep*rayBounds.x;
|
|
301
|
+
var curDist: f32 = rayBounds.x;
|
|
302
|
+
var sumVal: f32 = 0.0;
|
|
303
|
+
loop
|
|
304
|
+
{
|
|
305
|
+
var sample: f32 = getTextureValue(vTex, tpos);
|
|
306
|
+
// right now leave filtering off until WebGL changes get merged
|
|
307
|
+
// if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)
|
|
308
|
+
// {
|
|
309
|
+
sumVal = sumVal + sample;
|
|
310
|
+
// }
|
|
311
|
+
|
|
312
|
+
// increment position
|
|
313
|
+
curDist = curDist + 1.0;
|
|
314
|
+
tpos = tpos + tstep;
|
|
315
|
+
|
|
316
|
+
// check if we have reached a terminating condition
|
|
317
|
+
if (curDist > rayBounds.y) { break; }
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// process to get the color and opacity
|
|
321
|
+
traverseVals[vNum] = getSimpleColor(sumVal, vNum, cNum);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
fn composite(rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>) -> vec4<f32>
|
|
325
|
+
{
|
|
326
|
+
// initial ray position is at the beginning
|
|
327
|
+
var rayPosSC: vec4<f32> = minPosSC;
|
|
328
|
+
|
|
329
|
+
// how many rows (tfuns) do we have in our tfunTexture
|
|
330
|
+
var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);
|
|
331
|
+
|
|
332
|
+
var curDist: f32 = 0.0;
|
|
333
|
+
var computedColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);
|
|
334
|
+
var sampleColor: vec4<f32>;
|
|
335
|
+
//VTK::Volume::TraverseCalls
|
|
336
|
+
|
|
337
|
+
loop
|
|
338
|
+
{
|
|
339
|
+
// for each volume, sample and accumulate color
|
|
340
|
+
//VTK::Volume::CompositeCalls
|
|
341
|
+
|
|
342
|
+
// increment position
|
|
343
|
+
curDist = curDist + mapperUBO.SampleDistance;
|
|
344
|
+
rayPosSC = rayPosSC + rayStepSC;
|
|
345
|
+
|
|
346
|
+
// check if we have reached a terminating condition
|
|
347
|
+
if (curDist > rayLengthSC) { break; }
|
|
348
|
+
if (computedColor.a > 0.98) { break; }
|
|
349
|
+
}
|
|
350
|
+
return computedColor;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@fragment
|
|
354
|
+
fn main(
|
|
355
|
+
//VTK::IOStructs::Input
|
|
356
|
+
)
|
|
357
|
+
//VTK::IOStructs::Output
|
|
358
|
+
{
|
|
359
|
+
var output: fragmentOutput;
|
|
360
|
+
|
|
361
|
+
var rayMax: f32 = textureSampleLevel(maxTexture, clampSampler, input.tcoordVS, 0.0).r;
|
|
362
|
+
var rayMin: f32 = textureSampleLevel(minTexture, clampSampler, input.tcoordVS, 0.0).r;
|
|
363
|
+
|
|
364
|
+
// discard empty rays
|
|
365
|
+
if (rayMax <= rayMin) { discard; }
|
|
366
|
+
else
|
|
367
|
+
{
|
|
368
|
+
// compute start and end ray positions in view coordinates
|
|
369
|
+
var minPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMax, 1.0);
|
|
370
|
+
minPosSC = minPosSC * (1.0 / minPosSC.w);
|
|
371
|
+
var maxPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMin, 1.0);
|
|
372
|
+
maxPosSC = maxPosSC * (1.0 / maxPosSC.w);
|
|
373
|
+
|
|
374
|
+
var rayLengthSC: f32 = distance(minPosSC.xyz, maxPosSC.xyz);
|
|
375
|
+
var rayStepSC: vec4<f32> = (maxPosSC - minPosSC)*(mapperUBO.SampleDistance/rayLengthSC);
|
|
376
|
+
rayStepSC.w = 0.0;
|
|
377
|
+
|
|
378
|
+
var computedColor: vec4<f32>;
|
|
379
|
+
|
|
380
|
+
//VTK::Volume::Loop
|
|
381
|
+
|
|
382
|
+
//VTK::RenderEncoder::Impl
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return output;
|
|
386
|
+
}
|
|
387
|
+
`;
|
|
388
|
+
const tmpMat4 = new Float64Array(16);
|
|
389
|
+
const tmp2Mat4 = new Float64Array(16);
|
|
390
|
+
|
|
391
|
+
// ----------------------------------------------------------------------------
|
|
15
392
|
// vtkWebGPUVolumePassFSQ methods
|
|
16
393
|
// ----------------------------------------------------------------------------
|
|
17
394
|
|
|
18
395
|
function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
19
396
|
// Set our className
|
|
20
397
|
model.classHierarchy.push('vtkWebGPUVolumePassFSQ');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var vDesc = pipeline.getShaderDescription('vertex');
|
|
398
|
+
publicAPI.replaceShaderPosition = (hash, pipeline, vertexInput) => {
|
|
399
|
+
const vDesc = pipeline.getShaderDescription('vertex');
|
|
24
400
|
vDesc.addBuiltinOutput('vec4<f32>', '@builtin(position) Position');
|
|
25
|
-
|
|
401
|
+
let code = vDesc.getCode();
|
|
26
402
|
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', ['output.tcoordVS = vec2<f32>(vertexBC.x * 0.5 + 0.5, 1.0 - vertexBC.y * 0.5 - 0.5);', 'output.Position = vec4<f32>(vertexBC, 1.0);']).result;
|
|
27
403
|
vDesc.setCode(code);
|
|
28
|
-
|
|
404
|
+
const fDesc = pipeline.getShaderDescription('fragment');
|
|
29
405
|
fDesc.addBuiltinInput('vec4<f32>', '@builtin(position) fragPos');
|
|
30
406
|
};
|
|
31
|
-
|
|
32
407
|
model.shaderReplacements.set('replaceShaderPosition', publicAPI.replaceShaderPosition);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
for (var i = 0; i < model.volumes.length; i++) {
|
|
408
|
+
publicAPI.replaceShaderVolume = (hash, pipeline, vertexInput) => {
|
|
409
|
+
const fDesc = pipeline.getShaderDescription('fragment');
|
|
410
|
+
let code = fDesc.getCode();
|
|
411
|
+
const compositeCalls = [];
|
|
412
|
+
const traverseCalls = [];
|
|
413
|
+
for (let i = 0; i < model.volumes.length; i++) {
|
|
41
414
|
// todo pass rowPos
|
|
42
|
-
|
|
43
|
-
|
|
415
|
+
const blendMode = model.volumes[i].getRenderable().getMapper().getBlendMode();
|
|
44
416
|
if (blendMode === BlendMode.COMPOSITE_BLEND) {
|
|
45
|
-
compositeCalls.push(
|
|
46
|
-
compositeCalls.push(
|
|
417
|
+
compositeCalls.push(` sampleColor = processVolume(volTexture${i}, ${i}, ${model.rowStarts[i]}, rayPosSC, tfunRows);`);
|
|
418
|
+
compositeCalls.push(` computedColor = vec4<f32>(
|
|
419
|
+
sampleColor.a * sampleColor.rgb * (1.0 - computedColor.a) + computedColor.rgb,
|
|
420
|
+
(1.0 - computedColor.a)*sampleColor.a + computedColor.a);`);
|
|
47
421
|
} else {
|
|
48
|
-
traverseCalls.push(
|
|
49
|
-
traverseCalls.push(
|
|
422
|
+
traverseCalls.push(` sampleColor = traverseVals[${i}];`);
|
|
423
|
+
traverseCalls.push(` computedColor = vec4<f32>(
|
|
424
|
+
sampleColor.a * sampleColor.rgb * (1.0 - computedColor.a) + computedColor.rgb,
|
|
425
|
+
(1.0 - computedColor.a)*sampleColor.a + computedColor.a);`);
|
|
50
426
|
}
|
|
51
427
|
}
|
|
52
|
-
|
|
53
428
|
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::CompositeCalls', compositeCalls).result;
|
|
54
429
|
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::TraverseCalls', traverseCalls).result;
|
|
55
|
-
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::TraverseDec', [
|
|
430
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::TraverseDec', [`var<private> traverseVals: array<vec4<f32>,${model.volumes.length}>;`]).result;
|
|
56
431
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
for (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (_blendMode === BlendMode.COMPOSITE_BLEND) {
|
|
432
|
+
// call the full and partial methods as needed
|
|
433
|
+
let compositeWhileTraversing = false;
|
|
434
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
435
|
+
const blendMode = model.volumes[vidx].getRenderable().getMapper().getBlendMode();
|
|
436
|
+
if (blendMode === BlendMode.COMPOSITE_BLEND) {
|
|
63
437
|
compositeWhileTraversing = true;
|
|
64
|
-
} else if (
|
|
65
|
-
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [
|
|
66
|
-
} else if (
|
|
67
|
-
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [
|
|
68
|
-
} else if (
|
|
69
|
-
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [
|
|
70
|
-
} else if (
|
|
71
|
-
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [
|
|
438
|
+
} else if (blendMode === BlendMode.MAXIMUM_INTENSITY_BLEND) {
|
|
439
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [` traverseMax(volTexture${vidx}, ${vidx}, ${vidx}, rayLengthSC, minPosSC, rayStepSC);`, ` computedColor = traverseVals[${vidx}];`, '//VTK::Volume::Loop']).result;
|
|
440
|
+
} else if (blendMode === BlendMode.MINIMUM_INTENSITY_BLEND) {
|
|
441
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [` traverseMin(volTexture${vidx}, ${vidx}, ${vidx}, rayLengthSC, minPosSC, rayStepSC);`, ` computedColor = traverseVals[${vidx}];`, '//VTK::Volume::Loop']).result;
|
|
442
|
+
} else if (blendMode === BlendMode.AVERAGE_INTENSITY_BLEND) {
|
|
443
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [` traverseAverage(volTexture${vidx}, ${vidx}, ${vidx}, rayLengthSC, minPosSC, rayStepSC);`, ` computedColor = traverseVals[${vidx}];`, '//VTK::Volume::Loop']).result;
|
|
444
|
+
} else if (blendMode === BlendMode.ADDITIVE_INTENSITY_BLEND) {
|
|
445
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [` traverseAdditive(volTexture${vidx}, ${vidx}, ${vidx}, rayLengthSC, minPosSC, rayStepSC);`, ` computedColor = traverseVals[${vidx}];`, '//VTK::Volume::Loop']).result;
|
|
72
446
|
}
|
|
73
447
|
}
|
|
74
|
-
|
|
75
448
|
if (compositeWhileTraversing) {
|
|
76
449
|
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Volume::Loop', [' computedColor = composite(rayLengthSC, minPosSC, rayStepSC);']).result;
|
|
77
450
|
}
|
|
78
|
-
|
|
79
451
|
fDesc.setCode(code);
|
|
80
452
|
};
|
|
81
|
-
|
|
82
453
|
model.shaderReplacements.set('replaceShaderVolume', publicAPI.replaceShaderVolume);
|
|
83
|
-
|
|
84
|
-
publicAPI.updateLUTImage = function (device) {
|
|
454
|
+
publicAPI.updateLUTImage = device => {
|
|
85
455
|
// depends on
|
|
86
456
|
// - volumes array (length and values) - mtime
|
|
87
457
|
// - tfun arrays - renderable/property mtime
|
|
88
|
-
var mtime = publicAPI.getMTime();
|
|
89
458
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
459
|
+
let mtime = publicAPI.getMTime();
|
|
460
|
+
for (let i = 0; i < model.volumes.length; i++) {
|
|
461
|
+
const vol = model.volumes[i].getRenderable();
|
|
462
|
+
const image = vol.getMapper().getInputData();
|
|
93
463
|
mtime = Math.max(mtime, vol.getMTime(), image.getMTime());
|
|
94
464
|
}
|
|
95
|
-
|
|
96
465
|
if (mtime < model.lutBuildTime.getMTime()) {
|
|
97
466
|
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
467
|
+
}
|
|
100
468
|
|
|
469
|
+
// first determine how large the image should be
|
|
101
470
|
model.numRows = 0;
|
|
102
471
|
model.rowStarts = [];
|
|
103
|
-
|
|
104
|
-
for (var vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
472
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
105
473
|
model.rowStarts.push(model.numRows);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
var numComp = scalars.getNumberOfComponents();
|
|
116
|
-
var iComps = vprop.getIndependentComponents();
|
|
117
|
-
var numIComps = iComps ? numComp : 1;
|
|
474
|
+
const webgpuvol = model.volumes[vidx];
|
|
475
|
+
const actor = webgpuvol.getRenderable();
|
|
476
|
+
const volMapr = actor.getMapper();
|
|
477
|
+
const vprop = actor.getProperty();
|
|
478
|
+
const image = volMapr.getInputData();
|
|
479
|
+
const scalars = image.getPointData() && image.getPointData().getScalars();
|
|
480
|
+
const numComp = scalars.getNumberOfComponents();
|
|
481
|
+
const iComps = vprop.getIndependentComponents();
|
|
482
|
+
const numIComps = iComps ? numComp : 1;
|
|
118
483
|
model.numRows += numIComps;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
var colorArray = new Uint8Array(model.numRows * 2 * model.rowLength * 4);
|
|
123
|
-
var opacityArray = new Float32Array(model.numRows * 2 * model.rowLength);
|
|
124
|
-
var imgRow = 0;
|
|
125
|
-
var tmpTable = new Float32Array(model.rowLength * 3);
|
|
126
|
-
var rowLength = model.rowLength;
|
|
127
|
-
|
|
128
|
-
for (var _vidx = 0; _vidx < model.volumes.length; _vidx++) {
|
|
129
|
-
var _webgpuvol = model.volumes[_vidx];
|
|
130
|
-
|
|
131
|
-
var _actor = _webgpuvol.getRenderable();
|
|
132
|
-
|
|
133
|
-
var _volMapr = _actor.getMapper();
|
|
134
|
-
|
|
135
|
-
var _vprop = _actor.getProperty();
|
|
136
|
-
|
|
137
|
-
var _image2 = _volMapr.getInputData();
|
|
138
|
-
|
|
139
|
-
var _scalars = _image2.getPointData() && _image2.getPointData().getScalars();
|
|
140
|
-
|
|
141
|
-
var _numComp = _scalars.getNumberOfComponents();
|
|
142
|
-
|
|
143
|
-
var _iComps = _vprop.getIndependentComponents();
|
|
144
|
-
|
|
145
|
-
var _numIComps = _iComps ? _numComp : 1;
|
|
146
|
-
|
|
147
|
-
for (var c = 0; c < _numIComps; ++c) {
|
|
148
|
-
var cfun = _vprop.getRGBTransferFunction(c);
|
|
484
|
+
}
|
|
149
485
|
|
|
150
|
-
|
|
486
|
+
// allocate the image array
|
|
487
|
+
const colorArray = new Uint8Array(model.numRows * 2 * model.rowLength * 4);
|
|
488
|
+
const opacityArray = new Float32Array(model.numRows * 2 * model.rowLength);
|
|
489
|
+
let imgRow = 0;
|
|
490
|
+
const tmpTable = new Float32Array(model.rowLength * 3);
|
|
491
|
+
const rowLength = model.rowLength;
|
|
492
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
493
|
+
const webgpuvol = model.volumes[vidx];
|
|
494
|
+
const actor = webgpuvol.getRenderable();
|
|
495
|
+
const volMapr = actor.getMapper();
|
|
496
|
+
const vprop = actor.getProperty();
|
|
497
|
+
const image = volMapr.getInputData();
|
|
498
|
+
const scalars = image.getPointData() && image.getPointData().getScalars();
|
|
499
|
+
const numComp = scalars.getNumberOfComponents();
|
|
500
|
+
const iComps = vprop.getIndependentComponents();
|
|
501
|
+
const numIComps = iComps ? numComp : 1;
|
|
502
|
+
for (let c = 0; c < numIComps; ++c) {
|
|
503
|
+
const cfun = vprop.getRGBTransferFunction(c);
|
|
504
|
+
const cRange = cfun.getRange();
|
|
151
505
|
cfun.getTable(cRange[0], cRange[1], rowLength, tmpTable, 1);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
colorArray[ioffset +
|
|
156
|
-
colorArray[ioffset +
|
|
157
|
-
colorArray[ioffset +
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
for (var co = 0; co < 4; co++) {
|
|
161
|
-
colorArray[ioffset + (rowLength + _i) * 4 + co] = colorArray[ioffset + _i * 4 + co];
|
|
506
|
+
let ioffset = imgRow * rowLength * 4;
|
|
507
|
+
for (let i = 0; i < rowLength; ++i) {
|
|
508
|
+
colorArray[ioffset + i * 4] = 255.0 * tmpTable[i * 3];
|
|
509
|
+
colorArray[ioffset + i * 4 + 1] = 255.0 * tmpTable[i * 3 + 1];
|
|
510
|
+
colorArray[ioffset + i * 4 + 2] = 255.0 * tmpTable[i * 3 + 2];
|
|
511
|
+
colorArray[ioffset + i * 4 + 3] = 255.0;
|
|
512
|
+
for (let co = 0; co < 4; co++) {
|
|
513
|
+
colorArray[ioffset + (rowLength + i) * 4 + co] = colorArray[ioffset + i * 4 + co];
|
|
162
514
|
}
|
|
163
515
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
var oRange = ofun.getRange();
|
|
170
|
-
ofun.getTable(oRange[0], oRange[1], rowLength, tmpTable, 1); // adjust for sample distance etc
|
|
171
|
-
|
|
516
|
+
const ofun = vprop.getScalarOpacity(c);
|
|
517
|
+
const opacityFactor = model.sampleDist / vprop.getScalarOpacityUnitDistance(c);
|
|
518
|
+
const oRange = ofun.getRange();
|
|
519
|
+
ofun.getTable(oRange[0], oRange[1], rowLength, tmpTable, 1);
|
|
520
|
+
// adjust for sample distance etc
|
|
172
521
|
ioffset = imgRow * rowLength;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
opacityArray[ioffset +
|
|
176
|
-
opacityArray[ioffset + _i2 + rowLength] = opacityArray[ioffset + _i2];
|
|
522
|
+
for (let i = 0; i < rowLength; ++i) {
|
|
523
|
+
opacityArray[ioffset + i] = 1.0 - (1.0 - tmpTable[i]) ** opacityFactor;
|
|
524
|
+
opacityArray[ioffset + i + rowLength] = opacityArray[ioffset + i];
|
|
177
525
|
}
|
|
178
|
-
|
|
179
526
|
imgRow += 2;
|
|
180
527
|
}
|
|
181
528
|
}
|
|
182
|
-
|
|
183
529
|
{
|
|
184
|
-
|
|
530
|
+
const treq = {
|
|
185
531
|
nativeArray: colorArray,
|
|
186
532
|
width: model.rowLength,
|
|
187
533
|
height: model.numRows * 2,
|
|
188
534
|
depth: 1,
|
|
189
535
|
format: 'rgba8unorm'
|
|
190
536
|
};
|
|
191
|
-
|
|
192
|
-
|
|
537
|
+
const newTex = device.getTextureManager().getTexture(treq);
|
|
538
|
+
const tview = newTex.createView('tfunTexture');
|
|
193
539
|
model.textureViews[2] = tview;
|
|
194
540
|
}
|
|
195
541
|
{
|
|
196
|
-
|
|
542
|
+
const treq = {
|
|
197
543
|
nativeArray: opacityArray,
|
|
198
544
|
width: model.rowLength,
|
|
199
545
|
height: model.numRows * 2,
|
|
200
546
|
depth: 1,
|
|
201
547
|
format: 'r16float'
|
|
202
548
|
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
var _tview = _newTex.createView('ofunTexture');
|
|
207
|
-
|
|
208
|
-
model.textureViews[3] = _tview;
|
|
549
|
+
const newTex = device.getTextureManager().getTexture(treq);
|
|
550
|
+
const tview = newTex.createView('ofunTexture');
|
|
551
|
+
model.textureViews[3] = tview;
|
|
209
552
|
}
|
|
210
553
|
model.lutBuildTime.modified();
|
|
211
554
|
};
|
|
212
|
-
|
|
213
|
-
publicAPI.updateSSBO = function (device) {
|
|
555
|
+
publicAPI.updateSSBO = device => {
|
|
214
556
|
// if any of
|
|
215
557
|
// - color or opacity tfun ranges changed - volume Mtime
|
|
216
558
|
// - any volume matrix changed - volume MTime
|
|
217
559
|
// - stabilized center changed - ren.stabilizedMTime
|
|
218
560
|
// - any volume's input data worldtoindex or dimensions changed - input's mtime
|
|
219
561
|
//
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
var image = volMapr.getInputData();
|
|
562
|
+
let mtime = Math.max(publicAPI.getMTime(), model.WebGPURenderer.getStabilizedTime());
|
|
563
|
+
for (let i = 0; i < model.volumes.length; i++) {
|
|
564
|
+
const vol = model.volumes[i].getRenderable();
|
|
565
|
+
const volMapr = vol.getMapper();
|
|
566
|
+
const image = volMapr.getInputData();
|
|
226
567
|
mtime = Math.max(mtime, vol.getMTime(), image.getMTime(), volMapr.getMTime());
|
|
227
568
|
}
|
|
228
|
-
|
|
229
569
|
if (mtime < model.SSBO.getSendTime()) {
|
|
230
570
|
return;
|
|
231
|
-
}
|
|
232
|
-
|
|
571
|
+
}
|
|
233
572
|
|
|
234
|
-
|
|
573
|
+
// create the volumeSBBO
|
|
574
|
+
const center = model.WebGPURenderer.getStabilizedCenterByReference();
|
|
235
575
|
model.SSBO.clearData();
|
|
236
|
-
model.SSBO.setNumberOfInstances(model.volumes.length);
|
|
576
|
+
model.SSBO.setNumberOfInstances(model.volumes.length);
|
|
577
|
+
|
|
578
|
+
// create SCTC matrices SC -> world -> model -> index -> tcoord
|
|
237
579
|
//
|
|
238
580
|
// when doing coord conversions from A to C recall
|
|
239
581
|
// the order is mat4.mult(AtoC, BtoC, AtoB);
|
|
240
582
|
//
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
var _volMapr2 = actor.getMapper();
|
|
254
|
-
|
|
255
|
-
var _image3 = _volMapr2.getInputData();
|
|
256
|
-
|
|
583
|
+
const marray = new Float64Array(model.volumes.length * 16);
|
|
584
|
+
const vPlaneArray = new Float64Array(model.volumes.length * 16);
|
|
585
|
+
const tstepArray = new Float64Array(model.volumes.length * 4);
|
|
586
|
+
const shadeArray = new Float64Array(model.volumes.length * 4);
|
|
587
|
+
const spacingArray = new Float64Array(model.volumes.length * 4);
|
|
588
|
+
const ipScalarRangeArray = new Float64Array(model.volumes.length * 4);
|
|
589
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
590
|
+
const webgpuvol = model.volumes[vidx];
|
|
591
|
+
const actor = webgpuvol.getRenderable();
|
|
592
|
+
const volMapr = actor.getMapper();
|
|
593
|
+
const image = volMapr.getInputData();
|
|
257
594
|
mat4.identity(tmpMat4);
|
|
258
|
-
mat4.translate(tmpMat4, tmpMat4, center);
|
|
595
|
+
mat4.translate(tmpMat4, tmpMat4, center);
|
|
596
|
+
// tmpMat4 is now SC->World
|
|
259
597
|
|
|
260
|
-
|
|
598
|
+
const mcwcmat = actor.getMatrix();
|
|
261
599
|
mat4.transpose(tmp2Mat4, mcwcmat);
|
|
262
|
-
mat4.invert(tmp2Mat4, tmp2Mat4);
|
|
600
|
+
mat4.invert(tmp2Mat4, tmp2Mat4);
|
|
601
|
+
// tmp2Mat4 is now world to model
|
|
602
|
+
|
|
603
|
+
mat4.multiply(tmpMat4, tmp2Mat4, tmpMat4);
|
|
604
|
+
// tmp4Mat is now SC->Model
|
|
263
605
|
|
|
264
|
-
mat4.multiply(tmpMat4, tmp2Mat4, tmpMat4); // tmp4Mat is now SC->Model
|
|
265
606
|
// the method on the data is world to index but the volume is in
|
|
266
607
|
// model coordinates so really in this context it is model to index
|
|
608
|
+
const modelToIndex = image.getWorldToIndex();
|
|
609
|
+
mat4.multiply(tmpMat4, modelToIndex, tmpMat4);
|
|
610
|
+
// tmpMat4 is now SC -> Index
|
|
267
611
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
mat4.multiply(tmpMat4, modelToIndex, tmpMat4); // tmpMat4 is now SC -> Index
|
|
271
|
-
|
|
272
|
-
var dims = _image3.getDimensions();
|
|
273
|
-
|
|
612
|
+
const dims = image.getDimensions();
|
|
274
613
|
mat4.identity(tmp2Mat4);
|
|
275
614
|
mat4.scale(tmp2Mat4, tmp2Mat4, [1.0 / dims[0], 1.0 / dims[1], 1.0 / dims[2]]);
|
|
276
|
-
mat4.multiply(tmpMat4, tmp2Mat4, tmpMat4);
|
|
615
|
+
mat4.multiply(tmpMat4, tmp2Mat4, tmpMat4);
|
|
616
|
+
// tmpMat4 is now SC -> Tcoord
|
|
277
617
|
|
|
278
|
-
for (
|
|
618
|
+
for (let j = 0; j < 16; j++) {
|
|
279
619
|
marray[vidx * 16 + j] = tmpMat4[j];
|
|
280
620
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
for (
|
|
285
|
-
vPlaneArray[vidx * 16 +
|
|
286
|
-
vPlaneArray[vidx * 16 +
|
|
287
|
-
vPlaneArray[vidx * 16 +
|
|
288
|
-
vPlaneArray[vidx * 16 +
|
|
621
|
+
mat4.invert(tmpMat4, tmpMat4);
|
|
622
|
+
// now it is Tcoord To SC
|
|
623
|
+
|
|
624
|
+
for (let j = 0; j < 4; j++) {
|
|
625
|
+
vPlaneArray[vidx * 16 + j * 4] = tmpMat4[j * 4];
|
|
626
|
+
vPlaneArray[vidx * 16 + j * 4 + 1] = tmpMat4[j * 4 + 1];
|
|
627
|
+
vPlaneArray[vidx * 16 + j * 4 + 2] = tmpMat4[j * 4 + 2];
|
|
628
|
+
vPlaneArray[vidx * 16 + j * 4 + 3] = 0.0;
|
|
289
629
|
}
|
|
290
|
-
|
|
291
630
|
tstepArray[vidx * 4] = 1.0 / dims[0];
|
|
292
631
|
tstepArray[vidx * 4 + 1] = 1.0 / dims[1];
|
|
293
632
|
tstepArray[vidx * 4 + 2] = 1.0 / dims[2];
|
|
294
633
|
tstepArray[vidx * 4 + 3] = 1.0;
|
|
295
634
|
shadeArray[vidx * 4] = actor.getProperty().getShade() ? 1.0 : 0.0;
|
|
296
|
-
|
|
297
|
-
var spacing = _image3.getSpacing();
|
|
298
|
-
|
|
635
|
+
const spacing = image.getSpacing();
|
|
299
636
|
spacingArray[vidx * 4] = spacing[0];
|
|
300
637
|
spacingArray[vidx * 4 + 1] = spacing[1];
|
|
301
638
|
spacingArray[vidx * 4 + 2] = spacing[2];
|
|
302
|
-
spacingArray[vidx * 4 + 3] = 1.0;
|
|
303
|
-
|
|
304
|
-
var tScale = model.textureViews[vidx + 4].getTexture().getScale();
|
|
305
|
-
|
|
306
|
-
var ipScalarRange = _volMapr2.getIpScalarRange();
|
|
639
|
+
spacingArray[vidx * 4 + 3] = 1.0;
|
|
307
640
|
|
|
641
|
+
// handle filteringMode
|
|
642
|
+
const tScale = model.textureViews[vidx + 4].getTexture().getScale();
|
|
643
|
+
const ipScalarRange = volMapr.getIpScalarRange();
|
|
308
644
|
ipScalarRangeArray[vidx * 4] = ipScalarRange[0] / tScale;
|
|
309
645
|
ipScalarRangeArray[vidx * 4 + 1] = ipScalarRange[1] / tScale;
|
|
310
|
-
ipScalarRangeArray[vidx * 4 + 2] =
|
|
646
|
+
ipScalarRangeArray[vidx * 4 + 2] = volMapr.getFilterMode();
|
|
311
647
|
}
|
|
312
|
-
|
|
313
648
|
model.SSBO.addEntry('SCTCMatrix', 'mat4x4<f32>');
|
|
314
649
|
model.SSBO.addEntry('planeNormals', 'mat4x4<f32>');
|
|
315
650
|
model.SSBO.addEntry('shade', 'vec4<f32>');
|
|
@@ -322,75 +657,68 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
322
657
|
model.SSBO.setAllInstancesFromArray('tstep', tstepArray);
|
|
323
658
|
model.SSBO.setAllInstancesFromArray('spacing', spacingArray);
|
|
324
659
|
model.SSBO.setAllInstancesFromArray('ipScalarRange', ipScalarRangeArray);
|
|
325
|
-
model.SSBO.send(device);
|
|
660
|
+
model.SSBO.send(device);
|
|
326
661
|
|
|
662
|
+
// now create the componentSSBO
|
|
327
663
|
model.componentSSBO.clearData();
|
|
328
664
|
model.componentSSBO.setNumberOfInstances(model.numRows);
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
665
|
+
const cScaleArray = new Float64Array(model.numRows);
|
|
666
|
+
const cShiftArray = new Float64Array(model.numRows);
|
|
667
|
+
const oScaleArray = new Float64Array(model.numRows);
|
|
668
|
+
const oShiftArray = new Float64Array(model.numRows);
|
|
669
|
+
const gominArray = new Float64Array(model.numRows);
|
|
670
|
+
const gomaxArray = new Float64Array(model.numRows);
|
|
671
|
+
const goshiftArray = new Float64Array(model.numRows);
|
|
672
|
+
const goscaleArray = new Float64Array(model.numRows);
|
|
673
|
+
let rowIdx = 0;
|
|
674
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
675
|
+
const webgpuvol = model.volumes[vidx];
|
|
676
|
+
const actor = webgpuvol.getRenderable();
|
|
677
|
+
const volMapr = actor.getMapper();
|
|
678
|
+
const vprop = actor.getProperty();
|
|
679
|
+
const image = volMapr.getInputData();
|
|
680
|
+
const scalars = image.getPointData() && image.getPointData().getScalars();
|
|
681
|
+
const numComp = scalars.getNumberOfComponents();
|
|
682
|
+
const iComps = vprop.getIndependentComponents();
|
|
683
|
+
// const numIComps = iComps ? numComp : 1;
|
|
345
684
|
|
|
346
|
-
var vprop = _actor2.getProperty();
|
|
347
|
-
|
|
348
|
-
var _image4 = _volMapr3.getInputData();
|
|
349
|
-
|
|
350
|
-
var scalars = _image4.getPointData() && _image4.getPointData().getScalars();
|
|
351
|
-
|
|
352
|
-
var numComp = scalars.getNumberOfComponents();
|
|
353
|
-
var iComps = vprop.getIndependentComponents(); // const numIComps = iComps ? numComp : 1;
|
|
354
685
|
// half float?
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
var halfFloat = tDetails.elementSize === 2 && tDetails.sampleType === 'float';
|
|
360
|
-
var volInfo = {
|
|
686
|
+
const tformat = model.textureViews[vidx + 4].getTexture().getFormat();
|
|
687
|
+
const tDetails = vtkWebGPUTypes.getDetailsFromTextureFormat(tformat);
|
|
688
|
+
const halfFloat = tDetails.elementSize === 2 && tDetails.sampleType === 'float';
|
|
689
|
+
const volInfo = {
|
|
361
690
|
scale: [255.0],
|
|
362
691
|
offset: [0.0]
|
|
363
692
|
};
|
|
364
|
-
|
|
365
693
|
if (halfFloat) {
|
|
366
694
|
volInfo.scale[0] = 1.0;
|
|
367
|
-
}
|
|
368
|
-
// for performance in the fragment shader
|
|
369
|
-
|
|
695
|
+
}
|
|
370
696
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
697
|
+
// three levels of shift scale combined into one
|
|
698
|
+
// for performance in the fragment shader
|
|
699
|
+
for (let compIdx = 0; compIdx < numComp; compIdx++) {
|
|
700
|
+
const target = iComps ? compIdx : 0;
|
|
701
|
+
const sscale = volInfo.scale[compIdx];
|
|
702
|
+
const ofun = vprop.getScalarOpacity(target);
|
|
703
|
+
const oRange = ofun.getRange();
|
|
704
|
+
const oscale = sscale / (oRange[1] - oRange[0]);
|
|
705
|
+
const oshift = (volInfo.offset[compIdx] - oRange[0]) / (oRange[1] - oRange[0]);
|
|
378
706
|
oShiftArray[rowIdx] = oshift;
|
|
379
707
|
oScaleArray[rowIdx] = oscale;
|
|
380
|
-
|
|
381
|
-
|
|
708
|
+
const cfun = vprop.getRGBTransferFunction(target);
|
|
709
|
+
const cRange = cfun.getRange();
|
|
382
710
|
cShiftArray[rowIdx] = (volInfo.offset[compIdx] - cRange[0]) / (cRange[1] - cRange[0]);
|
|
383
|
-
cScaleArray[rowIdx] = sscale / (cRange[1] - cRange[0]);
|
|
384
|
-
// not target (which is 0 in that case)
|
|
385
|
-
|
|
386
|
-
var useGO = vprop.getUseGradientOpacity(target);
|
|
711
|
+
cScaleArray[rowIdx] = sscale / (cRange[1] - cRange[0]);
|
|
387
712
|
|
|
713
|
+
// todo sscale for dependent should be based off of the A channel?
|
|
714
|
+
// not target (which is 0 in that case)
|
|
715
|
+
const useGO = vprop.getUseGradientOpacity(target);
|
|
388
716
|
if (useGO) {
|
|
389
|
-
|
|
390
|
-
|
|
717
|
+
const gomin = vprop.getGradientOpacityMinimumOpacity(target);
|
|
718
|
+
const gomax = vprop.getGradientOpacityMaximumOpacity(target);
|
|
391
719
|
gominArray[rowIdx] = gomin;
|
|
392
720
|
gomaxArray[rowIdx] = gomax;
|
|
393
|
-
|
|
721
|
+
const goRange = [vprop.getGradientOpacityMinimumValue(target), vprop.getGradientOpacityMaximumValue(target)];
|
|
394
722
|
goscaleArray[rowIdx] = sscale * (gomax - gomin) / (goRange[1] - goRange[0]);
|
|
395
723
|
goshiftArray[rowIdx] = -goRange[0] * (gomax - gomin) / (goRange[1] - goRange[0]) + gomin;
|
|
396
724
|
} else {
|
|
@@ -399,11 +727,9 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
399
727
|
goscaleArray[rowIdx] = 0.0;
|
|
400
728
|
goshiftArray[rowIdx] = 1.0;
|
|
401
729
|
}
|
|
402
|
-
|
|
403
730
|
rowIdx++;
|
|
404
731
|
}
|
|
405
732
|
}
|
|
406
|
-
|
|
407
733
|
model.componentSSBO.addEntry('cScale', 'f32');
|
|
408
734
|
model.componentSSBO.addEntry('cShift', 'f32');
|
|
409
735
|
model.componentSSBO.addEntry('oScale', 'f32');
|
|
@@ -422,59 +748,48 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
422
748
|
model.componentSSBO.setAllInstancesFromArray('gomax', gomaxArray);
|
|
423
749
|
model.componentSSBO.send(device);
|
|
424
750
|
};
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
var vol = model.volumes[i];
|
|
435
|
-
var volMapr = vol.getRenderable().getMapper();
|
|
436
|
-
var sd = volMapr.getSampleDistance();
|
|
437
|
-
|
|
751
|
+
const superClassUpdateBuffers = publicAPI.updateBuffers;
|
|
752
|
+
publicAPI.updateBuffers = () => {
|
|
753
|
+
superClassUpdateBuffers();
|
|
754
|
+
// compute the min step size
|
|
755
|
+
let sampleDist = model.volumes[0].getRenderable().getMapper().getSampleDistance();
|
|
756
|
+
for (let i = 0; i < model.volumes.length; i++) {
|
|
757
|
+
const vol = model.volumes[i];
|
|
758
|
+
const volMapr = vol.getRenderable().getMapper();
|
|
759
|
+
const sd = volMapr.getSampleDistance();
|
|
438
760
|
if (sd < sampleDist) {
|
|
439
761
|
sampleDist = sd;
|
|
440
762
|
}
|
|
441
763
|
}
|
|
442
|
-
|
|
443
764
|
if (model.sampleDist !== sampleDist) {
|
|
444
765
|
model.sampleDist = sampleDist;
|
|
445
766
|
model.UBO.setValue('SampleDistance', sampleDist);
|
|
446
767
|
model.UBO.sendIfNeeded(model.device);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
for (var vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
451
|
-
var webgpuvol = model.volumes[vidx];
|
|
452
|
-
var actor = webgpuvol.getRenderable();
|
|
453
|
-
|
|
454
|
-
var _volMapr4 = actor.getMapper();
|
|
455
|
-
|
|
456
|
-
var image = _volMapr4.getInputData();
|
|
457
|
-
|
|
458
|
-
var newTex = model.device.getTextureManager().getTextureForImageData(image);
|
|
768
|
+
}
|
|
459
769
|
|
|
770
|
+
// add in 3d volume textures
|
|
771
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
772
|
+
const webgpuvol = model.volumes[vidx];
|
|
773
|
+
const actor = webgpuvol.getRenderable();
|
|
774
|
+
const volMapr = actor.getMapper();
|
|
775
|
+
const image = volMapr.getInputData();
|
|
776
|
+
const newTex = model.device.getTextureManager().getTextureForImageData(image);
|
|
460
777
|
if (!model.textureViews[vidx + 4] || model.textureViews[vidx + 4].getTexture() !== newTex) {
|
|
461
|
-
|
|
778
|
+
const tview = newTex.createView(`volTexture${vidx}`);
|
|
462
779
|
model.textureViews[vidx + 4] = tview;
|
|
463
780
|
}
|
|
464
|
-
}
|
|
465
|
-
|
|
781
|
+
}
|
|
466
782
|
|
|
783
|
+
// clear any old leftovers
|
|
467
784
|
if (model.volumes.length < model.lastVolumeLength) {
|
|
468
785
|
// we may have gaps in the array right now so no splice
|
|
469
|
-
for (
|
|
786
|
+
for (let i = model.volumes.length; i < model.lastVolumeLength; i++) {
|
|
470
787
|
model.textureViews.pop();
|
|
471
788
|
}
|
|
472
789
|
}
|
|
473
|
-
|
|
474
790
|
model.lastVolumeLength = model.volumes.length;
|
|
475
791
|
publicAPI.updateLUTImage(model.device);
|
|
476
792
|
publicAPI.updateSSBO(model.device);
|
|
477
|
-
|
|
478
793
|
if (!model.clampSampler) {
|
|
479
794
|
model.clampSampler = vtkWebGPUSampler.newInstance({
|
|
480
795
|
label: 'clampSampler'
|
|
@@ -485,56 +800,55 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
485
800
|
});
|
|
486
801
|
}
|
|
487
802
|
};
|
|
488
|
-
|
|
489
|
-
publicAPI.computePipelineHash = function () {
|
|
803
|
+
publicAPI.computePipelineHash = () => {
|
|
490
804
|
model.pipelineHash = 'volfsq';
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
model.pipelineHash += "".concat(blendMode);
|
|
805
|
+
for (let vidx = 0; vidx < model.volumes.length; vidx++) {
|
|
806
|
+
const blendMode = model.volumes[vidx].getRenderable().getMapper().getBlendMode();
|
|
807
|
+
model.pipelineHash += `${blendMode}`;
|
|
495
808
|
}
|
|
496
|
-
};
|
|
497
|
-
|
|
809
|
+
};
|
|
498
810
|
|
|
499
|
-
|
|
811
|
+
// marks modified when needed
|
|
812
|
+
publicAPI.setVolumes = val => {
|
|
500
813
|
if (!model.volumes || model.volumes.length !== val.length) {
|
|
501
|
-
model.volumes =
|
|
814
|
+
model.volumes = [...val];
|
|
502
815
|
publicAPI.modified();
|
|
503
816
|
return;
|
|
504
817
|
}
|
|
505
|
-
|
|
506
|
-
for (var i = 0; i < val.length; i++) {
|
|
818
|
+
for (let i = 0; i < val.length; i++) {
|
|
507
819
|
if (val[i] !== model.volumes[i]) {
|
|
508
|
-
model.volumes =
|
|
820
|
+
model.volumes = [...val];
|
|
509
821
|
publicAPI.modified();
|
|
510
822
|
return;
|
|
511
823
|
}
|
|
512
824
|
}
|
|
513
825
|
};
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
publicAPI.getBindables = function () {
|
|
518
|
-
var bindables = superclassGetBindables();
|
|
826
|
+
const superclassGetBindables = publicAPI.getBindables;
|
|
827
|
+
publicAPI.getBindables = () => {
|
|
828
|
+
const bindables = superclassGetBindables();
|
|
519
829
|
bindables.push(model.componentSSBO);
|
|
520
830
|
bindables.push(model.clampSampler);
|
|
521
831
|
return bindables;
|
|
522
832
|
};
|
|
523
|
-
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// ----------------------------------------------------------------------------
|
|
524
836
|
// Object factory
|
|
525
837
|
// ----------------------------------------------------------------------------
|
|
526
838
|
|
|
527
|
-
|
|
528
|
-
var DEFAULT_VALUES = {
|
|
839
|
+
const DEFAULT_VALUES = {
|
|
529
840
|
volumes: null,
|
|
530
841
|
rowLength: 1024,
|
|
531
842
|
lastVolumeLength: 0
|
|
532
|
-
};
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
// ----------------------------------------------------------------------------
|
|
533
846
|
|
|
534
847
|
function extend(publicAPI, model) {
|
|
535
|
-
|
|
536
|
-
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
848
|
+
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
849
|
+
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
537
850
|
|
|
851
|
+
// Inheritance
|
|
538
852
|
vtkWebGPUFullScreenQuad.extend(publicAPI, model, initialValues);
|
|
539
853
|
model.fragmentShaderTemplate = volFragTemplate;
|
|
540
854
|
model.UBO = vtkWebGPUUniformBuffer.newInstance({
|
|
@@ -550,16 +864,21 @@ function extend(publicAPI, model) {
|
|
|
550
864
|
model.lutBuildTime = {};
|
|
551
865
|
macro.obj(model.lutBuildTime, {
|
|
552
866
|
mtime: 0
|
|
553
|
-
});
|
|
867
|
+
});
|
|
554
868
|
|
|
869
|
+
// Object methods
|
|
555
870
|
vtkWebGPUVolumePassFSQ(publicAPI, model);
|
|
556
|
-
}
|
|
871
|
+
}
|
|
557
872
|
|
|
558
|
-
|
|
873
|
+
// ----------------------------------------------------------------------------
|
|
874
|
+
|
|
875
|
+
const newInstance = macro.newInstance(extend, 'vtkWebGPUVolumePassFSQ');
|
|
876
|
+
|
|
877
|
+
// ----------------------------------------------------------------------------
|
|
559
878
|
|
|
560
879
|
var vtkWebGPUVolumePassFSQ$1 = {
|
|
561
|
-
newInstance
|
|
562
|
-
extend
|
|
880
|
+
newInstance,
|
|
881
|
+
extend
|
|
563
882
|
};
|
|
564
883
|
|
|
565
884
|
export { vtkWebGPUVolumePassFSQ$1 as default, extend, newInstance };
|