@kitware/vtk.js 23.4.2 → 23.4.4

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.
Files changed (180) hide show
  1. package/Common/Core/Math/Constants.js +12 -0
  2. package/Common/Core/Math/index.js +1 -1
  3. package/Common/Core/Math.js +1 -1
  4. package/Common/Core/ScalarsToColors/Constants.d.ts +18 -0
  5. package/Common/DataModel/AbstractPointLocator.d.ts +54 -0
  6. package/Common/DataModel/AbstractPointLocator.js +40 -0
  7. package/Common/DataModel/BoundingBox.d.ts +659 -0
  8. package/Common/DataModel/Collection.d.ts +118 -0
  9. package/Common/DataModel/Collection.js +113 -0
  10. package/Common/DataModel/DataSet/Constants.d.ts +27 -0
  11. package/Common/DataModel/EdgeLocator.d.ts +79 -0
  12. package/Common/DataModel/EdgeLocator.js +85 -0
  13. package/Common/DataModel/ITKHelper.d.ts +54 -0
  14. package/Common/DataModel/IncrementalOctreeNode.d.ts +297 -0
  15. package/Common/DataModel/IncrementalOctreeNode.js +640 -0
  16. package/Common/DataModel/IncrementalOctreePointLocator.d.ts +61 -0
  17. package/Common/DataModel/IncrementalOctreePointLocator.js +398 -0
  18. package/Common/DataModel/Locator.d.ts +43 -0
  19. package/Common/DataModel/Locator.js +37 -0
  20. package/Common/DataModel/Plane.js +1 -1
  21. package/Common/DataModel/PolyData/Constants.d.ts +6 -0
  22. package/Common/DataModel/PolyLine.d.ts +63 -0
  23. package/Common/DataModel/PolyLine.js +77 -0
  24. package/Common/DataModel/Polygon/Constants.js +12 -0
  25. package/Common/DataModel/Polygon.js +1 -1
  26. package/Common/DataModel/Quad/Constants.js +9 -0
  27. package/Common/DataModel/Quad.d.ts +91 -0
  28. package/Common/DataModel/Quad.js +235 -0
  29. package/Common/DataModel/SelectionNode/Constants.d.ts +27 -0
  30. package/Common/DataModel/Spline1D/Constants.js +17 -0
  31. package/Common/DataModel/Spline3D/Constants.d.ts +9 -0
  32. package/Common/Transform/Transform.js +51 -0
  33. package/Filters/Core/PolyDataNormals.js +124 -0
  34. package/Filters/General/ClipClosedSurface/Constants.js +10 -0
  35. package/Filters/General/ClipClosedSurface.d.ts +95 -0
  36. package/Filters/General/ClipClosedSurface.js +972 -0
  37. package/Filters/General/ContourTriangulator/Constants.js +6 -0
  38. package/Filters/General/ContourTriangulator/helper.js +1951 -0
  39. package/Filters/General/ContourTriangulator.d.ts +136 -0
  40. package/Filters/General/ContourTriangulator.js +202 -0
  41. package/Filters/General/ImageMarchingCubes.js +1 -1
  42. package/Filters/General/MoleculeToRepresentation.js +1 -1
  43. package/Filters/General/OBBTree/OBBNode.js +82 -0
  44. package/Filters/General/OBBTree/helper.js +92 -0
  45. package/Filters/General/OBBTree.js +1243 -0
  46. package/Filters/General/TubeFilter.js +1 -1
  47. package/Filters/Sources/LineSource.js +1 -1
  48. package/Filters/Sources/PlaneSource.js +1 -1
  49. package/Filters/Texture/TextureMapToPlane.js +1 -1
  50. package/Interaction/Manipulators/CompositeCameraManipulator.d.ts +68 -0
  51. package/Interaction/Manipulators/CompositeGestureManipulator.d.ts +168 -0
  52. package/Interaction/Manipulators/CompositeKeyboardManipulator.d.ts +48 -0
  53. package/Interaction/Manipulators/CompositeMouseManipulator.d.ts +149 -0
  54. package/Interaction/Manipulators/CompositeVRManipulator.d.ts +44 -0
  55. package/Interaction/Manipulators/GestureCameraManipulator.d.ts +34 -0
  56. package/Interaction/Manipulators/KeyboardCameraManipulator.js +1 -1
  57. package/Interaction/Manipulators/MouseBoxSelectorManipulator.d.ts +88 -0
  58. package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +1 -1
  59. package/Interaction/Manipulators/MouseCameraTrackballMultiRotateManipulator.d.ts +32 -0
  60. package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.d.ts +33 -0
  61. package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +1 -1
  62. package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.d.ts +33 -0
  63. package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.d.ts +67 -0
  64. package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
  65. package/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.d.ts +45 -0
  66. package/Interaction/Manipulators/MouseCameraTrackballZoomToMouseManipulator.d.ts +26 -0
  67. package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
  68. package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
  69. package/Interaction/Manipulators/MouseRangeManipulator.d.ts +53 -0
  70. package/Interaction/Style/InteractorStyleImage.d.ts +107 -0
  71. package/Interaction/Style/InteractorStyleMPRSlice.js +1 -1
  72. package/Interaction/Style/InteractorStyleManipulator.d.ts +348 -0
  73. package/Interaction/Style/InteractorStyleTrackballCamera.d.ts +170 -0
  74. package/Interaction/Widgets/ImageCroppingRegionsWidget.js +1 -1
  75. package/Interaction/Widgets/LabelRepresentation.js +1 -1
  76. package/Interaction/Widgets/OrientationMarkerWidget/Constants.d.ts +11 -0
  77. package/Interaction/Widgets/ResliceCursor/ResliceCursor.js +1 -1
  78. package/Interaction/Widgets/ResliceCursor/ResliceCursorLineRepresentation.js +1 -1
  79. package/Interaction/Widgets/ResliceCursor/ResliceCursorRepresentation.js +1 -1
  80. package/Proxy/Core/AbstractRepresentationProxy.d.ts +24 -0
  81. package/Proxy/Core/LookupTableProxy.d.ts +45 -0
  82. package/Proxy/Core/PiecewiseFunctionProxy.d.ts +62 -0
  83. package/Proxy/Core/ProxyManager.d.ts +115 -0
  84. package/Proxy/Core/SourceProxy.d.ts +22 -0
  85. package/Proxy/Core/View2DProxy.d.ts +7 -0
  86. package/Proxy/Core/View2DProxy.js +1 -1
  87. package/Proxy/Core/ViewProxy.d.ts +86 -0
  88. package/Proxy/Representations/SliceRepresentationProxy.d.ts +27 -0
  89. package/Proxy/Representations/VolumeRepresentationProxy.d.ts +44 -0
  90. package/README.md +2 -2
  91. package/Rendering/Core/AbstractImageMapper/helper.js +127 -0
  92. package/Rendering/Core/AbstractImageMapper.d.ts +82 -0
  93. package/Rendering/Core/AbstractImageMapper.js +44 -0
  94. package/Rendering/Core/Camera.js +1 -1
  95. package/Rendering/Core/CellPicker.js +1 -1
  96. package/Rendering/Core/ColorTransferFunction/ColorMaps.d.ts +24 -0
  97. package/Rendering/Core/ColorTransferFunction/Constants.d.ts +17 -0
  98. package/Rendering/Core/ColorTransferFunction.js +1 -1
  99. package/Rendering/Core/Coordinate/Constants.d.ts +14 -0
  100. package/Rendering/Core/Coordinate.js +1 -1
  101. package/Rendering/Core/Glyph3DMapper/Constants.d.ts +17 -0
  102. package/Rendering/Core/Glyph3DMapper.js +1 -1
  103. package/Rendering/Core/HardwareSelector.d.ts +84 -0
  104. package/Rendering/Core/ImageArrayMapper.d.ts +253 -0
  105. package/Rendering/Core/ImageArrayMapper.js +242 -0
  106. package/Rendering/Core/ImageMapper/Constants.d.ts +14 -0
  107. package/Rendering/Core/ImageMapper.js +1 -1
  108. package/Rendering/Core/ImageProperty/Constants.d.ts +9 -0
  109. package/Rendering/Core/ImageResliceMapper/Constants.d.ts +11 -0
  110. package/Rendering/Core/ImageResliceMapper/Constants.js +11 -0
  111. package/Rendering/Core/ImageResliceMapper.d.ts +245 -0
  112. package/Rendering/Core/ImageResliceMapper.js +70 -0
  113. package/Rendering/Core/InteractorObserver.d.ts +132 -0
  114. package/Rendering/Core/InteractorStyle/Constants.d.ts +16 -0
  115. package/Rendering/Core/InteractorStyle.d.ts +229 -0
  116. package/Rendering/Core/Light.js +1 -1
  117. package/Rendering/Core/Mapper/Constants.d.ts +26 -0
  118. package/Rendering/Core/Mapper.js +1 -1
  119. package/Rendering/Core/Picker.js +1 -1
  120. package/Rendering/Core/Prop/Constants.d.ts +9 -0
  121. package/Rendering/Core/Prop/Constants.js +9 -0
  122. package/Rendering/Core/Property/Constants.d.ts +24 -0
  123. package/Rendering/Core/Property2D/Constants.d.ts +9 -0
  124. package/Rendering/Core/RenderWindow.js +1 -1
  125. package/Rendering/Core/RenderWindowInteractor/Constants.d.ts +31 -0
  126. package/Rendering/Core/Renderer.js +1 -1
  127. package/Rendering/Core/VolumeMapper/Constants.d.ts +20 -0
  128. package/Rendering/Core/VolumeMapper.js +1 -1
  129. package/Rendering/Core/VolumeProperty/Constants.d.ts +16 -0
  130. package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +129 -0
  131. package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager.js +131 -0
  132. package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.d.ts +80 -0
  133. package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.js +763 -0
  134. package/Rendering/OpenGL/HardwareSelector/Constants.d.ts +8 -0
  135. package/Rendering/OpenGL/HardwareSelector.d.ts +339 -0
  136. package/Rendering/OpenGL/ImageResliceMapper.js +996 -0
  137. package/Rendering/OpenGL/PolyDataMapper.js +1 -1
  138. package/Rendering/OpenGL/PolyDataMapper2D.js +1 -1
  139. package/Rendering/OpenGL/RenderWindow/Constants.d.ts +10 -0
  140. package/Rendering/OpenGL/RenderWindow/Constants.js +13 -0
  141. package/Rendering/OpenGL/RenderWindow/ContextProxy.js +70 -0
  142. package/Rendering/OpenGL/RenderWindow.d.ts +9 -2
  143. package/Rendering/OpenGL/RenderWindow.js +2 -1
  144. package/Rendering/OpenGL/glsl/vtkImageResliceMapperFS.glsl.js +3 -0
  145. package/Rendering/OpenGL/glsl/vtkImageResliceMapperVS.glsl.js +3 -0
  146. package/Rendering/WebGPU/Actor2D.js +151 -0
  147. package/Rendering/WebGPU/BufferManager.js +1 -1
  148. package/Rendering/WebGPU/CellArrayMapper.js +853 -0
  149. package/Rendering/WebGPU/IndexBuffer.js +397 -0
  150. package/Rendering/WebGPU/PolyDataMapper2D.js +99 -0
  151. package/Rendering/WebGPU/RenderWindow.js +3 -1
  152. package/Rendering/WebGPU/SimpleMapper.js +290 -0
  153. package/Widgets/Core/AbstractWidget.d.ts +187 -0
  154. package/Widgets/Core/AbstractWidgetFactory.d.ts +131 -0
  155. package/Widgets/Core/StateBuilder/color3Mixin.js +24 -0
  156. package/Widgets/Core/StateBuilder/orientationMixin.js +1 -1
  157. package/Widgets/Core/StateBuilder.d.ts +29 -0
  158. package/Widgets/Core/WidgetManager/Constants.d.ts +27 -0
  159. package/Widgets/Core/WidgetManager.d.ts +231 -0
  160. package/Widgets/Core/WidgetState.d.ts +81 -0
  161. package/Widgets/Manipulators/AbstractManipulator.d.ts +221 -0
  162. package/Widgets/Manipulators/AbstractManipulator.js +57 -0
  163. package/Widgets/Manipulators/LineManipulator.js +1 -1
  164. package/Widgets/Manipulators/TrackballManipulator.js +1 -1
  165. package/Widgets/Representations/GlyphRepresentation.js +325 -0
  166. package/Widgets/Representations/LineHandleRepresentation.js +116 -0
  167. package/Widgets/Representations/ResliceCursorContextRepresentation.js +1 -1
  168. package/Widgets/Representations/WidgetRepresentation.js +1 -1
  169. package/Widgets/Widgets3D/AngleWidget.js +1 -1
  170. package/Widgets/Widgets3D/InteractiveOrientationWidget.d.ts +40 -0
  171. package/Widgets/Widgets3D/LabelWidget/behavior.js +157 -0
  172. package/Widgets/Widgets3D/LabelWidget/state.js +22 -0
  173. package/Widgets/Widgets3D/LabelWidget.js +78 -0
  174. package/Widgets/Widgets3D/LineWidget/behavior.js +1 -1
  175. package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
  176. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
  177. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
  178. package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
  179. package/index.d.ts +133 -74
  180. package/package.json +1 -1
