@kitware/vtk.js 25.2.3 → 25.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,8 +48,8 @@ In general VTK tries to be as portable as possible; the specific configurations
48
48
 
49
49
  vtk.js supports the following development environments:
50
50
 
51
- - Node 12+
52
- - NPM 6+
51
+ - Node 14+
52
+ - NPM 7+
53
53
 
54
54
  and we use [@babel/preset-env](https://www.npmjs.com/package/@babel/preset-env) with the [defaults](https://github.com/Kitware/vtk-js/blob/master/.browserslistrc) set of [browsers target](https://browserl.ist/?q=defaults).
55
55
  But when built from source this could be adjusted to support any browser as long they provide WebGL.
@@ -35,6 +35,10 @@ export interface IRendererInitialValues extends IViewportInitialValues {
35
35
  occlusionRatio?: number;
36
36
  maximumNumberOfPeels?: number;
37
37
  texturedBackground?: boolean;
38
+ environmentTexture?: vtkTexture;
39
+ environmentTextureDiffuseStrength?: number;
40
+ environmentTextureSpecularStrength?: number;
41
+ useEnvironmentTextureAsBackground?: boolean;
38
42
  pass?: number;
39
43
  }
40
44
 
@@ -115,7 +119,25 @@ export interface vtkRenderer extends vtkViewport {
115
119
  *
116
120
  * @default null
117
121
  */
118
- getBackgroundTexture(): vtkTexture;
122
+ getEnvironmentTexture(): vtkTexture;
123
+
124
+ /**
125
+ * Returns the diffuse strength of the set environment texture.
126
+ * @default 1
127
+ */
128
+ getEnvironmentTextureDiffuseStrength(): number;
129
+
130
+ /**
131
+ * Returns the specular strength of the set environment texture.
132
+ * @default 1
133
+ */
134
+ getEnvironmentTextureSpecularStrength(): number;
135
+
136
+ /**
137
+ * Gets whether or not the environment texture is being used as the background for the view.
138
+ * @default false
139
+ */
140
+ getUseEnvironmentTextureAsBackground(): boolean;
119
141
 
120
142
  /**
121
143
  *
@@ -347,9 +369,27 @@ export interface vtkRenderer extends vtkViewport {
347
369
 
348
370
  /**
349
371
  *
350
- * @param {vtkTexture} backgroundTexture
372
+ * @param {vtkTexture} environmentTexture
373
+ */
374
+ setEnvironmentTexture(environmentTexture: vtkTexture): boolean;
375
+
376
+ /**
377
+ * Sets the diffuse strength of the set environment texture.
378
+ * @param {number} diffuseStrength the new diffuse strength.
351
379
  */
352
- setBackgroundTexture(backgroundTexture: vtkTexture): boolean;
380
+ setEnvironmentTextureDiffuseStrength(diffuseStrength: number): boolean;
381
+
382
+ /**
383
+ * Sets the specular strength of the set environment texture.
384
+ * @param {number} specularStrength the new specular strength.
385
+ */
386
+ setEnvironmentTextureSpecularStrength(specularStrength: number): boolean;
387
+
388
+ /**
389
+ * Sets whether or not to use the environment texture as the background for the view.
390
+ * @param {number} textureAsBackground
391
+ */
392
+ setUseEnvironmentTextureAsBackground(textureAsBackground: boolean): boolean;
353
393
 
354
394
  /**
355
395
  *
@@ -593,6 +593,10 @@ var DEFAULT_VALUES = {
593
593
  delegate: null,
594
594
  texturedBackground: false,
595
595
  backgroundTexture: null,
596
+ environmentTexture: null,
597
+ environmentTextureDiffuseStrength: 1,
598
+ environmentTextureSpecularStrength: 1,
599
+ useEnvironmentTextureAsBackground: false,
596
600
  pass: 0
597
601
  }; // ----------------------------------------------------------------------------
598
602
 
@@ -611,7 +615,7 @@ function extend(publicAPI, model) {
611
615
  if (model.background.length === 3) model.background.push(1); // Build VTK API
612
616
 
613
617
  get(publicAPI, model, ['_renderWindow', 'allocatedRenderTime', 'timeFactor', 'lastRenderTimeInSeconds', 'numberOfPropsRendered', 'lastRenderingUsedDepthPeeling', 'selector']);
614
- setGet(publicAPI, model, ['twoSidedLighting', 'lightFollowCamera', 'automaticLightCreation', 'erase', 'draw', 'nearClippingPlaneTolerance', 'clippingRangeExpansion', 'backingStore', 'interactive', 'layer', 'preserveColorBuffer', 'preserveDepthBuffer', 'useDepthPeeling', 'occlusionRatio', 'maximumNumberOfPeels', 'delegate', 'backgroundTexture', 'texturedBackground', 'useShadows', 'pass']);
618
+ setGet(publicAPI, model, ['twoSidedLighting', 'lightFollowCamera', 'automaticLightCreation', 'erase', 'draw', 'nearClippingPlaneTolerance', 'clippingRangeExpansion', 'backingStore', 'interactive', 'layer', 'preserveColorBuffer', 'preserveDepthBuffer', 'useDepthPeeling', 'occlusionRatio', 'maximumNumberOfPeels', 'delegate', 'backgroundTexture', 'texturedBackground', 'environmentTexture', 'environmentTextureDiffuseStrength', 'environmentTextureSpecularStrength', 'useEnvironmentTextureAsBackground', 'useShadows', 'pass']);
615
619
  getArray(publicAPI, model, ['actors', 'volumes', 'lights']);
616
620
  setGetArray(publicAPI, model, ['background'], 4, 1.0);
617
621
  moveToProtected(publicAPI, model, ['renderWindow']); // Object methods
@@ -5,6 +5,7 @@ export interface ITextureInitialValues {
5
5
  interpolate?: boolean;
6
6
  edgeClamp?: boolean;
7
7
  imageLoaded?: boolean;
8
+ mipLevel?: number;
8
9
  }
9
10
 
10
11
  export interface vtkTexture extends vtkAlgorithm {
@@ -34,6 +35,11 @@ export interface vtkTexture extends vtkAlgorithm {
34
35
  */
35
36
  getImageLoaded(): boolean;
36
37
 
38
+ /**
39
+ *
40
+ */
41
+ getMipLevel(): number;
42
+
37
43
  /**
38
44
  *
39
45
  * @param repeat
@@ -62,6 +68,11 @@ export interface vtkTexture extends vtkAlgorithm {
62
68
  * @default null
63
69
  */
64
70
  setImage(image: any): void;
71
+
72
+ /**
73
+ * @param level
74
+ */
75
+ setMipLevel(level: number): boolean;
65
76
  }
66
77
 
67
78
  /**
@@ -79,6 +90,17 @@ export function extend(publicAPI: object, model: object, initialValues?: ITextur
79
90
  */
80
91
  export function newInstance(initialValues?: ITextureInitialValues): vtkTexture;
81
92
 
93
+ /**
94
+ * Method used to create mipmaps from given texture data. Works best with textures that have a
95
+ * width and a height that are powers of two.
96
+ *
97
+ * @param nativeArray the array of data to create mipmaps from.
98
+ * @param width the width of the data
99
+ * @param height the height of the data
100
+ * @param level the level to which additional mipmaps are generated.
101
+ */
102
+ export function generateMipmaps(nativeArray: any, width: number, height: number, level: number): Array<Uint8ClampedArray>;
103
+
82
104
  /**
83
105
  * vtkTexture is an image algorithm that handles loading and binding of texture maps.
84
106
  * It obtains its data from an input image data dataset type.
@@ -1,5 +1,10 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
1
3
  import macro from '../../macros.js';
2
4
 
5
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
6
+
7
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
3
8
  // vtkTexture methods
4
9
  // ----------------------------------------------------------------------------
5
10
 
@@ -103,19 +108,160 @@ function vtkTexture(publicAPI, model) {
103
108
  var dimensionality = (width > 1) + (height > 1) + (depth > 1);
104
109
  return dimensionality;
105
110
  };
106
- } // ----------------------------------------------------------------------------
111
+
112
+ publicAPI.getInputAsJsImageData = function () {
113
+ if (!model.imageLoaded || publicAPI.getInputData()) return null;
114
+
115
+ if (model.jsImageData) {
116
+ return model.jsImageData();
117
+ }
118
+
119
+ if (model.canvas) {
120
+ var context = model.canvas.getContext('2d');
121
+ var imageData = context.getImageData(0, 0, model.canvas.width, model.canvas.height);
122
+ return imageData;
123
+ }
124
+
125
+ if (model.image) {
126
+ var canvas = document.createElement('canvas');
127
+ canvas.width = model.image.width;
128
+ canvas.height = model.image.height;
129
+
130
+ var _context = canvas.getContext('2d');
131
+
132
+ _context.translate(0, canvas.height);
133
+
134
+ _context.scale(1, -1);
135
+
136
+ _context.drawImage(model.image, 0, 0, model.image.width, model.image.height);
137
+
138
+ var _imageData = _context.getImageData(0, 0, canvas.width, canvas.height);
139
+
140
+ return _imageData;
141
+ }
142
+
143
+ return null;
144
+ };
145
+ } // Use nativeArray instead of self
146
+
147
+
148
+ var generateMipmaps = function generateMipmaps(nativeArray, width, height, level) {
149
+ // TODO: FIX UNEVEN TEXTURE MIP GENERATION:
150
+ // When textures don't have standard ratios, higher mip levels
151
+ // result in their color chanels getting messed up and shifting
152
+ // 3x3 gaussian kernel
153
+ var g3m = [1, 2, 1]; // eslint-disable-line
154
+
155
+ var g3w = 4; // eslint-disable-line
156
+
157
+ var kernel = g3m;
158
+ var kernelWeight = g3w;
159
+ var hs = nativeArray.length / (width * height); // TODO: support for textures with depth more than 1
160
+
161
+ var currentWidth = width;
162
+ var currentHeight = height;
163
+ var imageData = nativeArray;
164
+ var maps = [imageData];
165
+
166
+ for (var i = 0; i < level; i++) {
167
+ var oldData = _toConsumableArray(imageData);
168
+
169
+ currentWidth /= 2;
170
+ currentHeight /= 2;
171
+ imageData = new Uint8ClampedArray(currentWidth * currentHeight * hs);
172
+ var vs = hs * currentWidth; // Scale down
173
+
174
+ var shift = 0;
175
+
176
+ for (var p = 0; p < imageData.length; p += hs) {
177
+ if (p % vs === 0) {
178
+ shift += 2 * hs * currentWidth;
179
+ }
180
+
181
+ for (var c = 0; c < hs; c++) {
182
+ var sample = oldData[shift + c];
183
+ sample += oldData[shift + hs + c];
184
+ sample += oldData[shift - 2 * vs + c];
185
+ sample += oldData[shift - 2 * vs + hs + c];
186
+ sample /= 4;
187
+ imageData[p + c] = sample;
188
+ }
189
+
190
+ shift += 2 * hs;
191
+ } // Horizontal Pass
192
+
193
+
194
+ var dataCopy = _toConsumableArray(imageData);
195
+
196
+ for (var _p = 0; _p < imageData.length; _p += hs) {
197
+ for (var _c = 0; _c < hs; _c++) {
198
+ var x = -(kernel.length - 1) / 2;
199
+ var kw = kernelWeight;
200
+ var value = 0.0;
201
+
202
+ for (var k = 0; k < kernel.length; k++) {
203
+ var index = _p + _c + x * hs;
204
+ var lineShift = index % vs - (_p + _c) % vs;
205
+ if (lineShift > hs) index += vs;
206
+ if (lineShift < -hs) index -= vs;
207
+
208
+ if (dataCopy[index]) {
209
+ value += dataCopy[index] * kernel[k];
210
+ } else {
211
+ kw -= kernel[k];
212
+ }
213
+
214
+ x += 1;
215
+ }
216
+
217
+ imageData[_p + _c] = value / kw;
218
+ }
219
+ } // Vertical Pass
220
+
221
+
222
+ dataCopy = _toConsumableArray(imageData);
223
+
224
+ for (var _p2 = 0; _p2 < imageData.length; _p2 += hs) {
225
+ for (var _c2 = 0; _c2 < hs; _c2++) {
226
+ var _x = -(kernel.length - 1) / 2;
227
+
228
+ var _kw = kernelWeight;
229
+ var _value = 0.0;
230
+
231
+ for (var _k = 0; _k < kernel.length; _k++) {
232
+ var _index = _p2 + _c2 + _x * vs;
233
+
234
+ if (dataCopy[_index]) {
235
+ _value += dataCopy[_index] * kernel[_k];
236
+ } else {
237
+ _kw -= kernel[_k];
238
+ }
239
+
240
+ _x += 1;
241
+ }
242
+
243
+ imageData[_p2 + _c2] = _value / _kw;
244
+ }
245
+ }
246
+
247
+ maps.push(imageData);
248
+ }
249
+
250
+ return maps;
251
+ }; // ----------------------------------------------------------------------------
107
252
  // Object factory
108
253
  // ----------------------------------------------------------------------------
109
254
 
110
255
 
111
256
  var DEFAULT_VALUES = {
112
- repeat: false,
113
- interpolate: false,
114
- edgeClamp: false,
115
257
  image: null,
116
258
  canvas: null,
259
+ jsImageData: null,
117
260
  imageLoaded: false,
118
- jsImageData: null
261
+ repeat: false,
262
+ interpolate: false,
263
+ edgeClamp: false,
264
+ mipLevel: 0
119
265
  }; // ----------------------------------------------------------------------------
120
266
 
121
267
  function extend(publicAPI, model) {
@@ -125,15 +271,18 @@ function extend(publicAPI, model) {
125
271
  macro.obj(publicAPI, model);
126
272
  macro.algo(publicAPI, model, 6, 0);
127
273
  macro.get(publicAPI, model, ['canvas', 'image', 'jsImageData', 'imageLoaded']);
128
- macro.setGet(publicAPI, model, ['repeat', 'edgeClamp', 'interpolate']);
274
+ macro.setGet(publicAPI, model, ['repeat', 'edgeClamp', 'interpolate', 'mipLevel']);
129
275
  vtkTexture(publicAPI, model);
130
276
  } // ----------------------------------------------------------------------------
131
277
 
132
- var newInstance = macro.newInstance(extend, 'vtkTexture'); // ----------------------------------------------------------------------------
278
+ var newInstance = macro.newInstance(extend, 'vtkTexture');
279
+ var STATIC = {
280
+ generateMipmaps: generateMipmaps
281
+ }; // ----------------------------------------------------------------------------
133
282
 
134
- var vtkTexture$1 = {
283
+ var vtkTexture$1 = _objectSpread({
135
284
  newInstance: newInstance,
136
285
  extend: extend
137
- };
286
+ }, STATIC);
138
287
 
139
- export { vtkTexture$1 as default, extend, newInstance };
288
+ export { STATIC, vtkTexture$1 as default, extend, newInstance };
@@ -94,6 +94,24 @@ export interface vtkVolumeMapper extends vtkAbstractMapper {
94
94
  */
95
95
  getAnisotropy(): number;
96
96
 
97
+ /**
98
+ * Get local ambient occlusion flag
99
+ * @default false
100
+ */
101
+ getLocalAmbientOcclusion(): boolean;
102
+
103
+ /**
104
+ * Get kernel size for local ambient occlusion
105
+ * @default 15
106
+ */
107
+ getLAOKernelSize(): number;
108
+
109
+ /**
110
+ * Get kernel radius for local ambient occlusion
111
+ * @default 7
112
+ */
113
+ getLAOKernelRadius(): number;
114
+
97
115
  /**
98
116
  *
99
117
  * @param x
@@ -186,7 +204,28 @@ export interface vtkVolumeMapper extends vtkAbstractMapper {
186
204
  * Value of -1.0 means light scatters backward, value of 1.0 means light scatters forward.
187
205
  * @param anisotropy
188
206
  */
189
- setAnisotropy(anisotropy: number): number;
207
+ setAnisotropy(anisotropy: number): void;
208
+
209
+ /**
210
+ * Set whether to turn on local ambient occlusion (LAO). LAO is only effective if shading is on and volumeScatterBlendCoef is set to 0.
211
+ * LAO effect is added to ambient lighting, so the ambient component of the actor needs to be great than 0.
212
+ * @param localAmbientOcclusion
213
+ */
214
+ setLocalAmbientOcclusion(localAmbientOcclusion: boolean): void;
215
+
216
+ /**
217
+ * Set kernel size for local ambient occlusion. It specifies the number of rays that are randomly sampled in the hemisphere.
218
+ * Value is clipped between 1 and 32.
219
+ * @param LAOKernelSize
220
+ */
221
+ setLAOKernelSize(LAOKernelSize: number): void;
222
+
223
+ /**
224
+ * Set kernel radius for local ambient occlusion. It specifies the number of samples that are considered on each random ray.
225
+ * Value must be greater than or equal to 1.
226
+ * @param LAOKernelRadius
227
+ */
228
+ setLAOKernelRadius(LAOKernelRadius: number): void;
190
229
 
191
230
  /**
192
231
  *
@@ -1,8 +1,12 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
1
2
  import macro from '../../macros.js';
2
- import { O as createUninitializedBounds, D as clampValue } from '../../Common/Core/Math/index.js';
3
+ import { O as createUninitializedBounds, D as clampValue, K as floor } from '../../Common/Core/Math/index.js';
3
4
  import Constants from './VolumeMapper/Constants.js';
4
5
  import vtkAbstractMapper from './AbstractMapper.js';
5
6
 
7
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
8
+
9
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
10
  var BlendMode = Constants.BlendMode,
7
11
  FilterMode = Constants.FilterMode; // ----------------------------------------------------------------------------
8
12
  // vtkVolumeMapper methods
@@ -12,6 +16,8 @@ function vtkVolumeMapper(publicAPI, model) {
12
16
  // Set our className
13
17
  model.classHierarchy.push('vtkVolumeMapper');
14
18
 
19
+ var superClass = _objectSpread({}, publicAPI);
20
+
15
21
  publicAPI.getBounds = function () {
16
22
  var input = publicAPI.getInputData();
17
23
 
@@ -78,23 +84,27 @@ function vtkVolumeMapper(publicAPI, model) {
78
84
  };
79
85
 
80
86
  publicAPI.setGlobalIlluminationReach = function (gl) {
81
- model.globalIlluminationReach = clampValue(gl, 0.0, 1.0);
82
- publicAPI.modified();
87
+ return superClass.setGlobalIlluminationReach(clampValue(gl, 0.0, 1.0));
83
88
  };
84
89
 
85
90
  publicAPI.setVolumetricScatteringBlending = function (vsb) {
86
- model.volumetricScatteringBlending = clampValue(vsb, 0.0, 1.0);
87
- publicAPI.modified();
91
+ return superClass.setVolumetricScatteringBlending(clampValue(vsb, 0.0, 1.0));
88
92
  };
89
93
 
90
94
  publicAPI.setVolumeShadowSamplingDistFactor = function (vsdf) {
91
- model.volumeShadowSamplingDistFactor = vsdf >= 1.0 ? vsdf : 1.0;
92
- publicAPI.modified();
95
+ return superClass.setVolumeShadowSamplingDistFactor(vsdf >= 1.0 ? vsdf : 1.0);
93
96
  };
94
97
 
95
98
  publicAPI.setAnisotropy = function (at) {
96
- model.anisotropy = clampValue(at, -0.99, 0.99);
97
- publicAPI.modified();
99
+ return superClass.setAnisotropy(clampValue(at, -0.99, 0.99));
100
+ };
101
+
102
+ publicAPI.setLAOKernelSize = function (ks) {
103
+ return superClass.setLAOKernelSize(floor(clampValue(ks, 1, 32)));
104
+ };
105
+
106
+ publicAPI.setLAOKernelRadius = function (kr) {
107
+ return superClass.setLAOKernelRadius(kr >= 1 ? kr : 1);
98
108
  };
99
109
  } // ----------------------------------------------------------------------------
100
110
  // Object factory
@@ -119,14 +129,18 @@ var DEFAULT_VALUES = {
119
129
  volumetricScatteringBlending: 0.0,
120
130
  globalIlluminationReach: 0.0,
121
131
  volumeShadowSamplingDistFactor: 5.0,
122
- anisotropy: 0.0
132
+ anisotropy: 0.0,
133
+ // local ambient occlusion
134
+ localAmbientOcclusion: false,
135
+ LAOKernelSize: 15,
136
+ LAOKernelRadius: 7
123
137
  }; // ----------------------------------------------------------------------------
124
138
 
125
139
  function extend(publicAPI, model) {
126
140
  var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
127
141
  Object.assign(model, DEFAULT_VALUES, initialValues);
128
142
  vtkAbstractMapper.extend(publicAPI, model, initialValues);
129
- macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy']);
143
+ macro.setGet(publicAPI, model, ['sampleDistance', 'imageSampleDistance', 'maximumSamplesPerRay', 'autoAdjustSampleDistances', 'blendMode', 'filterMode', 'preferSizeOverAccuracy', 'computeNormalFromOpacity', 'volumetricScatteringBlending', 'globalIlluminationReach', 'volumeShadowSamplingDistFactor', 'anisotropy', 'localAmbientOcclusion', 'LAOKernelSize', 'LAOKernelRadius']);
130
144
  macro.setGetArray(publicAPI, model, ['ipScalarRange'], 2);
131
145
  macro.event(publicAPI, model, 'lightingActivated'); // Object methods
132
146
 
@@ -151,6 +151,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
151
151
  if (model.renderable.getVolumetricScatteringBlending() < 1.0) {
152
152
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::SurfaceShadowOn', "#define SurfaceShadowOn").result;
153
153
  }
154
+
155
+ if (model.renderable.getVolumetricScatteringBlending() === 0.0 && model.renderable.getLocalAmbientOcclusion() && actor.getProperty().getAmbient() > 0.0) {
156
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::localAmbientOcclusionOn', "#define localAmbientOcclusionOn").result;
157
+ }
154
158
  } // if using gradient opacity define that
155
159
 
156
160
 
@@ -210,6 +214,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
210
214
  FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::VolumeShadow::Dec', ["uniform float volumetricScatteringBlending;", "uniform float giReach;", "uniform float volumeShadowSamplingDistFactor;", "uniform float anisotropy;", "uniform float anisotropy2;"], false).result;
211
215
  }
212
216
 
217
+ if (model.renderable.getVolumetricScatteringBlending() === 0.0 && model.renderable.getLocalAmbientOcclusion() && actor.getProperty().getAmbient() > 0.0) {
218
+ FSSource = vtkShaderProgram.substitute(FSSource, '//VTK::LAO::Dec', ["uniform int kernelRadius;", "uniform vec2 kernelSample[".concat(model.renderable.getLAOKernelRadius(), "];"), "uniform int kernelSize;"], false).result;
219
+ }
220
+
213
221
  shaders.Fragment = FSSource;
214
222
  };
215
223
 
@@ -617,6 +625,20 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
617
625
  program.setUniformf('anisotropy', model.renderable.getAnisotropy());
618
626
  program.setUniformf('anisotropy2', Math.pow(model.renderable.getAnisotropy(), 2.0));
619
627
  }
628
+
629
+ if (model.renderable.getVolumetricScatteringBlending() === 0.0 && model.renderable.getLocalAmbientOcclusion() && actor.getProperty().getAmbient() > 0.0) {
630
+ var ks = model.renderable.getLAOKernelSize();
631
+ program.setUniformi('kernelSize', ks);
632
+ var kernelSample = [];
633
+
634
+ for (var _i2 = 0; _i2 < ks; _i2++) {
635
+ kernelSample[_i2 * 2] = Math.random() * 0.5;
636
+ kernelSample[_i2 * 2 + 1] = Math.random() * 0.5;
637
+ }
638
+
639
+ program.setUniform2fv('kernelSample', kernelSample);
640
+ program.setUniformi('kernelRadius', model.renderable.getLAOKernelRadius());
641
+ }
620
642
  };
621
643
 
622
644
  publicAPI.setPropertyShaderParameters = function (cellBO, ren, actor) {
@@ -638,19 +660,19 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
638
660
  // for performance in the fragment shader
639
661
 
640
662
 
641
- for (var _i2 = 0; _i2 < numComp; _i2++) {
642
- var target = iComps ? _i2 : 0;
643
- var sscale = volInfo.scale[_i2];
663
+ for (var _i3 = 0; _i3 < numComp; _i3++) {
664
+ var target = iComps ? _i3 : 0;
665
+ var sscale = volInfo.scale[_i3];
644
666
  var ofun = vprop.getScalarOpacity(target);
645
667
  var oRange = ofun.getRange();
646
668
  var oscale = sscale / (oRange[1] - oRange[0]);
647
- var oshift = (volInfo.offset[_i2] - oRange[0]) / (oRange[1] - oRange[0]);
648
- program.setUniformf("oshift".concat(_i2), oshift);
649
- program.setUniformf("oscale".concat(_i2), oscale);
669
+ var oshift = (volInfo.offset[_i3] - oRange[0]) / (oRange[1] - oRange[0]);
670
+ program.setUniformf("oshift".concat(_i3), oshift);
671
+ program.setUniformf("oscale".concat(_i3), oscale);
650
672
  var cfun = vprop.getRGBTransferFunction(target);
651
673
  var cRange = cfun.getRange();
652
- program.setUniformf("cshift".concat(_i2), (volInfo.offset[_i2] - cRange[0]) / (cRange[1] - cRange[0]));
653
- program.setUniformf("cscale".concat(_i2), sscale / (cRange[1] - cRange[0]));
674
+ program.setUniformf("cshift".concat(_i3), (volInfo.offset[_i3] - cRange[0]) / (cRange[1] - cRange[0]));
675
+ program.setUniformf("cscale".concat(_i3), sscale / (cRange[1] - cRange[0]));
654
676
  }
655
677
 
656
678
  if (model.gopacity) {
@@ -1009,9 +1031,9 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1009
1031
  var oRange = ofun.getRange();
1010
1032
  ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1); // adjust for sample distance etc
1011
1033
 
1012
- for (var _i3 = 0; _i3 < oWidth; ++_i3) {
1013
- ofTable[c * oWidth * 2 + _i3] = 1.0 - Math.pow(1.0 - tmpTable[_i3], opacityFactor);
1014
- ofTable[c * oWidth * 2 + _i3 + oWidth] = ofTable[c * oWidth * 2 + _i3];
1034
+ for (var _i4 = 0; _i4 < oWidth; ++_i4) {
1035
+ ofTable[c * oWidth * 2 + _i4] = 1.0 - Math.pow(1.0 - tmpTable[_i4], opacityFactor);
1036
+ ofTable[c * oWidth * 2 + _i4 + oWidth] = ofTable[c * oWidth * 2 + _i4];
1015
1037
  }
1016
1038
  }
1017
1039
 
@@ -1027,8 +1049,8 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1027
1049
  } else {
1028
1050
  var _oTable = new Uint8Array(oSize);
1029
1051
 
1030
- for (var _i4 = 0; _i4 < oSize; ++_i4) {
1031
- _oTable[_i4] = 255.0 * ofTable[_i4];
1052
+ for (var _i5 = 0; _i5 < oSize; ++_i5) {
1053
+ _oTable[_i5] = 255.0 * ofTable[_i5];
1032
1054
  }
1033
1055
 
1034
1056
  model.opacityTexture.create2DFromRaw(oWidth, 2 * numIComps, 1, VtkDataTypes.UNSIGNED_CHAR, _oTable);
@@ -1052,9 +1074,9 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1052
1074
  var cRange = cfun.getRange();
1053
1075
  cfun.getTable(cRange[0], cRange[1], cWidth, _tmpTable, 1);
1054
1076
 
1055
- for (var _i5 = 0; _i5 < cWidth * 3; ++_i5) {
1056
- cTable[_c * cWidth * 6 + _i5] = 255.0 * _tmpTable[_i5];
1057
- cTable[_c * cWidth * 6 + _i5 + cWidth * 3] = 255.0 * _tmpTable[_i5];
1077
+ for (var _i6 = 0; _i6 < cWidth * 3; ++_i6) {
1078
+ cTable[_c * cWidth * 6 + _i6] = 255.0 * _tmpTable[_i6];
1079
+ cTable[_c * cWidth * 6 + _i6 + cWidth * 3] = 255.0 * _tmpTable[_i6];
1058
1080
  }
1059
1081
  }
1060
1082
 
@@ -1081,10 +1103,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1081
1103
  // build the CABO
1082
1104
  var ptsArray = new Float32Array(12);
1083
1105
 
1084
- for (var _i6 = 0; _i6 < 4; _i6++) {
1085
- ptsArray[_i6 * 3] = _i6 % 2 * 2 - 1.0;
1086
- ptsArray[_i6 * 3 + 1] = _i6 > 1 ? 1.0 : -1.0;
1087
- ptsArray[_i6 * 3 + 2] = -1.0;
1106
+ for (var _i7 = 0; _i7 < 4; _i7++) {
1107
+ ptsArray[_i7 * 3] = _i7 % 2 * 2 - 1.0;
1108
+ ptsArray[_i7 * 3 + 1] = _i7 > 1 ? 1.0 : -1.0;
1109
+ ptsArray[_i7 * 3 + 2] = -1.0;
1088
1110
  }
1089
1111
 
1090
1112
  var cellArray = new Uint16Array(8);