@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.
- package/Common/Core/Math/Constants.js +12 -0
- package/Common/Core/Math/index.js +1 -1
- package/Common/Core/Math.js +1 -1
- package/Common/Core/ScalarsToColors/Constants.d.ts +18 -0
- package/Common/DataModel/AbstractPointLocator.d.ts +54 -0
- package/Common/DataModel/AbstractPointLocator.js +40 -0
- package/Common/DataModel/BoundingBox.d.ts +659 -0
- package/Common/DataModel/Collection.d.ts +118 -0
- package/Common/DataModel/Collection.js +113 -0
- package/Common/DataModel/DataSet/Constants.d.ts +27 -0
- package/Common/DataModel/EdgeLocator.d.ts +79 -0
- package/Common/DataModel/EdgeLocator.js +85 -0
- package/Common/DataModel/ITKHelper.d.ts +54 -0
- package/Common/DataModel/IncrementalOctreeNode.d.ts +297 -0
- package/Common/DataModel/IncrementalOctreeNode.js +640 -0
- package/Common/DataModel/IncrementalOctreePointLocator.d.ts +61 -0
- package/Common/DataModel/IncrementalOctreePointLocator.js +398 -0
- package/Common/DataModel/Locator.d.ts +43 -0
- package/Common/DataModel/Locator.js +37 -0
- package/Common/DataModel/Plane.js +1 -1
- package/Common/DataModel/PolyData/Constants.d.ts +6 -0
- package/Common/DataModel/PolyLine.d.ts +63 -0
- package/Common/DataModel/PolyLine.js +77 -0
- package/Common/DataModel/Polygon/Constants.js +12 -0
- package/Common/DataModel/Polygon.js +1 -1
- package/Common/DataModel/Quad/Constants.js +9 -0
- package/Common/DataModel/Quad.d.ts +91 -0
- package/Common/DataModel/Quad.js +235 -0
- package/Common/DataModel/SelectionNode/Constants.d.ts +27 -0
- package/Common/DataModel/Spline1D/Constants.js +17 -0
- package/Common/DataModel/Spline3D/Constants.d.ts +9 -0
- package/Common/Transform/Transform.js +51 -0
- package/Filters/Core/PolyDataNormals.js +124 -0
- package/Filters/General/ClipClosedSurface/Constants.js +10 -0
- package/Filters/General/ClipClosedSurface.d.ts +95 -0
- package/Filters/General/ClipClosedSurface.js +972 -0
- package/Filters/General/ContourTriangulator/Constants.js +6 -0
- package/Filters/General/ContourTriangulator/helper.js +1951 -0
- package/Filters/General/ContourTriangulator.d.ts +136 -0
- package/Filters/General/ContourTriangulator.js +202 -0
- package/Filters/General/ImageMarchingCubes.js +1 -1
- package/Filters/General/MoleculeToRepresentation.js +1 -1
- package/Filters/General/OBBTree/OBBNode.js +82 -0
- package/Filters/General/OBBTree/helper.js +92 -0
- package/Filters/General/OBBTree.js +1243 -0
- package/Filters/General/TubeFilter.js +1 -1
- package/Filters/Sources/LineSource.js +1 -1
- package/Filters/Sources/PlaneSource.js +1 -1
- package/Filters/Texture/TextureMapToPlane.js +1 -1
- package/Interaction/Manipulators/CompositeCameraManipulator.d.ts +68 -0
- package/Interaction/Manipulators/CompositeGestureManipulator.d.ts +168 -0
- package/Interaction/Manipulators/CompositeKeyboardManipulator.d.ts +48 -0
- package/Interaction/Manipulators/CompositeMouseManipulator.d.ts +149 -0
- package/Interaction/Manipulators/CompositeVRManipulator.d.ts +44 -0
- package/Interaction/Manipulators/GestureCameraManipulator.d.ts +34 -0
- package/Interaction/Manipulators/KeyboardCameraManipulator.js +1 -1
- package/Interaction/Manipulators/MouseBoxSelectorManipulator.d.ts +88 -0
- package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballMultiRotateManipulator.d.ts +32 -0
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.d.ts +33 -0
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.d.ts +33 -0
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.d.ts +67 -0
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.d.ts +45 -0
- package/Interaction/Manipulators/MouseCameraTrackballZoomToMouseManipulator.d.ts +26 -0
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
- package/Interaction/Manipulators/MouseRangeManipulator.d.ts +53 -0
- package/Interaction/Style/InteractorStyleImage.d.ts +107 -0
- package/Interaction/Style/InteractorStyleMPRSlice.js +1 -1
- package/Interaction/Style/InteractorStyleManipulator.d.ts +348 -0
- package/Interaction/Style/InteractorStyleTrackballCamera.d.ts +170 -0
- package/Interaction/Widgets/ImageCroppingRegionsWidget.js +1 -1
- package/Interaction/Widgets/LabelRepresentation.js +1 -1
- package/Interaction/Widgets/OrientationMarkerWidget/Constants.d.ts +11 -0
- package/Interaction/Widgets/ResliceCursor/ResliceCursor.js +1 -1
- package/Interaction/Widgets/ResliceCursor/ResliceCursorLineRepresentation.js +1 -1
- package/Interaction/Widgets/ResliceCursor/ResliceCursorRepresentation.js +1 -1
- package/Proxy/Core/AbstractRepresentationProxy.d.ts +24 -0
- package/Proxy/Core/LookupTableProxy.d.ts +45 -0
- package/Proxy/Core/PiecewiseFunctionProxy.d.ts +62 -0
- package/Proxy/Core/ProxyManager.d.ts +115 -0
- package/Proxy/Core/SourceProxy.d.ts +22 -0
- package/Proxy/Core/View2DProxy.d.ts +7 -0
- package/Proxy/Core/View2DProxy.js +1 -1
- package/Proxy/Core/ViewProxy.d.ts +86 -0
- package/Proxy/Representations/SliceRepresentationProxy.d.ts +27 -0
- package/Proxy/Representations/VolumeRepresentationProxy.d.ts +44 -0
- package/README.md +2 -2
- package/Rendering/Core/AbstractImageMapper/helper.js +127 -0
- package/Rendering/Core/AbstractImageMapper.d.ts +82 -0
- package/Rendering/Core/AbstractImageMapper.js +44 -0
- package/Rendering/Core/Camera.js +1 -1
- package/Rendering/Core/CellPicker.js +1 -1
- package/Rendering/Core/ColorTransferFunction/ColorMaps.d.ts +24 -0
- package/Rendering/Core/ColorTransferFunction/Constants.d.ts +17 -0
- package/Rendering/Core/ColorTransferFunction.js +1 -1
- package/Rendering/Core/Coordinate/Constants.d.ts +14 -0
- package/Rendering/Core/Coordinate.js +1 -1
- package/Rendering/Core/Glyph3DMapper/Constants.d.ts +17 -0
- package/Rendering/Core/Glyph3DMapper.js +1 -1
- package/Rendering/Core/HardwareSelector.d.ts +84 -0
- package/Rendering/Core/ImageArrayMapper.d.ts +253 -0
- package/Rendering/Core/ImageArrayMapper.js +242 -0
- package/Rendering/Core/ImageMapper/Constants.d.ts +14 -0
- package/Rendering/Core/ImageMapper.js +1 -1
- package/Rendering/Core/ImageProperty/Constants.d.ts +9 -0
- package/Rendering/Core/ImageResliceMapper/Constants.d.ts +11 -0
- package/Rendering/Core/ImageResliceMapper/Constants.js +11 -0
- package/Rendering/Core/ImageResliceMapper.d.ts +245 -0
- package/Rendering/Core/ImageResliceMapper.js +70 -0
- package/Rendering/Core/InteractorObserver.d.ts +132 -0
- package/Rendering/Core/InteractorStyle/Constants.d.ts +16 -0
- package/Rendering/Core/InteractorStyle.d.ts +229 -0
- package/Rendering/Core/Light.js +1 -1
- package/Rendering/Core/Mapper/Constants.d.ts +26 -0
- package/Rendering/Core/Mapper.js +1 -1
- package/Rendering/Core/Picker.js +1 -1
- package/Rendering/Core/Prop/Constants.d.ts +9 -0
- package/Rendering/Core/Prop/Constants.js +9 -0
- package/Rendering/Core/Property/Constants.d.ts +24 -0
- package/Rendering/Core/Property2D/Constants.d.ts +9 -0
- package/Rendering/Core/RenderWindow.js +1 -1
- package/Rendering/Core/RenderWindowInteractor/Constants.d.ts +31 -0
- package/Rendering/Core/Renderer.js +1 -1
- package/Rendering/Core/VolumeMapper/Constants.d.ts +20 -0
- package/Rendering/Core/VolumeMapper.js +1 -1
- package/Rendering/Core/VolumeProperty/Constants.d.ts +16 -0
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +129 -0
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager.js +131 -0
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.d.ts +80 -0
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.js +763 -0
- package/Rendering/OpenGL/HardwareSelector/Constants.d.ts +8 -0
- package/Rendering/OpenGL/HardwareSelector.d.ts +339 -0
- package/Rendering/OpenGL/ImageResliceMapper.js +996 -0
- package/Rendering/OpenGL/PolyDataMapper.js +1 -1
- package/Rendering/OpenGL/PolyDataMapper2D.js +1 -1
- package/Rendering/OpenGL/RenderWindow/Constants.d.ts +10 -0
- package/Rendering/OpenGL/RenderWindow/Constants.js +13 -0
- package/Rendering/OpenGL/RenderWindow/ContextProxy.js +70 -0
- package/Rendering/OpenGL/RenderWindow.d.ts +9 -2
- package/Rendering/OpenGL/RenderWindow.js +2 -1
- package/Rendering/OpenGL/glsl/vtkImageResliceMapperFS.glsl.js +3 -0
- package/Rendering/OpenGL/glsl/vtkImageResliceMapperVS.glsl.js +3 -0
- package/Rendering/WebGPU/Actor2D.js +151 -0
- package/Rendering/WebGPU/BufferManager.js +1 -1
- package/Rendering/WebGPU/CellArrayMapper.js +853 -0
- package/Rendering/WebGPU/IndexBuffer.js +397 -0
- package/Rendering/WebGPU/PolyDataMapper2D.js +99 -0
- package/Rendering/WebGPU/RenderWindow.js +3 -1
- package/Rendering/WebGPU/SimpleMapper.js +290 -0
- package/Widgets/Core/AbstractWidget.d.ts +187 -0
- package/Widgets/Core/AbstractWidgetFactory.d.ts +131 -0
- package/Widgets/Core/StateBuilder/color3Mixin.js +24 -0
- package/Widgets/Core/StateBuilder/orientationMixin.js +1 -1
- package/Widgets/Core/StateBuilder.d.ts +29 -0
- package/Widgets/Core/WidgetManager/Constants.d.ts +27 -0
- package/Widgets/Core/WidgetManager.d.ts +231 -0
- package/Widgets/Core/WidgetState.d.ts +81 -0
- package/Widgets/Manipulators/AbstractManipulator.d.ts +221 -0
- package/Widgets/Manipulators/AbstractManipulator.js +57 -0
- package/Widgets/Manipulators/LineManipulator.js +1 -1
- package/Widgets/Manipulators/TrackballManipulator.js +1 -1
- package/Widgets/Representations/GlyphRepresentation.js +325 -0
- package/Widgets/Representations/LineHandleRepresentation.js +116 -0
- package/Widgets/Representations/ResliceCursorContextRepresentation.js +1 -1
- package/Widgets/Representations/WidgetRepresentation.js +1 -1
- package/Widgets/Widgets3D/AngleWidget.js +1 -1
- package/Widgets/Widgets3D/InteractiveOrientationWidget.d.ts +40 -0
- package/Widgets/Widgets3D/LabelWidget/behavior.js +157 -0
- package/Widgets/Widgets3D/LabelWidget/state.js +22 -0
- package/Widgets/Widgets3D/LabelWidget.js +78 -0
- package/Widgets/Widgets3D/LineWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
- package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
- package/index.d.ts +133 -74
- 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 };
|