@@ -0,0 +1,853 @@
1
+ import { mat3, mat4 } from 'gl-matrix';
2
+ import { newInstance as newInstance$1, setGet } from '../../macros.js';
3
+ import vtkMapper from '../Core/Mapper.js';
4
+ import vtkProp from '../Core/Prop.js';
5
+ import vtkProperty from '../Core/Property.js';
6
+ import vtkProperty2D from '../Core/Property2D.js';
7
+ import vtkTexture from '../Core/Texture.js';
8
+ import vtkWebGPUBufferManager from './BufferManager.js';
9
+ import vtkWebGPUShaderCache from './ShaderCache.js';
10
+ import vtkWebGPUUniformBuffer from './UniformBuffer.js';
11
+ import vtkWebGPUSimpleMapper from './SimpleMapper.js';
12
+ import vtkWebGPUTypes from './Types.js';
13
+
14
+ var BufferUsage = vtkWebGPUBufferManager.BufferUsage,
15
+ PrimitiveTypes = vtkWebGPUBufferManager.PrimitiveTypes;
16
+ var Representation = vtkProperty.Representation;
17
+ var ScalarMode = vtkMapper.ScalarMode;
18
+ var CoordinateSystem = vtkProp.CoordinateSystem;
19
+ var DisplayLocation = vtkProperty2D.DisplayLocation;
20
+ var vtkWebGPUPolyDataVS = "\n//VTK::Renderer::Dec\n\n//VTK::Color::Dec\n\n//VTK::Normal::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::Select::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::IOStructs::Dec\n\n@vertex\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output : vertexOutput;\n\n var vertex: vec4<f32> = vertexBC;\n\n //VTK::Color::Impl\n\n //VTK::Normal::Impl\n\n //VTK::TCoord::Impl\n\n //VTK::Select::Impl\n\n //VTK::Position::Impl\n\n return output;\n}\n";
21
+ var vtkWebGPUPolyDataFS = "\nstruct PBRData {\n diffuse: vec3<f32>,\n specular: vec3<f32>,\n}\n\n// Dot product with the max already in it\nfn mdot(a: vec3<f32>, b: vec3<f32>) -> f32 {\n return max(0.0, dot(a, b));\n}\n// Dot product with a max in it that does not allow for negative values\n// Physically based rendering is accurate as long as normals are accurate,\n// however this is pretty often not the case. In order to prevent negative\n// values from ruining light calculations and creating zones of zero light,\n// this remapping is used, which smoothly clamps the dot product between\n// zero and one while still maintaining a good amount of accuracy.\nfn cdot(a: vec3<f32>, b: vec3<f32>) -> f32 {\n var d: f32 = max(0.0, dot(a, b));\n d = pow((d + 1) / 2.0, 2.6);\n return d;\n}\n\n// Lambertian diffuse model\nfn lambertDiffuse(base: vec3<f32>, N: vec3<f32>, L: vec3<f32>) -> vec3<f32> {\n var pi: f32 = 3.14159265359; \n var NdotL: f32 = mdot(N, L);\n NdotL = pow(NdotL, 1.5);\n return (base/pi)*NdotL;\n}\n\n// Yasuhiro Fujii improvement on the Oren-Nayar model\n// https://mimosa-pudica.net/improved-oren-nayar.html\n// p is surface color, o is roughness\nfn fujiiOrenNayar(p: vec3<f32>, o: f32, N: vec3<f32>, L: vec3<f32>, V: vec3<f32>) -> vec3<f32> {\n var invpi: f32 = 0.31830988618; // 1/pi\n\n var o2 = o*o;\n var NdotL: f32 = mdot(N, L);\n NdotL = pow(NdotL, 1.5); // Less physically accurate, but hides the \"seams\" between lights better\n\n var NdotV: f32 = mdot(N, V);\n var LdotV: f32 = mdot(L, V);\n\n var s: f32 = LdotV - NdotL*NdotV;\n var t: f32 = mix(1, max(NdotL, NdotV), step(0, s)); // Mix with step is the equivalent of an if statement\n var A: vec3<f32> = 0.5*(o2 / (o2 + 0.33)) + 0.17*p*(o2 / (o2 + 0.13));\n A = invpi*(1 - A);\n var B: f32 = 0.45*(o2 / (o2 + 0.09));\n B = invpi*B;\n\n return p*NdotL*(A + B*(s/t));\n}\n\n// Fresnel portion of BRDF (IOR only, simplified)\nfn schlickFresnelIOR(V: vec3<f32>, N: vec3<f32>, ior: f32, k: f32) -> f32 {\n var NdotV: f32 = mdot(V, N);\n var F0: f32 = (pow((ior - 1.0), 2) + k*k) / (pow((ior + 1.0), 2) + k*k); // This takes into account the roughness, which the other one does not\n return F0 + (1 - F0) * pow((1-NdotV), 5); \n}\n\n// Fresnel portion of BRDF (Color ior, better)\nfn schlickFresnelRGB(V: vec3<f32>, N: vec3<f32>, F0: vec3<f32>) -> vec3<f32> {\n var NdotV: f32 = mdot(V, N);\n return F0 + (1 - F0) * pow((1-NdotV), 5); \n}\n\n// Normal portion of BRDF\n// https://learnopengl.com/PBR/Theory\n// Trowbridge-Reitz GGX functions: normal, halfway, roughness^2\nfn trGGX(N: vec3<f32>, H: vec3<f32>, a: f32) -> f32 {\n var pi: f32 = 3.14159265359; \n\n var a2: f32 = a*a;\n var NdotH = mdot(N, H);\n var NdotH2 = NdotH*NdotH;\n \n var denom: f32 = NdotH2 * (a2 - 1.0) + 1.0;\n\n return a2 / max((pi*denom*denom), 0.000001);\n}\n\n// A VERY bad approximation of anisotropy. Real anisotropic calculations require tangent and bitangent\nfn anisotrophicTrGGX(N: vec3<f32>, H: vec3<f32>, O: vec3<f32>, s: f32, a: f32) -> f32 {\n var Op: vec3<f32> = (rendererUBO.WCVCNormals * vec4<f32>(normalize(O) * s, 0.)).xyz;\n\n var ggx1: f32 = trGGX(N + Op*s, H, a);\n var ggx2: f32 = trGGX(N - Op*s, H, a);\n return (0.5 * ggx1 + 0.5 * ggx2);\n}\n\n// Geometry portion of BRDF\nfn schlickGGX(N: vec3<f32>, X: vec3<f32>, k: f32) -> f32 {\n var NdotX = cdot(N, X);\n return NdotX / max(0.000001, (NdotX*(1-k) + k));\n}\n\nfn smithSurfaceRoughness(N: vec3<f32>, V: vec3<f32>, L: vec3<f32>, k: f32) -> f32 {\n var ggx1: f32 = min(1, schlickGGX(N, V, k));\n var ggx2: f32 = min(1, schlickGGX(N, L, k));\n return ggx1*ggx2;\n}\n\n// BRDF Combination\nfn cookTorrance(D: f32, F: f32, G: f32, N: vec3<f32>, V: vec3<f32>, L: vec3<f32>) -> f32 {\n var num: f32 = D*F*G;\n var denom: f32 = 4*cdot(V, N)*cdot(L, N);\n\n return num / max(denom, 0.000001);\n}\n\n// Different lighting calculations for different light sources\nfn calcDirectionalLight(N: vec3<f32>, V: vec3<f32>, ior: f32, roughness: f32, metallic: f32, direction: vec3<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData { \n var L: vec3<f32> = normalize(direction); // Light Vector\n var H: vec3<f32> = normalize(L + V); // Halfway Vector\n\n var alpha = roughness*roughness;\n var k: f32 = alpha*alpha / 2;\n\n var D: f32 = trGGX(N, H, alpha); // Distribution\n // var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel\n var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry\n\n var brdf: f32 = cookTorrance(D, 1, G, N, V, L); // Fresnel term is replaced with 1 because it is added later\n var incoming: vec3<f32> = color;\n var angle: f32 = mdot(L, N);\n angle = pow(angle, 1.5);\n\n var specular: vec3<f32> = brdf*incoming*angle;\n // Oren-Nayar gives a clay-like effect when fully rough which some people may not want, so it might be better to give a separate\n // control property for the diffuse vs specular roughness\n var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V); \n // Stores the specular and diffuse separately to allow for finer post processing\n var out = PBRData(diffuse, specular);\n \n return out; // Returns angle along with color of light so the final color can be multiplied by angle as well (creates black areas)\n}\n\n// TODO: find some way to reduce the number of arguments going in here\nfn calcPointLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, ior: f32, roughness: f32, metallic: f32, position: vec3<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData {\n var L: vec3<f32> = normalize(position - fragPos); // Light Vector\n var H: vec3<f32> = normalize(L + V); // Halfway Vector\n var dist = distance(position, fragPos);\n\n var alpha = roughness*roughness;\n var k: f32 = alpha*alpha / 2; // could also be pow(alpha + 1.0, 2) / 8\n\n var D: f32 = trGGX(N, H, alpha); // Distribution\n // var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel\n var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry\n\n var brdf: f32 = cookTorrance(D, 1, G, N, V, L); \n var incoming: vec3<f32> = color * (1. / (dist*dist));\n var angle: f32 = mdot(L, N);\n angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly \"seams\" bewteen light sources\n\n var specular: vec3<f32> = brdf*incoming*angle;\n var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V);\n\n // Stores the specular and diffuse separately to allow for finer post processing\n // Could also be done (propably more properly) with a struct\n var out = PBRData(diffuse, specular);\n \n return out; // Returns angle along with color of light so the final color can be multiplied by angle as well (creates black areas)\n}\n\n// For a reason unknown to me, spheres dont seem to behave propperly with head-on spot lights\nfn calcSpotLight(N: vec3<f32>, V: vec3<f32>, fragPos: vec3<f32>, ior: f32, roughness: f32, metallic: f32, position: vec3<f32>, direction: vec3<f32>, cones: vec2<f32>, color: vec3<f32>, base: vec3<f32>) -> PBRData {\n var L: vec3<f32> = normalize(position - fragPos);\n var H: vec3<f32> = normalize(L + V); // Halfway Vector\n var dist = distance(position, fragPos);\n\n var alpha = roughness*roughness;\n var k: f32 = alpha*alpha / 2; // could also be pow(alpha + 1.0, 2) / 8\n\n var D: f32 = trGGX(N, H, alpha); // Distribution\n // var F: f32 = schlickFresnelIOR(V, N, ior, k); // Fresnel\n var G: f32 = smithSurfaceRoughness(N, V, L, k); // Geometry\n\n var brdf: f32 = cookTorrance(D, 1, G, N, V, L); \n \n // Cones.x is the inner phi and cones.y is the outer phi\n var theta: f32 = mdot(normalize(direction), L);\n var epsilon: f32 = cones.x - cones.y;\n var intensity: f32 = (theta - cones.y) / epsilon;\n intensity = clamp(intensity, 0.0, 1.0);\n intensity /= dist*dist;\n\n var incoming: vec3<f32> = color * intensity;\n\n var angle: f32 = mdot(L, N);\n angle = pow(angle, 1.5); // Smoothing factor makes it less accurate, but reduces ugly \"seams\" bewteen light sources\n\n var specular: vec3<f32> = brdf*incoming*angle;\n var diffuse: vec3<f32> = incoming*fujiiOrenNayar(base, roughness, N, L, V);\n\n // Stores the specular and diffuse separately to allow for finer post processing\n // Could also be done (propably more properly) with a struct\n var out = PBRData(diffuse, specular);\n \n return out; // Returns angle along with color of light so the final color can be multiplied by angle as well (creates black areas)\n}\n\n// Environment mapping stuff\n// Takes in a vector and converts it to an equivalent coordinate in a rectilinear texture. Should be replaced with cubemaps at some point\nfn vecToRectCoord(dir: vec3<f32>) -> vec2<f32> {\n var tau: f32 = 6.28318530718;\n var pi: f32 = 3.14159265359;\n var out: vec2<f32> = vec2<f32>(0.0);\n\n out.x = atan2(dir.z, dir.x) / tau;\n out.x += 0.5;\n\n var phix: f32 = length(vec2(dir.x, dir.z));\n out.y = atan2(dir.y, phix) / pi + 0.5;\n\n return out;\n}\n\n//VTK::Renderer::Dec\n\n//VTK::Color::Dec\n\n//VTK::TCoord::Dec\n\n// optional surface normal declaration\n//VTK::Normal::Dec\n\n//VTK::Select::Dec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::IOStructs::Dec\n\n@fragment\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output : fragmentOutput;\n\n // Temporary ambient, diffuse, and opacity\n var ambientColor: vec4<f32> = mapperUBO.AmbientColor;\n var diffuseColor: vec4<f32> = mapperUBO.DiffuseColor;\n var opacity: f32 = mapperUBO.Opacity;\n\n // This should be declared somewhere else\n var _diffuseMap: vec4<f32> = vec4<f32>(1);\n var _roughnessMap: vec4<f32> = vec4<f32>(1);\n var _metallicMap: vec4<f32> = vec4<f32>(1);\n var _normalMap: vec4<f32> = vec4<f32>(0, 0, 1, 0); // normal map was setting off the normal vector detection in fragment\n var _ambientOcclusionMap: vec4<f32> = vec4<f32>(1);\n var _emissionMap: vec4<f32> = vec4<f32>(0);\n\n //VTK::Color::Impl\n\n //VTK::TCoord::Impl\n\n //VTK::Normal::Impl\n\n var computedColor: vec4<f32> = vec4<f32>(diffuseColor.rgb, 1.0);\n\n //VTK::Light::Impl\n\n //VTK::Select::Impl\n\n if (computedColor.a == 0.0) { discard; };\n\n //VTK::Position::Impl\n\n //VTK::RenderEncoder::Impl\n\n return output;\n}\n";
22
+
23
+ function isEdges(hash) {
24
+ // edge pipelines have "edge" in them
25
+ return hash.indexOf('edge') >= 0;
26
+ } // ----------------------------------------------------------------------------
27
+ // vtkWebGPUCellArrayMapper methods
28
+ // ----------------------------------------------------------------------------
29
+
30
+
31
+ function vtkWebGPUCellArrayMapper(publicAPI, model) {
32
+ // Set our className
33
+ model.classHierarchy.push('vtkWebGPUCellArrayMapper');
34
+
35
+ publicAPI.buildPass = function (prepass) {
36
+ if (prepass) {
37
+ if (model.is2D) {
38
+ model.WebGPUActor = publicAPI.getFirstAncestorOfType('vtkWebGPUActor2D');
39
+ model.forceZValue = true;
40
+ } else {
41
+ model.WebGPUActor = publicAPI.getFirstAncestorOfType('vtkWebGPUActor');
42
+ model.forceZValue = false;
43
+ }
44
+
45
+ model.coordinateSystem = model.WebGPUActor.getRenderable().getCoordinateSystem();
46
+ model.useRendererMatrix = model.coordinateSystem !== CoordinateSystem.DISPLAY;
47
+ model.WebGPURenderer = model.WebGPUActor.getFirstAncestorOfType('vtkWebGPURenderer');
48
+ model.WebGPURenderWindow = model.WebGPURenderer.getParent();
49
+ model.device = model.WebGPURenderWindow.getDevice();
50
+ }
51
+ }; // Renders myself
52
+
53
+
54
+ publicAPI.translucentPass = function (prepass) {
55
+ if (prepass) {
56
+ publicAPI.prepareToDraw(model.WebGPURenderer.getRenderEncoder());
57
+ model.renderEncoder.registerDrawCallback(model.pipeline, publicAPI.draw);
58
+ }
59
+ };
60
+
61
+ publicAPI.opaquePass = function (prepass) {
62
+ if (prepass) {
63
+ publicAPI.prepareToDraw(model.WebGPURenderer.getRenderEncoder());
64
+ model.renderEncoder.registerDrawCallback(model.pipeline, publicAPI.draw);
65
+ }
66
+ };
67
+
68
+ publicAPI.updateUBO = function () {
69
+ // make sure the data is up to date
70
+ var actor = model.WebGPUActor.getRenderable();
71
+ var ppty = actor.getProperty();
72
+ var utime = model.UBO.getSendTime();
73
+
74
+ if (publicAPI.getMTime() > utime || ppty.getMTime() > utime || model.renderable.getMTime() > utime) {
75
+ var _ppty$getEdgeColorByR;
76
+
77
+ // Matricies
78
+ var keyMats = model.WebGPUActor.getKeyMatrices(model.WebGPURenderer);
79
+ model.UBO.setArray('BCWCMatrix', keyMats.bcwc);
80
+ model.UBO.setArray('BCSCMatrix', keyMats.bcsc);
81
+ model.UBO.setArray('MCWCNormals', keyMats.normalMatrix);
82
+
83
+ if (model.is2D) {
84
+ model.UBO.setValue('ZValue', model.WebGPUActor.getRenderable().getProperty().getDisplayLocation() === DisplayLocation.FOREGROUND ? 1.0 : 0.0);
85
+
86
+ var _aColor = ppty.getColorByReference();
87
+
88
+ model.UBO.setValue('AmbientIntensity', 1.0);
89
+ model.UBO.setArray('DiffuseColor', [_aColor[0], _aColor[1], _aColor[2], 1.0]);
90
+ model.UBO.setValue('DiffuseIntensity', 0.0);
91
+ model.UBO.setValue('SpecularIntensity', 0.0);
92
+ } else {
93
+ // Base Colors
94
+ var _aColor2 = ppty.getAmbientColorByReference();
95
+
96
+ model.UBO.setValue('AmbientIntensity', ppty.getAmbient());
97
+ model.UBO.setArray('AmbientColor', [_aColor2[0], _aColor2[1], _aColor2[2], 1.0]);
98
+ model.UBO.setValue('DiffuseIntensity', ppty.getDiffuse());
99
+ _aColor2 = ppty.getDiffuseColorByReference();
100
+ model.UBO.setArray('DiffuseColor', [_aColor2[0], _aColor2[1], _aColor2[2], 1.0]); // Roughness
101
+
102
+ model.UBO.setValue('Roughness', ppty.getRoughness());
103
+ model.UBO.setValue('BaseIOR', ppty.getBaseIOR()); // Metallic
104
+
105
+ model.UBO.setValue('Metallic', ppty.getMetallic()); // Normal
106
+
107
+ model.UBO.setValue('NormalStrength', ppty.getNormalStrength()); // Emission
108
+
109
+ model.UBO.setValue('Emission', ppty.getEmission()); // Specular
110
+
111
+ model.UBO.setValue('SpecularIntensity', ppty.getSpecular());
112
+ _aColor2 = ppty.getSpecularColorByReference();
113
+ model.UBO.setArray('SpecularColor', [_aColor2[0], _aColor2[1], _aColor2[2], 1.0]);
114
+ } // Edge and line rendering
115
+
116
+
117
+ var aColor = (_ppty$getEdgeColorByR = ppty.getEdgeColorByReference) === null || _ppty$getEdgeColorByR === void 0 ? void 0 : _ppty$getEdgeColorByR.call(ppty);
118
+
119
+ if (aColor) {
120
+ model.UBO.setArray('EdgeColor', [aColor[0], aColor[1], aColor[2], 1.0]);
121
+ }
122
+
123
+ model.UBO.setValue('LineWidth', ppty.getLineWidth());
124
+ model.UBO.setValue('Opacity', ppty.getOpacity());
125
+ model.UBO.setValue('PropID', model.WebGPUActor.getPropID());
126
+ var device = model.WebGPURenderWindow.getDevice();
127
+ model.UBO.sendIfNeeded(device);
128
+ }
129
+ };
130
+
131
+ publicAPI.haveWideLines = function () {
132
+ var actor = model.WebGPUActor.getRenderable();
133
+ var representation = actor.getProperty().getRepresentation();
134
+
135
+ if (actor.getProperty().getLineWidth() <= 1.0) {
136
+ return false;
137
+ }
138
+
139
+ if (model.primitiveType === PrimitiveTypes.Verts) {
140
+ return false;
141
+ }
142
+
143
+ if (model.primitiveType === PrimitiveTypes.Triangles || model.primitiveType === PrimitiveTypes.TriangleStrips) {
144
+ return representation === Representation.WIREFRAME;
145
+ }
146
+
147
+ return true;
148
+ };
149
+
150
+ publicAPI.replaceShaderPosition = function (hash, pipeline, vertexInput) {
151
+ var vDesc = pipeline.getShaderDescription('vertex');
152
+ vDesc.addBuiltinOutput('vec4<f32>', '@builtin(position) Position');
153
+ if (!vDesc.hasOutput('vertexVC')) vDesc.addOutput('vec4<f32>', 'vertexVC');
154
+ var code = vDesc.getCode();
155
+
156
+ if (model.useRendererMatrix) {
157
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' var pCoord: vec4<f32> = rendererUBO.SCPCMatrix*mapperUBO.BCSCMatrix*vertexBC;', ' output.vertexVC = rendererUBO.SCVCMatrix * mapperUBO.BCSCMatrix * vec4<f32>(vertexBC.xyz, 1.0);', '//VTK::Position::Impl']).result;
158
+
159
+ if (model.forceZValue) {
160
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', ['pCoord = vec4<f32>(pCoord.xyz/pCoord.w, 1.0);', 'pCoord.z = mapperUBO.ZValue;', '//VTK::Position::Impl']).result;
161
+ }
162
+ } else {
163
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' var pCoord: vec4<f32> = mapperUBO.BCSCMatrix*vertexBC;', ' pCoord.x = 2.0* pCoord.x / rendererUBO.viewportSize.x - 1.0;', ' pCoord.y = 2.0* pCoord.y / rendererUBO.viewportSize.y - 1.0;', ' pCoord.z = 0.5 - 0.5 * pCoord.z;', '//VTK::Position::Impl']).result;
164
+
165
+ if (model.forceZValue) {
166
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' pCoord.z = mapperUBO.ZValue;', '//VTK::Position::Impl']).result;
167
+ }
168
+ }
169
+
170
+ if (publicAPI.haveWideLines()) {
171
+ vDesc.addBuiltinInput('u32', '@builtin(instance_index) instanceIndex'); // widen the edge
172
+
173
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' var tmpPos: vec4<f32> = pCoord;', ' var numSteps: f32 = ceil(mapperUBO.LineWidth - 1.0);', ' var offset: f32 = (mapperUBO.LineWidth - 1.0) * (f32(input.instanceIndex / 2u) - numSteps/2.0) / numSteps;', ' var tmpPos2: vec3<f32> = tmpPos.xyz / tmpPos.w;', ' tmpPos2.x = tmpPos2.x + 2.0 * (f32(input.instanceIndex) % 2.0) * offset / rendererUBO.viewportSize.x;', ' tmpPos2.y = tmpPos2.y + 2.0 * (f32(input.instanceIndex + 1u) % 2.0) * offset / rendererUBO.viewportSize.y;', ' tmpPos2.z = min(1.0, tmpPos2.z + 0.00001);', // could become a setting
174
+ ' pCoord = vec4<f32>(tmpPos2.xyz * tmpPos.w, tmpPos.w);', '//VTK::Position::Impl']).result;
175
+ }
176
+
177
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' output.Position = pCoord;']).result;
178
+ vDesc.setCode(code);
179
+ };
180
+
181
+ model.shaderReplacements.set('replaceShaderPosition', publicAPI.replaceShaderPosition);
182
+
183
+ publicAPI.replaceShaderNormal = function (hash, pipeline, vertexInput) {
184
+ var normalBuffer = vertexInput.getBuffer('normalMC');
185
+ var actor = model.WebGPUActor.getRenderable();
186
+
187
+ if (normalBuffer) {
188
+ var vDesc = pipeline.getShaderDescription('vertex');
189
+
190
+ if (!vDesc.hasOutput('normalVC')) {
191
+ vDesc.addOutput('vec3<f32>', 'normalVC', normalBuffer.getArrayInformation()[0].interpolation);
192
+ }
193
+
194
+ if (!vDesc.hasOutput('tangentVC')) {
195
+ vDesc.addOutput('vec3<f32>', 'tangentVC', normalBuffer.getArrayInformation()[0].interpolation);
196
+ }
197
+
198
+ if (!vDesc.hasOutput('bitangentVC')) {
199
+ vDesc.addOutput('vec3<f32>', 'bitangentVC', normalBuffer.getArrayInformation()[0].interpolation);
200
+ }
201
+
202
+ var code = vDesc.getCode();
203
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [' output.normalVC = normalize((rendererUBO.WCVCNormals * mapperUBO.MCWCNormals * normalMC).xyz);', // This is just an approximation, but it happens to work extremely well
204
+ // It only works well for normals that are head on and not super angled though
205
+ // Definitely needs to be replaced
206
+ ' var c1: vec3<f32> = cross(output.normalVC, vec3<f32>(0, 0, 1));', ' var c2: vec3<f32> = cross(output.normalVC, vec3<f32>(0, 1, 0));', ' var tangent: vec3<f32> = mix(c1, c2, distance(c1, c2));', ' output.tangentVC = normalize(tangent);', ' output.bitangentVC = normalize(cross(output.normalVC, tangent));']).result;
207
+ vDesc.setCode(code);
208
+ var fDesc = pipeline.getShaderDescription('fragment');
209
+ code = fDesc.getCode();
210
+
211
+ if (actor.getProperty().getNormalTexture()) {
212
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [' var normal: vec3<f32> = input.normalVC;', ' if (!input.frontFacing) { normal = -normal; }', ' var tangent: vec3<f32> = input.tangentVC;', ' var bitangent: vec3<f32> = input.bitangentVC;', ' var TCVCMatrix: mat3x3<f32> = mat3x3<f32>(', ' tangent.x, bitangent.x, normal.x,', ' tangent.y, bitangent.y, normal.y,', ' tangent.z, bitangent.z, normal.z,', ' );', ' var mappedNormal: vec3<f32> = TCVCMatrix * (_normalMap.xyz * 2 - 1);', ' normal = mix(normal, mappedNormal, mapperUBO.NormalStrength);', ' normal = normalize(normal);']).result;
213
+ } else {
214
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [' var normal: vec3<f32> = input.normalVC;', ' if (!input.frontFacing) { normal = -normal; }', ' normal = normalize(normal);']).result;
215
+ }
216
+
217
+ fDesc.setCode(code);
218
+ }
219
+ };
220
+
221
+ model.shaderReplacements.set('replaceShaderNormal', publicAPI.replaceShaderNormal); // we only apply lighting when there is a "var normal" declaration in the
222
+ // fragment shader code. That is the lighting trigger.
223
+
224
+ publicAPI.replaceShaderLight = function (hash, pipeline, vertexInput) {
225
+ if (hash.includes('sel')) return;
226
+ var vDesc = pipeline.getShaderDescription('vertex');
227
+ if (!vDesc.hasOutput('vertexVC')) vDesc.addOutput('vec4<f32>', 'vertexVC');
228
+ var renderer = model.WebGPURenderer.getRenderable();
229
+ var fDesc = pipeline.getShaderDescription('fragment');
230
+ var code = fDesc.getCode(); // Code that runs if the fragment shader includes normals
231
+
232
+ if (code.includes('var normal:') && model.useRendererMatrix && !isEdges(hash) && !model.is2D && !hash.includes('sel')) {
233
+ var _renderer$getEnvironm;
234
+
235
+ var lightingCode = [// Constants
236
+ ' var pi: f32 = 3.14159265359;', // Vectors needed for light calculations
237
+ ' var fragPos: vec3<f32> = vec3<f32>(input.vertexVC.xyz);', ' var V: vec3<f32> = mix(normalize(-fragPos), vec3<f32>(0, 0, 1), f32(rendererUBO.cameraParallel)); // View Vector', // Values needed for light calculations
238
+ ' var baseColor: vec3<f32> = _diffuseMap.rgb * diffuseColor.rgb;', ' var roughness: f32 = max(0.000001, mapperUBO.Roughness * _roughnessMap.r);', // Need to have a different way of sampling greyscale values aside from .r
239
+ ' var metallic: f32 = mapperUBO.Metallic * _metallicMap.r;', ' var alpha: f32 = roughness*roughness;', ' var ior: f32 = mapperUBO.BaseIOR;', ' var k: f32 = alpha*alpha / 2;', // Split diffuse and specular components
240
+ ' var diffuse: vec3<f32> = vec3<f32>(0.);', ' var specular: vec3<f32> = vec3<f32>(0.);', ' var emission: vec3<f32> = _emissionMap.rgb * mapperUBO.Emission;', // Summing diffuse and specular components of directional lights
241
+ ' {', ' var i: i32 = 0;', ' loop {', ' if !(i < rendererUBO.LightCount) { break; }', ' switch (i32(rendererLightSSBO.values[i].LightData.x)) {', ' // Point Light', ' case 0 {', ' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;', ' var pos: vec3<f32> = (rendererLightSSBO.values[i].LightPos).xyz;', ' var calculated: PBRData = calcPointLight(normal, V, fragPos, ior, roughness, metallic, pos, color, baseColor);', ' diffuse += max(vec3<f32>(0), calculated.diffuse);', ' specular += max(vec3<f32>(0), calculated.specular);', ' }', ' // Directional light', ' case 1 {', ' var dir: vec3<f32> = (rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz;', ' dir = normalize(dir);', ' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;', ' var calculated: PBRData = calcDirectionalLight(normal, V, ior, roughness, metallic, dir, color, baseColor); // diffuseColor.rgb needs to be fixed with a more dynamic diffuse color', ' diffuse += max(vec3<f32>(0), calculated.diffuse);', ' specular += max(vec3<f32>(0), calculated.specular);', ' }', ' // Spot Light', ' case 2 {', ' var color: vec3<f32> = rendererLightSSBO.values[i].LightColor.rgb * rendererLightSSBO.values[i].LightColor.w;', ' var pos: vec3<f32> = (rendererLightSSBO.values[i].LightPos).xyz;', ' var dir: vec3<f32> = (rendererUBO.WCVCNormals * vec4<f32>(normalize(rendererLightSSBO.values[i].LightDir.xyz), 0.)).xyz;', ' dir = normalize(dir);', ' var cones: vec2<f32> = vec2<f32>(rendererLightSSBO.values[i].LightData.y, rendererLightSSBO.values[i].LightData.z);', ' var calculated: PBRData = calcSpotLight(normal, V, fragPos, ior, roughness, metallic, pos, dir, cones, color, baseColor);', ' diffuse += max(vec3<f32>(0), calculated.diffuse);', ' specular += max(vec3<f32>(0), calculated.specular);', ' }', ' default { continue; }', ' }', ' continuing { i++; }', ' }', ' }', // Final variables for combining specular and diffuse
242
+ ' var fresnel: f32 = schlickFresnelIOR(V, normal, ior, k); // Fresnel', ' fresnel = min(1, fresnel);', ' // This could be controlled with its own variable (that isnt base color) for better artistic control', ' var fresnelMetallic: vec3<f32> = schlickFresnelRGB(V, normal, baseColor); // Fresnel for metal, takes color into account', ' var kS: vec3<f32> = mix(vec3<f32>(fresnel), fresnelMetallic, metallic);', ' kS = min(vec3<f32>(1), kS);', ' var kD: vec3<f32> = (1.0 - kS) * (1.0 - metallic);', ' var PBR: vec3<f32> = mapperUBO.DiffuseIntensity*kD*diffuse + kS*specular;', ' PBR += emission;', ' computedColor = vec4<f32>(PBR, mapperUBO.Opacity);'];
243
+
244
+ if ((_renderer$getEnvironm = renderer.getEnvironmentTexture()) !== null && _renderer$getEnvironm !== void 0 && _renderer$getEnvironm.getImageLoaded()) {
245
+ lightingCode.push(' // To get diffuse IBL, the texture is sampled with normals in worldspace', ' var diffuseIBLCoords: vec3<f32> = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(normal, 1.)).xyz;', ' var diffuseCoords: vec2<f32> = vecToRectCoord(diffuseIBLCoords);', ' // To get specular IBL, the texture is sampled as the worldspace reflection between the normal and view vectors', ' // Reflections are first calculated in viewspace, then converted to worldspace to sample the environment', ' var VreflN: vec3<f32> = normalize(reflect(-V, normal));', ' var reflectionIBLCoords = (transpose(rendererUBO.WCVCNormals) * vec4<f32>(VreflN, 1.)).xyz;', ' var specularCoords: vec2<f32> = vecToRectCoord(reflectionIBLCoords);', ' var diffuseIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, diffuseCoords, rendererUBO.MaxEnvironmentMipLevel);', // Level multiplier should be set by UBO
246
+ ' var level = roughness * rendererUBO.MaxEnvironmentMipLevel;', ' var specularIBL = textureSampleLevel(EnvironmentTexture, EnvironmentTextureSampler, specularCoords, level);', // Manual mip smoothing since not all formats support smooth level sampling
247
+ ' var specularIBLContribution: vec3<f32> = specularIBL.rgb*rendererUBO.BackgroundSpecularStrength;', ' computedColor += vec4<f32>(specularIBLContribution*kS, 0);', ' var diffuseIBLContribution: vec3<f32> = diffuseIBL.rgb*rendererUBO.BackgroundDiffuseStrength;', ' diffuseIBLContribution *= baseColor * _ambientOcclusionMap.rgb;', // Multipy by baseColor may be changed
248
+ ' computedColor += vec4<f32>(diffuseIBLContribution*kD, 0);');
249
+ }
250
+
251
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Light::Impl', lightingCode).result;
252
+ fDesc.setCode(code); // If theres no normals, just set the specular color to be flat
253
+ } else {
254
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Light::Impl', [' var diffuse: vec3<f32> = diffuseColor.rgb;', ' var specular: vec3<f32> = mapperUBO.SpecularColor.rgb * mapperUBO.SpecularColor.a;', ' computedColor = vec4<f32>(diffuse * _diffuseMap.rgb, mapperUBO.Opacity);']).result;
255
+ fDesc.setCode(code);
256
+ }
257
+ };
258
+
259
+ model.shaderReplacements.set('replaceShaderLight', publicAPI.replaceShaderLight);
260
+
261
+ publicAPI.replaceShaderColor = function (hash, pipeline, vertexInput) {
262
+ // By default, set the colors to be flat
263
+ if (isEdges(hash)) {
264
+ var _fDesc = pipeline.getShaderDescription('fragment');
265
+
266
+ var _code = _fDesc.getCode();
267
+
268
+ _code = vtkWebGPUShaderCache.substitute(_code, '//VTK::Color::Impl', ['ambientColor = mapperUBO.EdgeColor;', 'diffuseColor = mapperUBO.EdgeColor;']).result;
269
+
270
+ _fDesc.setCode(_code);
271
+
272
+ return;
273
+ } // If there's no vertex color buffer return the shader as is
274
+
275
+
276
+ var colorBuffer = vertexInput.getBuffer('colorVI');
277
+ if (!colorBuffer) return; // Modifies the vertex shader to include the vertex colors and interpolation in the outputs
278
+
279
+ var vDesc = pipeline.getShaderDescription('vertex');
280
+ vDesc.addOutput('vec4<f32>', 'color', colorBuffer.getArrayInformation()[0].interpolation);
281
+ var code = vDesc.getCode();
282
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Color::Impl', [' output.color = colorVI;']).result;
283
+ vDesc.setCode(code); // Sets the fragment shader to accept the color inputs from the vertex shader
284
+
285
+ var fDesc = pipeline.getShaderDescription('fragment');
286
+ code = fDesc.getCode();
287
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Color::Impl', ['ambientColor = input.color;', 'diffuseColor = input.color;', 'opacity = mapperUBO.Opacity * input.color.a;']).result;
288
+ fDesc.setCode(code);
289
+ };
290
+
291
+ model.shaderReplacements.set('replaceShaderColor', publicAPI.replaceShaderColor);
292
+
293
+ publicAPI.replaceShaderTCoord = function (hash, pipeline, vertexInput) {
294
+ var _actor$getProperty$ge, _actor$getProperty, _actor$getProperty$ge2, _actor$getProperty$ge4, _actor$getProperty3, _actor$getProperty$ge5, _actor$getProperty$ge6, _actor$getProperty4, _actor$getProperty$ge7, _actor$getProperty$ge8, _actor$getProperty5, _actor$getProperty$ge9, _actor$getProperty$ge10, _actor$getProperty6, _actor$getProperty$ge11, _actor$getProperty$ge12, _actor$getProperty7, _actor$getProperty$ge13;
295
+
296
+ if (!vertexInput.hasAttribute('tcoord')) return;
297
+ var vDesc = pipeline.getShaderDescription('vertex');
298
+ var tcoords = vertexInput.getBuffer('tcoord');
299
+ var numComp = vtkWebGPUTypes.getNumberOfComponentsFromBufferFormat(tcoords.getArrayInformation()[0].format);
300
+ var code = vDesc.getCode();
301
+ vDesc.addOutput("vec".concat(numComp, "<f32>"), 'tcoordVS');
302
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::TCoord::Impl', [' output.tcoordVS = tcoord;']).result;
303
+ vDesc.setCode(code);
304
+ var fDesc = pipeline.getShaderDescription('fragment');
305
+ code = fDesc.getCode();
306
+ var actor = model.WebGPUActor.getRenderable();
307
+
308
+ var checkDims = function checkDims(texture) {
309
+ if (!texture) return false;
310
+ var dims = texture.getDimensionality();
311
+ return dims === numComp;
312
+ };
313
+
314
+ var usedTextures = [];
315
+
316
+ if ((_actor$getProperty$ge = (_actor$getProperty = actor.getProperty()).getDiffuseTexture) !== null && _actor$getProperty$ge !== void 0 && (_actor$getProperty$ge2 = _actor$getProperty$ge.call(_actor$getProperty)) !== null && _actor$getProperty$ge2 !== void 0 && _actor$getProperty$ge2.getImageLoaded() || actor.getTextures()[0] || model.colorTexture) {
317
+ var _actor$getProperty$ge3, _actor$getProperty2;
318
+
319
+ if ( // Chained or statements here are questionable
320
+ checkDims((_actor$getProperty$ge3 = (_actor$getProperty2 = actor.getProperty()).getDiffuseTexture) === null || _actor$getProperty$ge3 === void 0 ? void 0 : _actor$getProperty$ge3.call(_actor$getProperty2)) || checkDims(actor.getTextures()[0]) || checkDims(model.colorTexture)) {
321
+ usedTextures.push('_diffuseMap = textureSample(DiffuseTexture, DiffuseTextureSampler, input.tcoordVS);');
322
+ }
323
+ }
324
+
325
+ if ((_actor$getProperty$ge4 = (_actor$getProperty3 = actor.getProperty()).getRoughnessTexture) !== null && _actor$getProperty$ge4 !== void 0 && (_actor$getProperty$ge5 = _actor$getProperty$ge4.call(_actor$getProperty3)) !== null && _actor$getProperty$ge5 !== void 0 && _actor$getProperty$ge5.getImageLoaded()) {
326
+ if (checkDims(actor.getProperty().getRoughnessTexture())) {
327
+ usedTextures.push('_roughnessMap = textureSample(RoughnessTexture, RoughnessTextureSampler, input.tcoordVS);');
328
+ }
329
+ }
330
+
331
+ if ((_actor$getProperty$ge6 = (_actor$getProperty4 = actor.getProperty()).getMetallicTexture) !== null && _actor$getProperty$ge6 !== void 0 && (_actor$getProperty$ge7 = _actor$getProperty$ge6.call(_actor$getProperty4)) !== null && _actor$getProperty$ge7 !== void 0 && _actor$getProperty$ge7.getImageLoaded()) {
332
+ if (checkDims(actor.getProperty().getMetallicTexture())) {
333
+ usedTextures.push('_metallicMap = textureSample(MetallicTexture, MetallicTextureSampler, input.tcoordVS);');
334
+ }
335
+ }
336
+
337
+ if ((_actor$getProperty$ge8 = (_actor$getProperty5 = actor.getProperty()).getNormalTexture) !== null && _actor$getProperty$ge8 !== void 0 && (_actor$getProperty$ge9 = _actor$getProperty$ge8.call(_actor$getProperty5)) !== null && _actor$getProperty$ge9 !== void 0 && _actor$getProperty$ge9.getImageLoaded()) {
338
+ if (checkDims(actor.getProperty().getNormalTexture())) {
339
+ usedTextures.push('_normalMap = textureSample(NormalTexture, NormalTextureSampler, input.tcoordVS);');
340
+ }
341
+ }
342
+
343
+ if ((_actor$getProperty$ge10 = (_actor$getProperty6 = actor.getProperty()).getAmbientOcclusionTexture) !== null && _actor$getProperty$ge10 !== void 0 && (_actor$getProperty$ge11 = _actor$getProperty$ge10.call(_actor$getProperty6)) !== null && _actor$getProperty$ge11 !== void 0 && _actor$getProperty$ge11.getImageLoaded()) {
344
+ if (checkDims(actor.getProperty().getAmbientOcclusionTexture())) {
345
+ usedTextures.push('_ambientOcclusionMap = textureSample(AmbientOcclusionTexture, AmbientOcclusionTextureSampler, input.tcoordVS);');
346
+ }
347
+ }
348
+
349
+ if ((_actor$getProperty$ge12 = (_actor$getProperty7 = actor.getProperty()).getEmissionTexture) !== null && _actor$getProperty$ge12 !== void 0 && (_actor$getProperty$ge13 = _actor$getProperty$ge12.call(_actor$getProperty7)) !== null && _actor$getProperty$ge13 !== void 0 && _actor$getProperty$ge13.getImageLoaded()) {
350
+ if (checkDims(actor.getProperty().getEmissionTexture())) {
351
+ usedTextures.push('_emissionMap = textureSample(EmissionTexture, EmissionTextureSampler, input.tcoordVS);');
352
+ }
353
+ }
354
+
355
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::TCoord::Impl', usedTextures).result;
356
+ fDesc.setCode(code);
357
+ };
358
+
359
+ model.shaderReplacements.set('replaceShaderTCoord', publicAPI.replaceShaderTCoord);
360
+
361
+ publicAPI.replaceShaderSelect = function (hash, pipeline, vertexInput) {
362
+ if (hash.includes('sel')) {
363
+ var fDesc = pipeline.getShaderDescription('fragment');
364
+ var code = fDesc.getCode(); // by default there are no composites, so just 0
365
+
366
+ code = vtkWebGPUShaderCache.substitute(code, '//VTK::Select::Impl', [' var compositeID: u32 = 0u;']).result;
367
+ fDesc.setCode(code);
368
+ }
369
+ };
370
+
371
+ model.shaderReplacements.set('replaceShaderSelect', publicAPI.replaceShaderSelect);
372
+
373
+ publicAPI.getUsage = function (rep, i) {
374
+ if (rep === Representation.POINTS || i === PrimitiveTypes.Points) {
375
+ return BufferUsage.Verts;
376
+ }
377
+
378
+ if (i === PrimitiveTypes.Lines) {
379
+ return BufferUsage.Lines;
380
+ }
381
+
382
+ if (rep === Representation.WIREFRAME) {
383
+ if (i === PrimitiveTypes.Triangles) {
384
+ return BufferUsage.LinesFromTriangles;
385
+ }
386
+
387
+ return BufferUsage.LinesFromStrips;
388
+ }
389
+
390
+ if (i === PrimitiveTypes.Triangles) {
391
+ return BufferUsage.Triangles;
392
+ }
393
+
394
+ if (i === PrimitiveTypes.TriangleStrips) {
395
+ return BufferUsage.Strips;
396
+ }
397
+
398
+ if (i === PrimitiveTypes.TriangleEdges) {
399
+ return BufferUsage.LinesFromTriangles;
400
+ } // only strip edges left which are lines
401
+
402
+
403
+ return BufferUsage.LinesFromStrips;
404
+ };
405
+
406
+ publicAPI.getHashFromUsage = function (usage) {
407
+ return "pt".concat(usage);
408
+ };
409
+
410
+ publicAPI.getTopologyFromUsage = function (usage) {
411
+ switch (usage) {
412
+ case BufferUsage.Triangles:
413
+ return 'triangle-list';
414
+
415
+ case BufferUsage.Verts:
416
+ return 'point-list';
417
+
418
+ case BufferUsage.Lines:
419
+ default:
420
+ return 'line-list';
421
+ }
422
+ }; // TODO: calculate tangents
423
+
424
+
425
+ publicAPI.buildVertexInput = function () {
426
+ var _model$renderable$get, _model$renderable;
427
+
428
+ var pd = model.currentInput;
429
+ var cells = model.cellArray;
430
+ var primType = model.primitiveType;
431
+ var actor = model.WebGPUActor.getRenderable();
432
+ var representation = actor.getProperty().getRepresentation();
433
+ var device = model.WebGPURenderWindow.getDevice();
434
+ var edges = false;
435
+
436
+ if (primType === PrimitiveTypes.TriangleEdges) {
437
+ edges = true;
438
+ representation = Representation.WIREFRAME;
439
+ }
440
+
441
+ var vertexInput = model.vertexInput;
442
+ var points = pd.getPoints();
443
+ var indexBuffer; // get the flat mapping indexBuffer for the cells
444
+
445
+ if (cells) {
446
+ var buffRequest = {
447
+ hash: "R".concat(representation, "P").concat(primType).concat(cells.getMTime()),
448
+ usage: BufferUsage.Index,
449
+ cells: cells,
450
+ numberOfPoints: points.getNumberOfPoints(),
451
+ primitiveType: primType,
452
+ representation: representation
453
+ };
454
+ indexBuffer = device.getBufferManager().getBuffer(buffRequest);
455
+ vertexInput.setIndexBuffer(indexBuffer);
456
+ } else {
457
+ vertexInput.setIndexBuffer(null);
458
+ } // hash = all things that can change the values on the buffer
459
+ // since mtimes are unique we can use
460
+ // - indexBuffer mtime - because cells drive how we pack
461
+ // - relevant dataArray mtime - the source data
462
+ // - shift - not currently captured
463
+ // - scale - not currently captured
464
+ // - format
465
+ // - usage
466
+ // - packExtra - covered by format
467
+ // points
468
+
469
+
470
+ if (points) {
471
+ var shift = model.WebGPUActor.getBufferShift(model.WebGPURenderer);
472
+ var _buffRequest = {
473
+ hash: "".concat(points.getMTime(), "I").concat(indexBuffer.getMTime()).concat(shift.join(), "float32x4"),
474
+ usage: BufferUsage.PointArray,
475
+ format: 'float32x4',
476
+ dataArray: points,
477
+ indexBuffer: indexBuffer,
478
+ shift: shift,
479
+ packExtra: true
480
+ };
481
+ var buff = device.getBufferManager().getBuffer(_buffRequest);
482
+ vertexInput.addBuffer(buff, ['vertexBC']);
483
+ } else {
484
+ vertexInput.removeBufferIfPresent('vertexBC');
485
+ } // normals, only used for surface rendering
486
+
487
+
488
+ var usage = publicAPI.getUsage(representation, primType);
489
+ model._usesCellNormals = false;
490
+
491
+ if (!model.is2D && ( // no lighting on Property2D
492
+ usage === BufferUsage.Triangles || usage === BufferUsage.Strips)) {
493
+ var normals = pd.getPointData().getNormals(); // https://vtk.org/doc/nightly/html/classvtkPolyDataTangents.html
494
+ // Need to find some way of using precomputed tangents (or computing new ones)
495
+
496
+ var _buffRequest2 = {
497
+ format: 'snorm8x4',
498
+ indexBuffer: indexBuffer,
499
+ packExtra: true,
500
+ shift: 0,
501
+ scale: 127
502
+ };
503
+
504
+ if (normals) {
505
+ _buffRequest2.hash = "".concat(normals.getMTime(), "I").concat(indexBuffer.getMTime(), "snorm8x4");
506
+ _buffRequest2.dataArray = normals;
507
+ _buffRequest2.usage = BufferUsage.PointArray;
508
+
509
+ var _buff = device.getBufferManager().getBuffer(_buffRequest2);
510
+
511
+ vertexInput.addBuffer(_buff, ['normalMC']);
512
+ } else if (primType === PrimitiveTypes.Triangles) {
513
+ model._usesCellNormals = true;
514
+ _buffRequest2.hash = "PFN".concat(points.getMTime(), "I").concat(indexBuffer.getMTime(), "snorm8x4");
515
+ _buffRequest2.dataArray = points;
516
+ _buffRequest2.cells = cells;
517
+ _buffRequest2.usage = BufferUsage.NormalsFromPoints;
518
+
519
+ var _buff2 = device.getBufferManager().getBuffer(_buffRequest2);
520
+
521
+ vertexInput.addBuffer(_buff2, ['normalMC']);
522
+ } else {
523
+ vertexInput.removeBufferIfPresent('normalMC');
524
+ }
525
+ } else {
526
+ vertexInput.removeBufferIfPresent('normalMC');
527
+ } // deal with colors but only if modified
528
+
529
+
530
+ var haveColors = false;
531
+
532
+ if (model.renderable.getScalarVisibility()) {
533
+ var c = model.renderable.getColorMapColors();
534
+
535
+ if (c && !edges) {
536
+ var scalarMode = model.renderable.getScalarMode();
537
+ var haveCellScalars = false; // We must figure out how the scalars should be mapped to the polydata.
538
+
539
+ if ((scalarMode === ScalarMode.USE_CELL_DATA || scalarMode === ScalarMode.USE_CELL_FIELD_DATA || scalarMode === ScalarMode.USE_FIELD_DATA || !pd.getPointData().getScalars()) && scalarMode !== ScalarMode.USE_POINT_FIELD_DATA && c) {
540
+ haveCellScalars = true;
541
+ }
542
+
543
+ var _buffRequest3 = {
544
+ usage: BufferUsage.PointArray,
545
+ format: 'unorm8x4',
546
+ hash: "".concat(haveCellScalars).concat(c.getMTime(), "I").concat(indexBuffer.getMTime(), "unorm8x4"),
547
+ dataArray: c,
548
+ indexBuffer: indexBuffer,
549
+ cellData: haveCellScalars,
550
+ cellOffset: 0
551
+ };
552
+
553
+ var _buff3 = device.getBufferManager().getBuffer(_buffRequest3);
554
+
555
+ vertexInput.addBuffer(_buff3, ['colorVI']);
556
+ haveColors = true;
557
+ }
558
+ }
559
+
560
+ if (!haveColors) {
561
+ vertexInput.removeBufferIfPresent('colorVI');
562
+ }
563
+
564
+ var tcoords = null;
565
+
566
+ if ((_model$renderable$get = (_model$renderable = model.renderable).getInterpolateScalarsBeforeMapping) !== null && _model$renderable$get !== void 0 && _model$renderable$get.call(_model$renderable) && model.renderable.getColorCoordinates()) {
567
+ tcoords = model.renderable.getColorCoordinates();
568
+ } else {
569
+ tcoords = pd.getPointData().getTCoords();
570
+ }
571
+
572
+ if (tcoords && !edges) {
573
+ var _buff4 = device.getBufferManager().getBufferForPointArray(tcoords, vertexInput.getIndexBuffer());
574
+
575
+ vertexInput.addBuffer(_buff4, ['tcoord']);
576
+ } else {
577
+ vertexInput.removeBufferIfPresent('tcoord');
578
+ }
579
+ };
580
+
581
+ publicAPI.updateTextures = function () {
582
+ var _model$renderable$get2, _model$renderable2, _actor$getProperty$ge14, _actor$getProperty8, _actor$getProperty$ge15, _actor$getProperty9, _actor$getProperty$ge16, _actor$getProperty10, _actor$getProperty$ge17, _actor$getProperty11, _actor$getProperty$ge18, _actor$getProperty12, _actor$getProperty$ge19, _actor$getProperty13, _renderer$getEnvironm2;
583
+
584
+ // we keep track of new and used textures so
585
+ // that we can clean up any unused textures so we don't hold onto them
586
+ var usedTextures = [];
587
+ var newTextures = []; // do we have a scalar color texture
588
+
589
+ var idata = (_model$renderable$get2 = (_model$renderable2 = model.renderable).getColorTextureMap) === null || _model$renderable$get2 === void 0 ? void 0 : _model$renderable$get2.call(_model$renderable2);
590
+
591
+ if (idata) {
592
+ if (!model.colorTexture) {
593
+ model.colorTexture = vtkTexture.newInstance({
594
+ label: 'polyDataColor'
595
+ });
596
+ }
597
+
598
+ model.colorTexture.setInputData(idata);
599
+ newTextures.push(['Diffuse', model.colorTexture]);
600
+ } // actor textures?
601
+
602
+
603
+ var actor = model.WebGPUActor.getRenderable();
604
+ var renderer = model.WebGPURenderer.getRenderable(); // Reusing the old code for new and old textures, just loading in from properties instead of actor.getTextures()
605
+
606
+ var textures = []; // Feels like there should be a better way than individually adding all
607
+
608
+ if ((_actor$getProperty$ge14 = (_actor$getProperty8 = actor.getProperty()).getDiffuseTexture) !== null && _actor$getProperty$ge14 !== void 0 && _actor$getProperty$ge14.call(_actor$getProperty8)) {
609
+ var pair = ['Diffuse', actor.getProperty().getDiffuseTexture()];
610
+ textures.push(pair);
611
+ }
612
+
613
+ if (actor.getTextures()[0]) {
614
+ var _pair = ['Diffuse', actor.getTextures()[0]];
615
+ textures.push(_pair);
616
+ }
617
+
618
+ if (model.colorTexture) {
619
+ var _pair2 = ['Diffuse', model.colorTexture];
620
+ textures.push(_pair2);
621
+ }
622
+
623
+ if ((_actor$getProperty$ge15 = (_actor$getProperty9 = actor.getProperty()).getRoughnessTexture) !== null && _actor$getProperty$ge15 !== void 0 && _actor$getProperty$ge15.call(_actor$getProperty9)) {
624
+ var _pair3 = ['Roughness', actor.getProperty().getRoughnessTexture()];
625
+ textures.push(_pair3);
626
+ }
627
+
628
+ if ((_actor$getProperty$ge16 = (_actor$getProperty10 = actor.getProperty()).getMetallicTexture) !== null && _actor$getProperty$ge16 !== void 0 && _actor$getProperty$ge16.call(_actor$getProperty10)) {
629
+ var _pair4 = ['Metallic', actor.getProperty().getMetallicTexture()];
630
+ textures.push(_pair4);
631
+ }
632
+
633
+ if ((_actor$getProperty$ge17 = (_actor$getProperty11 = actor.getProperty()).getNormalTexture) !== null && _actor$getProperty$ge17 !== void 0 && _actor$getProperty$ge17.call(_actor$getProperty11)) {
634
+ var _pair5 = ['Normal', actor.getProperty().getNormalTexture()];
635
+ textures.push(_pair5);
636
+ }
637
+
638
+ if ((_actor$getProperty$ge18 = (_actor$getProperty12 = actor.getProperty()).getAmbientOcclusionTexture) !== null && _actor$getProperty$ge18 !== void 0 && _actor$getProperty$ge18.call(_actor$getProperty12)) {
639
+ var _pair6 = ['AmbientOcclusion', actor.getProperty().getAmbientOcclusionTexture()];
640
+ textures.push(_pair6);
641
+ }
642
+
643
+ if ((_actor$getProperty$ge19 = (_actor$getProperty13 = actor.getProperty()).getEmissionTexture) !== null && _actor$getProperty$ge19 !== void 0 && _actor$getProperty$ge19.call(_actor$getProperty13)) {
644
+ var _pair7 = ['Emission', actor.getProperty().getEmissionTexture()];
645
+ textures.push(_pair7);
646
+ }
647
+
648
+ if ((_renderer$getEnvironm2 = renderer.getEnvironmentTexture) !== null && _renderer$getEnvironm2 !== void 0 && _renderer$getEnvironm2.call(renderer)) {
649
+ var _pair8 = ['Environment', renderer.getEnvironmentTexture()];
650
+ textures.push(_pair8);
651
+ }
652
+
653
+ for (var i = 0; i < textures.length; i++) {
654
+ if (textures[i][1].getInputData() || textures[i][1].getJsImageData() || textures[i][1].getCanvas()) {
655
+ newTextures.push(textures[i]);
656
+ }
657
+
658
+ if (textures[i][1].getImage() && textures[i][1].getImageLoaded()) {
659
+ newTextures.push(textures[i]);
660
+ }
661
+ }
662
+
663
+ for (var _i = 0; _i < newTextures.length; _i++) {
664
+ var srcTexture = newTextures[_i][1];
665
+ var textureName = newTextures[_i][0];
666
+ var newTex = model.device.getTextureManager().getTextureForVTKTexture(srcTexture); // Generates hash
667
+
668
+ if (newTex.getReady()) {
669
+ // is this a new texture
670
+ var found = false;
671
+
672
+ for (var t = 0; t < model.textures.length; t++) {
673
+ if (model.textures[t] === newTex) {
674
+ found = true;
675
+ usedTextures[t] = true;
676
+ }
677
+ }
678
+
679
+ if (!found) {
680
+ usedTextures[model.textures.length] = true;
681
+ var tview = newTex.createView("".concat(textureName, "Texture"));
682
+ model.textures.push(newTex);
683
+ model.textureViews.push(tview);
684
+ var interpolate = srcTexture.getInterpolate() ? 'linear' : 'nearest';
685
+ var addressMode = null;
686
+ if (!addressMode && srcTexture.getEdgeClamp() && srcTexture.getRepeat()) addressMode = 'mirror-repeat';
687
+ if (!addressMode && srcTexture.getEdgeClamp()) addressMode = 'clamp-to-edge';
688
+ if (!addressMode && srcTexture.getRepeat()) addressMode = 'repeat';
689
+
690
+ if (textureName !== 'Environment') {
691
+ tview.addSampler(model.device, {
692
+ addressModeU: addressMode,
693
+ addressModeV: addressMode,
694
+ addressModeW: addressMode,
695
+ minFilter: interpolate,
696
+ magFilter: interpolate
697
+ });
698
+ } else {
699
+ tview.addSampler(model.device, {
700
+ addressModeU: 'repeat',
701
+ addressModeV: 'clamp-to-edge',
702
+ addressModeW: 'repeat',
703
+ minFilter: interpolate,
704
+ magFilter: interpolate,
705
+ mipmapFilter: 'linear'
706
+ });
707
+ }
708
+ }
709
+ }
710
+ } // remove unused textures
711
+
712
+
713
+ for (var _i2 = model.textures.length - 1; _i2 >= 0; _i2--) {
714
+ if (!usedTextures[_i2]) {
715
+ model.textures.splice(_i2, 1);
716
+ model.textureViews.splice(_i2, 1);
717
+ }
718
+ }
719
+ }; // compute a unique hash for a pipeline, this needs to be unique enough to
720
+ // capture any pipeline code changes (which includes shader changes)
721
+ // or vertex input changes/ bind groups/ etc
722
+
723
+
724
+ publicAPI.computePipelineHash = function () {
725
+ var pipelineHash = "pd".concat(model.useRendererMatrix ? 'r' : '').concat(model.forceZValue ? 'z' : '');
726
+
727
+ if (model.primitiveType === PrimitiveTypes.TriangleEdges || model.primitiveType === PrimitiveTypes.TriangleStripEdges) {
728
+ pipelineHash += 'edge';
729
+ } else {
730
+ if (model.vertexInput.hasAttribute("normalMC")) {
731
+ pipelineHash += "n";
732
+ }
733
+
734
+ if (model.vertexInput.hasAttribute("colorVI")) {
735
+ pipelineHash += "c";
736
+ }
737
+
738
+ if (model.vertexInput.hasAttribute("tcoord")) {
739
+ var tcoords = model.vertexInput.getBuffer('tcoord');
740
+ var numComp = vtkWebGPUTypes.getNumberOfComponentsFromBufferFormat(tcoords.getArrayInformation()[0].format);
741
+ pipelineHash += "t".concat(numComp);
742
+ }
743
+
744
+ if (model.textures.length) {
745
+ pipelineHash += "tx".concat(model.textures.length);
746
+ }
747
+ }
748
+
749
+ if (model._usesCellNormals) {
750
+ pipelineHash += "cn";
751
+ }
752
+
753
+ if (model.SSBO) {
754
+ pipelineHash += "ssbo";
755
+ }
756
+
757
+ var uhash = publicAPI.getHashFromUsage(model.usage);
758
+ pipelineHash += uhash;
759
+ pipelineHash += model.renderEncoder.getPipelineHash();
760
+ model.pipelineHash = pipelineHash;
761
+ };
762
+
763
+ publicAPI.updateBuffers = function () {
764
+ // handle textures if not edges
765
+ if (model.primitiveType !== PrimitiveTypes.TriangleEdges && model.primitiveType !== PrimitiveTypes.TriangleStripEdges) {
766
+ publicAPI.updateTextures();
767
+ }
768
+
769
+ var actor = model.WebGPUActor.getRenderable();
770
+ var rep = actor.getProperty().getRepresentation(); // handle per primitive type
771
+
772
+ model.usage = publicAPI.getUsage(rep, model.primitiveType);
773
+ publicAPI.buildVertexInput();
774
+ var vbo = model.vertexInput.getBuffer('vertexBC');
775
+ publicAPI.setNumberOfVertices(vbo.getSizeInBytes() / vbo.getStrideInBytes());
776
+ publicAPI.setTopology(publicAPI.getTopologyFromUsage(model.usage));
777
+ publicAPI.updateUBO();
778
+
779
+ if (publicAPI.haveWideLines()) {
780
+ var ppty = actor.getProperty();
781
+ publicAPI.setNumberOfInstances(Math.ceil(ppty.getLineWidth() * 2.0));
782
+ } else {
783
+ publicAPI.setNumberOfInstances(1);
784
+ }
785
+ };
786
+ } // ----------------------------------------------------------------------------
787
+ // Object factory
788
+ // ----------------------------------------------------------------------------
789
+
790
+
791
+ var DEFAULT_VALUES = {
792
+ is2D: false,
793
+ cellArray: null,
794
+ currentInput: null,
795
+ cellOffset: 0,
796
+ primitiveType: 0,
797
+ colorTexture: null,
798
+ renderEncoder: null,
799
+ textures: null
800
+ }; // ----------------------------------------------------------------------------
801
+
802
+ function extend(publicAPI, model) {
803
+ var initiaLalues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
804
+ Object.assign(model, DEFAULT_VALUES, initiaLalues); // Inheritance
805
+
806
+ vtkWebGPUSimpleMapper.extend(publicAPI, model, initiaLalues);
807
+ model.fragmentShaderTemplate = vtkWebGPUPolyDataFS;
808
+ model.vertexShaderTemplate = vtkWebGPUPolyDataVS;
809
+ model._tmpMat3 = mat3.identity(new Float64Array(9));
810
+ model._tmpMat4 = mat4.identity(new Float64Array(16)); // UBO
811
+
812
+ model.UBO = vtkWebGPUUniformBuffer.newInstance({
813
+ label: 'mapperUBO'
814
+ });
815
+ model.UBO.addEntry('BCWCMatrix', 'mat4x4<f32>');
816
+ model.UBO.addEntry('BCSCMatrix', 'mat4x4<f32>');
817
+ model.UBO.addEntry('MCWCNormals', 'mat4x4<f32>');
818
+ model.UBO.addEntry('AmbientColor', 'vec4<f32>');
819
+ model.UBO.addEntry('DiffuseColor', 'vec4<f32>');
820
+ model.UBO.addEntry('EdgeColor', 'vec4<f32>');
821
+ model.UBO.addEntry('SpecularColor', 'vec4<f32>');
822
+ model.UBO.addEntry('AmbientIntensity', 'f32');
823
+ model.UBO.addEntry('DiffuseIntensity', 'f32');
824
+ model.UBO.addEntry('Roughness', 'f32');
825
+ model.UBO.addEntry('Metallic', 'f32');
826
+ model.UBO.addEntry('Ambient', 'f32');
827
+ model.UBO.addEntry('Normal', 'f32');
828
+ model.UBO.addEntry('Emission', 'f32');
829
+ model.UBO.addEntry('NormalStrength', 'f32');
830
+ model.UBO.addEntry('BaseIOR', 'f32');
831
+ model.UBO.addEntry('SpecularIntensity', 'f32');
832
+ model.UBO.addEntry('LineWidth', 'f32');
833
+ model.UBO.addEntry('Opacity', 'f32');
834
+ model.UBO.addEntry('ZValue', 'f32');
835
+ model.UBO.addEntry('PropID', 'u32');
836
+ model.UBO.addEntry('ClipNear', 'f32');
837
+ model.UBO.addEntry('ClipFar', 'f32');
838
+ model.UBO.addEntry('Time', 'u32'); // Build VTK API
839
+
840
+ setGet(publicAPI, model, ['cellArray', 'currentInput', 'cellOffset', 'is2D', 'primitiveType', 'renderEncoder']);
841
+ model.textures = []; // Object methods
842
+
843
+ vtkWebGPUCellArrayMapper(publicAPI, model);
844
+ } // ----------------------------------------------------------------------------
845
+
846
+ var newInstance = newInstance$1(extend, 'vtkWebGPUCellArrayMapper'); // ----------------------------------------------------------------------------
847
+
848
+ var vtkWebGPUCellArrayMapper$1 = {
849
+ newInstance: newInstance,
850
+ extend: extend
851
+ };
852
+
853
+ export { vtkWebGPUCellArrayMapper$1 as default, extend, newInstance };