@kitware/vtk.js 24.5.2 → 24.5.5
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/DataModel/DataSetAttributes/FieldData.d.ts +3 -1
- package/Rendering/Core/RenderWindowInteractor.d.ts +123 -109
- package/Rendering/Core/ScalarBarActor.js +2 -2
- package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +5 -1
- package/Rendering/OpenGL/RenderWindow.d.ts +1 -1
- package/Rendering/OpenGL/VolumeMapper.js +1 -1
- package/Rendering/SceneGraph/ViewNode.js +28 -2
- package/Rendering/WebGPU/BufferManager.js +83 -14
- package/Rendering/WebGPU/CellArrayMapper.js +591 -0
- package/Rendering/WebGPU/Device.js +97 -57
- package/Rendering/WebGPU/FullScreenQuad.js +4 -6
- package/Rendering/WebGPU/Glyph3DMapper.js +62 -27
- package/Rendering/WebGPU/ImageMapper.js +23 -64
- package/Rendering/WebGPU/OrderIndependentTranslucentPass.js +4 -6
- package/Rendering/WebGPU/Pipeline.js +12 -0
- package/Rendering/WebGPU/PolyDataMapper.js +49 -623
- package/Rendering/WebGPU/RenderEncoder.js +34 -0
- package/Rendering/WebGPU/Renderer.js +4 -62
- package/Rendering/WebGPU/ShaderDescription.js +6 -6
- package/Rendering/WebGPU/{MapperHelper.js → SimpleMapper.js} +64 -38
- package/Rendering/WebGPU/SphereMapper.js +66 -64
- package/Rendering/WebGPU/StickMapper.js +73 -72
- package/Rendering/WebGPU/StorageBuffer.js +2 -3
- package/Rendering/WebGPU/Texture.js +0 -2
- package/Rendering/WebGPU/TextureManager.js +37 -7
- package/Rendering/WebGPU/UniformBuffer.js +1 -2
- package/Rendering/WebGPU/Volume.js +1 -14
- package/Rendering/WebGPU/VolumePass.js +16 -22
- package/Rendering/WebGPU/VolumePassFSQ.js +19 -29
- package/package.json +1 -1
|
@@ -0,0 +1,591 @@
|
|
|
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 vtkProperty from '../Core/Property.js';
|
|
5
|
+
import vtkTexture from '../Core/Texture.js';
|
|
6
|
+
import vtkWebGPUBufferManager from './BufferManager.js';
|
|
7
|
+
import vtkWebGPUShaderCache from './ShaderCache.js';
|
|
8
|
+
import vtkWebGPUUniformBuffer from './UniformBuffer.js';
|
|
9
|
+
import vtkWebGPUSimpleMapper from './SimpleMapper.js';
|
|
10
|
+
|
|
11
|
+
var BufferUsage = vtkWebGPUBufferManager.BufferUsage,
|
|
12
|
+
PrimitiveTypes = vtkWebGPUBufferManager.PrimitiveTypes;
|
|
13
|
+
var Representation = vtkProperty.Representation;
|
|
14
|
+
var ScalarMode = vtkMapper.ScalarMode;
|
|
15
|
+
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@stage(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";
|
|
16
|
+
var vtkWebGPUPolyDataFS = "\n//VTK::Renderer::Dec\n\n//VTK::Color::Dec\n\n// optional surface normal declaration\n//VTK::Normal::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::Select::Dec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::IOStructs::Dec\n\n@stage(fragment)\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output : fragmentOutput;\n\n var ambientColor: vec4<f32> = mapperUBO.AmbientColor;\n var diffuseColor: vec4<f32> = mapperUBO.DiffuseColor;\n var opacity: f32 = mapperUBO.Opacity;\n\n //VTK::Color::Impl\n\n //VTK::Normal::Impl\n\n //VTK::Light::Impl\n\n var computedColor: vec4<f32> = vec4<f32>(ambientColor.rgb * mapperUBO.AmbientIntensity\n + diffuse * mapperUBO.DiffuseIntensity\n + specular * mapperUBO.SpecularIntensity,\n opacity);\n\n //VTK::TCoord::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 return output;\n}\n";
|
|
17
|
+
|
|
18
|
+
function isEdges(hash) {
|
|
19
|
+
// edge pipelines have "edge" in them
|
|
20
|
+
return hash.indexOf('edge') >= 0;
|
|
21
|
+
} // ----------------------------------------------------------------------------
|
|
22
|
+
// vtkWebGPUCellArrayMapper methods
|
|
23
|
+
// ----------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function vtkWebGPUCellArrayMapper(publicAPI, model) {
|
|
27
|
+
// Set our className
|
|
28
|
+
model.classHierarchy.push('vtkWebGPUCellArrayMapper');
|
|
29
|
+
|
|
30
|
+
publicAPI.buildPass = function (prepass) {
|
|
31
|
+
if (prepass) {
|
|
32
|
+
model.WebGPUActor = publicAPI.getFirstAncestorOfType('vtkWebGPUActor');
|
|
33
|
+
model.WebGPURenderer = model.WebGPUActor.getFirstAncestorOfType('vtkWebGPURenderer');
|
|
34
|
+
model.WebGPURenderWindow = model.WebGPURenderer.getParent();
|
|
35
|
+
model.device = model.WebGPURenderWindow.getDevice();
|
|
36
|
+
}
|
|
37
|
+
}; // Renders myself
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
publicAPI.translucentPass = function (prepass) {
|
|
41
|
+
if (prepass) {
|
|
42
|
+
publicAPI.prepareToDraw(model.WebGPURenderer.getRenderEncoder());
|
|
43
|
+
model.renderEncoder.registerDrawCallback(model.pipeline, publicAPI.draw);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
publicAPI.opaquePass = function (prepass) {
|
|
48
|
+
if (prepass) {
|
|
49
|
+
publicAPI.prepareToDraw(model.WebGPURenderer.getRenderEncoder());
|
|
50
|
+
model.renderEncoder.registerDrawCallback(model.pipeline, publicAPI.draw);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
publicAPI.updateUBO = function () {
|
|
55
|
+
// make sure the data is up to date
|
|
56
|
+
var actor = model.WebGPUActor.getRenderable();
|
|
57
|
+
var ppty = actor.getProperty();
|
|
58
|
+
var utime = model.UBO.getSendTime();
|
|
59
|
+
|
|
60
|
+
if (publicAPI.getMTime() > utime || ppty.getMTime() > utime || model.renderable.getMTime() > utime) {
|
|
61
|
+
var keyMats = model.WebGPUActor.getKeyMatrices(model.WebGPURenderer);
|
|
62
|
+
model.UBO.setArray('BCWCMatrix', keyMats.bcwc);
|
|
63
|
+
model.UBO.setArray('BCSCMatrix', keyMats.bcsc);
|
|
64
|
+
model.UBO.setArray('MCWCNormals', keyMats.normalMatrix);
|
|
65
|
+
var aColor = ppty.getAmbientColorByReference();
|
|
66
|
+
model.UBO.setValue('AmbientIntensity', ppty.getAmbient());
|
|
67
|
+
model.UBO.setArray('AmbientColor', [aColor[0], aColor[1], aColor[2], 1.0]);
|
|
68
|
+
model.UBO.setValue('DiffuseIntensity', ppty.getDiffuse());
|
|
69
|
+
aColor = ppty.getDiffuseColorByReference();
|
|
70
|
+
model.UBO.setArray('DiffuseColor', [aColor[0], aColor[1], aColor[2], 1.0]);
|
|
71
|
+
model.UBO.setValue('SpecularIntensity', ppty.getSpecular());
|
|
72
|
+
model.UBO.setValue('SpecularPower', ppty.getSpecularPower());
|
|
73
|
+
aColor = ppty.getSpecularColorByReference();
|
|
74
|
+
model.UBO.setArray('SpecularColor', [aColor[0], aColor[1], aColor[2], 1.0]);
|
|
75
|
+
model.UBO.setValue('LineWidth', ppty.getLineWidth());
|
|
76
|
+
aColor = ppty.getEdgeColorByReference();
|
|
77
|
+
model.UBO.setArray('EdgeColor', [aColor[0], aColor[1], aColor[2], 1.0]);
|
|
78
|
+
model.UBO.setValue('Opacity', ppty.getOpacity());
|
|
79
|
+
model.UBO.setValue('PropID', model.WebGPUActor.getPropID());
|
|
80
|
+
var device = model.WebGPURenderWindow.getDevice();
|
|
81
|
+
model.UBO.sendIfNeeded(device);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
publicAPI.haveWideLines = function () {
|
|
86
|
+
var actor = model.WebGPUActor.getRenderable();
|
|
87
|
+
var representation = actor.getProperty().getRepresentation();
|
|
88
|
+
|
|
89
|
+
if (actor.getProperty().getLineWidth() <= 1.0) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (model.primitiveType === PrimitiveTypes.Verts) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (model.primitiveType === PrimitiveTypes.Triangles || model.primitiveType === PrimitiveTypes.TriangleStrips) {
|
|
98
|
+
return representation === Representation.WIREFRAME;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return true;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
publicAPI.replaceShaderPosition = function (hash, pipeline, vertexInput) {
|
|
105
|
+
var vDesc = pipeline.getShaderDescription('vertex');
|
|
106
|
+
vDesc.addBuiltinOutput('vec4<f32>', '@builtin(position) Position');
|
|
107
|
+
var code = vDesc.getCode();
|
|
108
|
+
|
|
109
|
+
if (publicAPI.haveWideLines()) {
|
|
110
|
+
vDesc.addBuiltinInput('u32', '@builtin(instance_index) instanceIndex'); // widen the edge
|
|
111
|
+
|
|
112
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' var tmpPos: vec4<f32> = rendererUBO.SCPCMatrix*mapperUBO.BCSCMatrix*vertexBC;', ' 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 = tmpPos2.z + 0.00001;', // could become a setting
|
|
113
|
+
' output.Position = vec4<f32>(tmpPos2.xyz * tmpPos.w, tmpPos.w);']).result;
|
|
114
|
+
} else {
|
|
115
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', [' output.Position = rendererUBO.SCPCMatrix*mapperUBO.BCSCMatrix*vertexBC;']).result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
vDesc.setCode(code);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
model.shaderReplacements.set('replaceShaderPosition', publicAPI.replaceShaderPosition);
|
|
122
|
+
|
|
123
|
+
publicAPI.replaceShaderNormal = function (hash, pipeline, vertexInput) {
|
|
124
|
+
if (vertexInput.hasAttribute('normalMC')) {
|
|
125
|
+
var vDesc = pipeline.getShaderDescription('vertex');
|
|
126
|
+
vDesc.addOutput('vec3<f32>', 'normalVC');
|
|
127
|
+
var code = vDesc.getCode();
|
|
128
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [' output.normalVC = normalize((rendererUBO.WCVCNormals * mapperUBO.MCWCNormals * normalMC).xyz);']).result;
|
|
129
|
+
vDesc.setCode(code);
|
|
130
|
+
var fDesc = pipeline.getShaderDescription('fragment');
|
|
131
|
+
code = fDesc.getCode();
|
|
132
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [' var normal: vec3<f32> = input.normalVC;', ' if (!input.frontFacing) { normal = -normal; }']).result;
|
|
133
|
+
fDesc.setCode(code);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
model.shaderReplacements.set('replaceShaderNormal', publicAPI.replaceShaderNormal); // we only apply lighting when there is a "var normal" declaration in the
|
|
138
|
+
// fragment shader code. That is the lighting trigger.
|
|
139
|
+
|
|
140
|
+
publicAPI.replaceShaderLight = function (hash, pipeline, vertexInput) {
|
|
141
|
+
var fDesc = pipeline.getShaderDescription('fragment');
|
|
142
|
+
var code = fDesc.getCode();
|
|
143
|
+
|
|
144
|
+
if (code.includes('var normal')) {
|
|
145
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Light::Impl', [' var df: f32 = max(0.0, normal.z);', ' var sf: f32 = pow(df, mapperUBO.SpecularPower);', ' var diffuse: vec3<f32> = df * diffuseColor.rgb;', ' var specular: vec3<f32> = sf * mapperUBO.SpecularColor.rgb * mapperUBO.SpecularColor.a;']).result;
|
|
146
|
+
fDesc.setCode(code);
|
|
147
|
+
} else {
|
|
148
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Light::Impl', [' var diffuse: vec3<f32> = diffuseColor.rgb;', ' var specular: vec3<f32> = mapperUBO.SpecularColor.rgb * mapperUBO.SpecularColor.a;']).result;
|
|
149
|
+
fDesc.setCode(code);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
model.shaderReplacements.set('replaceShaderLight', publicAPI.replaceShaderLight);
|
|
154
|
+
|
|
155
|
+
publicAPI.replaceShaderColor = function (hash, pipeline, vertexInput) {
|
|
156
|
+
if (isEdges(hash)) {
|
|
157
|
+
var _fDesc = pipeline.getShaderDescription('fragment');
|
|
158
|
+
|
|
159
|
+
var _code = _fDesc.getCode();
|
|
160
|
+
|
|
161
|
+
_code = vtkWebGPUShaderCache.substitute(_code, '//VTK::Color::Impl', ['ambientColor = mapperUBO.EdgeColor;', 'diffuseColor = mapperUBO.EdgeColor;']).result;
|
|
162
|
+
|
|
163
|
+
_fDesc.setCode(_code);
|
|
164
|
+
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!vertexInput.hasAttribute('colorVI')) return;
|
|
169
|
+
var vDesc = pipeline.getShaderDescription('vertex');
|
|
170
|
+
vDesc.addOutput('vec4<f32>', 'color');
|
|
171
|
+
var code = vDesc.getCode();
|
|
172
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Color::Impl', [' output.color = colorVI;']).result;
|
|
173
|
+
vDesc.setCode(code);
|
|
174
|
+
var fDesc = pipeline.getShaderDescription('fragment');
|
|
175
|
+
code = fDesc.getCode();
|
|
176
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Color::Impl', ['ambientColor = input.color;', 'diffuseColor = input.color;', 'opacity = mapperUBO.Opacity * input.color.a;']).result;
|
|
177
|
+
fDesc.setCode(code);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
model.shaderReplacements.set('replaceShaderColor', publicAPI.replaceShaderColor);
|
|
181
|
+
|
|
182
|
+
publicAPI.replaceShaderTCoord = function (hash, pipeline, vertexInput) {
|
|
183
|
+
if (!vertexInput.hasAttribute('tcoord')) return;
|
|
184
|
+
var vDesc = pipeline.getShaderDescription('vertex');
|
|
185
|
+
vDesc.addOutput('vec2<f32>', 'tcoordVS');
|
|
186
|
+
var code = vDesc.getCode();
|
|
187
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::TCoord::Impl', [' output.tcoordVS = tcoord;']).result;
|
|
188
|
+
vDesc.setCode(code);
|
|
189
|
+
var fDesc = pipeline.getShaderDescription('fragment');
|
|
190
|
+
code = fDesc.getCode(); // todo handle multiple textures? Blend multiply ?
|
|
191
|
+
|
|
192
|
+
if (model.textures.length) {
|
|
193
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::TCoord::Impl', ['var tcolor: vec4<f32> = textureSample(Texture0, Texture0Sampler, input.tcoordVS);', 'computedColor = computedColor*tcolor;']).result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
fDesc.setCode(code);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
model.shaderReplacements.set('replaceShaderTCoord', publicAPI.replaceShaderTCoord);
|
|
200
|
+
|
|
201
|
+
publicAPI.replaceShaderSelect = function (hash, pipeline, vertexInput) {
|
|
202
|
+
if (hash.includes('sel')) {
|
|
203
|
+
var fDesc = pipeline.getShaderDescription('fragment');
|
|
204
|
+
var code = fDesc.getCode(); // by default there are no composites, so just 0
|
|
205
|
+
|
|
206
|
+
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Select::Impl', [' var compositeID: u32 = 0u;']).result;
|
|
207
|
+
fDesc.setCode(code);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
model.shaderReplacements.set('replaceShaderSelect', publicAPI.replaceShaderSelect);
|
|
212
|
+
|
|
213
|
+
publicAPI.getUsage = function (rep, i) {
|
|
214
|
+
if (rep === Representation.POINTS || i === PrimitiveTypes.Points) {
|
|
215
|
+
return BufferUsage.Verts;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (i === PrimitiveTypes.Lines) {
|
|
219
|
+
return BufferUsage.Lines;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (rep === Representation.WIREFRAME) {
|
|
223
|
+
if (i === PrimitiveTypes.Triangles) {
|
|
224
|
+
return BufferUsage.LinesFromTriangles;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return BufferUsage.LinesFromStrips;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (i === PrimitiveTypes.Triangles) {
|
|
231
|
+
return BufferUsage.Triangles;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (i === PrimitiveTypes.TriangleStrips) {
|
|
235
|
+
return BufferUsage.Strips;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (i === PrimitiveTypes.TriangleEdges) {
|
|
239
|
+
return BufferUsage.LinesFromTriangles;
|
|
240
|
+
} // only strip edges left which are lines
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
return BufferUsage.LinesFromStrips;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
publicAPI.getHashFromUsage = function (usage) {
|
|
247
|
+
return "pt".concat(usage);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
publicAPI.getTopologyFromUsage = function (usage) {
|
|
251
|
+
switch (usage) {
|
|
252
|
+
case BufferUsage.Triangles:
|
|
253
|
+
return 'triangle-list';
|
|
254
|
+
|
|
255
|
+
case BufferUsage.Verts:
|
|
256
|
+
return 'point-list';
|
|
257
|
+
|
|
258
|
+
case BufferUsage.Lines:
|
|
259
|
+
default:
|
|
260
|
+
return 'line-list';
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
publicAPI.buildVertexInput = function () {
|
|
265
|
+
var pd = model.currentInput;
|
|
266
|
+
var cells = model.cellArray;
|
|
267
|
+
var primType = model.primitiveType;
|
|
268
|
+
var actor = model.WebGPUActor.getRenderable();
|
|
269
|
+
var representation = actor.getProperty().getRepresentation();
|
|
270
|
+
var device = model.WebGPURenderWindow.getDevice();
|
|
271
|
+
var edges = false;
|
|
272
|
+
|
|
273
|
+
if (primType === PrimitiveTypes.TriangleEdges) {
|
|
274
|
+
edges = true;
|
|
275
|
+
representation = Representation.WIREFRAME;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
var vertexInput = model.vertexInput;
|
|
279
|
+
var hash = "R".concat(representation, "P").concat(primType); // hash = all things that can change the values on the buffer
|
|
280
|
+
// since mtimes are unique we can use
|
|
281
|
+
// - cells mtime - because cells drive how we pack
|
|
282
|
+
// - rep (point/wireframe/surface) - again because of packing
|
|
283
|
+
// - relevant dataArray mtime - the source data
|
|
284
|
+
// - shift - not currently captured
|
|
285
|
+
// - scale - not currently captured
|
|
286
|
+
// - format
|
|
287
|
+
// - usage
|
|
288
|
+
// - packExtra - covered by format
|
|
289
|
+
// - prim type (vert/lines/polys/strips) - covered by cells mtime
|
|
290
|
+
// points
|
|
291
|
+
|
|
292
|
+
var points = pd.getPoints();
|
|
293
|
+
|
|
294
|
+
if (points) {
|
|
295
|
+
var shift = model.WebGPUActor.getBufferShift(model.WebGPURenderer);
|
|
296
|
+
var buffRequest = {
|
|
297
|
+
hash: "".concat(hash).concat(points.getMTime()).concat(cells.getMTime()).concat(shift.join(), "float32x4"),
|
|
298
|
+
usage: BufferUsage.PointArray,
|
|
299
|
+
format: 'float32x4',
|
|
300
|
+
dataArray: points,
|
|
301
|
+
cells: cells,
|
|
302
|
+
primitiveType: primType,
|
|
303
|
+
representation: representation,
|
|
304
|
+
shift: shift,
|
|
305
|
+
packExtra: true
|
|
306
|
+
};
|
|
307
|
+
var buff = device.getBufferManager().getBuffer(buffRequest);
|
|
308
|
+
vertexInput.addBuffer(buff, ['vertexBC']);
|
|
309
|
+
} else {
|
|
310
|
+
vertexInput.removeBufferIfPresent('vertexBC');
|
|
311
|
+
} // normals, only used for surface rendering
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
var usage = publicAPI.getUsage(representation, primType);
|
|
315
|
+
|
|
316
|
+
if (usage === BufferUsage.Triangles || usage === BufferUsage.Strips) {
|
|
317
|
+
var normals = pd.getPointData().getNormals();
|
|
318
|
+
var _buffRequest = {
|
|
319
|
+
format: 'snorm8x4',
|
|
320
|
+
cells: cells,
|
|
321
|
+
representation: representation,
|
|
322
|
+
primitiveType: primType,
|
|
323
|
+
packExtra: true,
|
|
324
|
+
shift: 0,
|
|
325
|
+
scale: 127
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
if (normals) {
|
|
329
|
+
_buffRequest.hash = "".concat(hash).concat(normals.getMTime()).concat(cells.getMTime(), "snorm8x4");
|
|
330
|
+
_buffRequest.dataArray = normals;
|
|
331
|
+
_buffRequest.usage = BufferUsage.PointArray;
|
|
332
|
+
|
|
333
|
+
var _buff = device.getBufferManager().getBuffer(_buffRequest);
|
|
334
|
+
|
|
335
|
+
vertexInput.addBuffer(_buff, ['normalMC']);
|
|
336
|
+
} else if (primType === PrimitiveTypes.Triangles) {
|
|
337
|
+
_buffRequest.hash = "".concat(hash).concat(points.getMTime()).concat(cells.getMTime(), "snorm8x4");
|
|
338
|
+
_buffRequest.dataArray = points;
|
|
339
|
+
_buffRequest.usage = BufferUsage.NormalsFromPoints;
|
|
340
|
+
|
|
341
|
+
var _buff2 = device.getBufferManager().getBuffer(_buffRequest);
|
|
342
|
+
|
|
343
|
+
vertexInput.addBuffer(_buff2, ['normalMC']);
|
|
344
|
+
} else {
|
|
345
|
+
vertexInput.removeBufferIfPresent('normalMC');
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
vertexInput.removeBufferIfPresent('normalMC');
|
|
349
|
+
} // deal with colors but only if modified
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
var haveColors = false;
|
|
353
|
+
|
|
354
|
+
if (model.renderable.getScalarVisibility()) {
|
|
355
|
+
var c = model.renderable.getColorMapColors();
|
|
356
|
+
|
|
357
|
+
if (c && !edges) {
|
|
358
|
+
var scalarMode = model.renderable.getScalarMode();
|
|
359
|
+
var haveCellScalars = false; // We must figure out how the scalars should be mapped to the polydata.
|
|
360
|
+
|
|
361
|
+
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) {
|
|
362
|
+
haveCellScalars = true;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
var _buffRequest2 = {
|
|
366
|
+
usage: BufferUsage.PointArray,
|
|
367
|
+
format: 'unorm8x4',
|
|
368
|
+
hash: "".concat(hash).concat(haveCellScalars).concat(c.getMTime()).concat(cells.getMTime(), "unorm8x4"),
|
|
369
|
+
dataArray: c,
|
|
370
|
+
cells: cells,
|
|
371
|
+
primitiveType: primType,
|
|
372
|
+
representation: representation,
|
|
373
|
+
cellData: haveCellScalars,
|
|
374
|
+
cellOffset: 0
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
var _buff3 = device.getBufferManager().getBuffer(_buffRequest2);
|
|
378
|
+
|
|
379
|
+
vertexInput.addBuffer(_buff3, ['colorVI']);
|
|
380
|
+
haveColors = true;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (!haveColors) {
|
|
385
|
+
vertexInput.removeBufferIfPresent('colorVI');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
var tcoords = null;
|
|
389
|
+
|
|
390
|
+
if (model.renderable.getInterpolateScalarsBeforeMapping() && model.renderable.getColorCoordinates()) {
|
|
391
|
+
tcoords = model.renderable.getColorCoordinates();
|
|
392
|
+
} else {
|
|
393
|
+
tcoords = pd.getPointData().getTCoords();
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (tcoords && !edges) {
|
|
397
|
+
var _buff4 = device.getBufferManager().getBufferForPointArray(tcoords, cells, primType, representation);
|
|
398
|
+
|
|
399
|
+
vertexInput.addBuffer(_buff4, ['tcoord']);
|
|
400
|
+
} else {
|
|
401
|
+
vertexInput.removeBufferIfPresent('tcoord');
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
publicAPI.updateTextures = function () {
|
|
406
|
+
// we keep track of new and used textures so
|
|
407
|
+
// that we can clean up any unused textures so we don't hold onto them
|
|
408
|
+
var usedTextures = [];
|
|
409
|
+
var newTextures = []; // do we have a scalar color texture
|
|
410
|
+
|
|
411
|
+
var idata = model.renderable.getColorTextureMap(); // returns an imagedata
|
|
412
|
+
|
|
413
|
+
if (idata) {
|
|
414
|
+
if (!model.colorTexture) {
|
|
415
|
+
model.colorTexture = vtkTexture.newInstance({
|
|
416
|
+
label: 'polyDataColor'
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
model.colorTexture.setInputData(idata);
|
|
421
|
+
newTextures.push(model.colorTexture);
|
|
422
|
+
} // actor textures?
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
var actor = model.WebGPUActor.getRenderable();
|
|
426
|
+
var textures = actor.getTextures();
|
|
427
|
+
|
|
428
|
+
for (var i = 0; i < textures.length; i++) {
|
|
429
|
+
if (textures[i].getInputData() || textures[i].getJsImageData() || textures[i].getCanvas()) {
|
|
430
|
+
newTextures.push(textures[i]);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (textures[i].getImage() && textures[i].getImageLoaded()) {
|
|
434
|
+
newTextures.push(textures[i]);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
var usedCount = 0;
|
|
439
|
+
|
|
440
|
+
for (var _i = 0; _i < newTextures.length; _i++) {
|
|
441
|
+
var srcTexture = newTextures[_i];
|
|
442
|
+
var newTex = model.device.getTextureManager().getTextureForVTKTexture(srcTexture);
|
|
443
|
+
|
|
444
|
+
if (newTex.getReady()) {
|
|
445
|
+
// is this a new texture
|
|
446
|
+
var found = false;
|
|
447
|
+
|
|
448
|
+
for (var t = 0; t < model.textures.length; t++) {
|
|
449
|
+
if (model.textures[t] === newTex) {
|
|
450
|
+
usedCount++;
|
|
451
|
+
found = true;
|
|
452
|
+
usedTextures[t] = true;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (!found) {
|
|
457
|
+
usedTextures[model.textures.length] = true;
|
|
458
|
+
var tview = newTex.createView("Texture".concat(usedCount++));
|
|
459
|
+
model.textures.push(newTex);
|
|
460
|
+
model.textureViews.push(tview);
|
|
461
|
+
var interpolate = srcTexture.getInterpolate() ? 'linear' : 'nearest';
|
|
462
|
+
tview.addSampler(model.device, {
|
|
463
|
+
minFilter: interpolate,
|
|
464
|
+
magFilter: interpolate
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
} // remove unused textures
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
for (var _i2 = model.textures.length - 1; _i2 >= 0; _i2--) {
|
|
472
|
+
if (!usedTextures[_i2]) {
|
|
473
|
+
model.textures.splice(_i2, 1);
|
|
474
|
+
model.textureViews.splice(_i2, 1);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}; // compute a unique hash for a pipeline, this needs to be unique enough to
|
|
478
|
+
// capture any pipeline code changes (which includes shader changes)
|
|
479
|
+
// or vertex input changes/ bind groups/ etc
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
publicAPI.computePipelineHash = function () {
|
|
483
|
+
var pipelineHash = 'pd';
|
|
484
|
+
|
|
485
|
+
if (model.primitiveType === PrimitiveTypes.TriangleEdges || model.primitiveType === PrimitiveTypes.TriangleStripEdges) {
|
|
486
|
+
pipelineHash += 'edge';
|
|
487
|
+
} else {
|
|
488
|
+
if (model.vertexInput.hasAttribute("normalMC")) {
|
|
489
|
+
pipelineHash += "n";
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (model.vertexInput.hasAttribute("colorVI")) {
|
|
493
|
+
pipelineHash += "c";
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (model.vertexInput.hasAttribute("tcoord")) {
|
|
497
|
+
pipelineHash += "t";
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (model.textures.length) {
|
|
501
|
+
pipelineHash += "tx".concat(model.textures.length);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (model.SSBO) {
|
|
506
|
+
pipelineHash += "ssbo";
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
var uhash = publicAPI.getHashFromUsage(model.usage);
|
|
510
|
+
pipelineHash += uhash;
|
|
511
|
+
pipelineHash += model.renderEncoder.getPipelineHash();
|
|
512
|
+
model.pipelineHash = pipelineHash;
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
publicAPI.updateBuffers = function () {
|
|
516
|
+
// handle textures if not edges
|
|
517
|
+
if (model.primitiveType !== PrimitiveTypes.TriangleEdges && model.primitiveType !== PrimitiveTypes.TriangleStripEdges) {
|
|
518
|
+
publicAPI.updateTextures();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
var actor = model.WebGPUActor.getRenderable();
|
|
522
|
+
var rep = actor.getProperty().getRepresentation(); // handle per primitive type
|
|
523
|
+
|
|
524
|
+
model.usage = publicAPI.getUsage(rep, model.primitiveType);
|
|
525
|
+
publicAPI.buildVertexInput();
|
|
526
|
+
var vbo = model.vertexInput.getBuffer('vertexBC');
|
|
527
|
+
publicAPI.setNumberOfVertices(vbo.getSizeInBytes() / vbo.getStrideInBytes());
|
|
528
|
+
publicAPI.setTopology(publicAPI.getTopologyFromUsage(model.usage));
|
|
529
|
+
publicAPI.updateUBO();
|
|
530
|
+
|
|
531
|
+
if (publicAPI.haveWideLines()) {
|
|
532
|
+
var ppty = actor.getProperty();
|
|
533
|
+
publicAPI.setNumberOfInstances(Math.ceil(ppty.getLineWidth() * 2.0));
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
} // ----------------------------------------------------------------------------
|
|
537
|
+
// Object factory
|
|
538
|
+
// ----------------------------------------------------------------------------
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
var DEFAULT_VALUES = {
|
|
542
|
+
cellArray: null,
|
|
543
|
+
currentInput: null,
|
|
544
|
+
cellOffset: 0,
|
|
545
|
+
primitiveType: 0,
|
|
546
|
+
colorTexture: null,
|
|
547
|
+
renderEncoder: null,
|
|
548
|
+
textures: null
|
|
549
|
+
}; // ----------------------------------------------------------------------------
|
|
550
|
+
|
|
551
|
+
function extend(publicAPI, model) {
|
|
552
|
+
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
553
|
+
Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance
|
|
554
|
+
|
|
555
|
+
vtkWebGPUSimpleMapper.extend(publicAPI, model, initialValues);
|
|
556
|
+
model.fragmentShaderTemplate = vtkWebGPUPolyDataFS;
|
|
557
|
+
model.vertexShaderTemplate = vtkWebGPUPolyDataVS;
|
|
558
|
+
model._tmpMat3 = mat3.identity(new Float64Array(9));
|
|
559
|
+
model._tmpMat4 = mat4.identity(new Float64Array(16));
|
|
560
|
+
model.UBO = vtkWebGPUUniformBuffer.newInstance({
|
|
561
|
+
label: 'mapperUBO'
|
|
562
|
+
});
|
|
563
|
+
model.UBO.addEntry('BCWCMatrix', 'mat4x4<f32>');
|
|
564
|
+
model.UBO.addEntry('BCSCMatrix', 'mat4x4<f32>');
|
|
565
|
+
model.UBO.addEntry('MCWCNormals', 'mat4x4<f32>');
|
|
566
|
+
model.UBO.addEntry('AmbientColor', 'vec4<f32>');
|
|
567
|
+
model.UBO.addEntry('DiffuseColor', 'vec4<f32>');
|
|
568
|
+
model.UBO.addEntry('EdgeColor', 'vec4<f32>');
|
|
569
|
+
model.UBO.addEntry('SpecularColor', 'vec4<f32>');
|
|
570
|
+
model.UBO.addEntry('AmbientIntensity', 'f32');
|
|
571
|
+
model.UBO.addEntry('DiffuseIntensity', 'f32');
|
|
572
|
+
model.UBO.addEntry('SpecularIntensity', 'f32');
|
|
573
|
+
model.UBO.addEntry('LineWidth', 'f32');
|
|
574
|
+
model.UBO.addEntry('Opacity', 'f32');
|
|
575
|
+
model.UBO.addEntry('SpecularPower', 'f32');
|
|
576
|
+
model.UBO.addEntry('PropID', 'u32'); // Build VTK API
|
|
577
|
+
|
|
578
|
+
setGet(publicAPI, model, ['cellArray', 'currentInput', 'cellOffset', 'primitiveType', 'renderEncoder']);
|
|
579
|
+
model.textures = []; // Object methods
|
|
580
|
+
|
|
581
|
+
vtkWebGPUCellArrayMapper(publicAPI, model);
|
|
582
|
+
} // ----------------------------------------------------------------------------
|
|
583
|
+
|
|
584
|
+
var newInstance = newInstance$1(extend, 'vtkWebGPUCellArrayMapper'); // ----------------------------------------------------------------------------
|
|
585
|
+
|
|
586
|
+
var vtkWebGPUCellArrayMapper$1 = {
|
|
587
|
+
newInstance: newInstance,
|
|
588
|
+
extend: extend
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
export { vtkWebGPUCellArrayMapper$1 as default, extend, newInstance };
|