@@ -35,12 +35,8 @@ const { vtkWarningMacro, vtkErrorMacro } = macro;
35
35
// helper methods
36
36
// ----------------------------------------------------------------------------
37
37
38
- function computeFnToString ( property , pwfun , numberOfComponents ) {
39
- if ( pwfun ) {
40
- const iComps = property . getIndependentComponents ( ) ;
41
- return `${ pwfun . getMTime ( ) } -${ iComps } -${ numberOfComponents } ` ;
42
- }
43
- return '0' ;
38
+ function computeFnToString ( pwfun , useIComps , numberOfComponents ) {
39
+ return pwfun ? `${ pwfun . getMTime ( ) } -${ useIComps } -${ numberOfComponents } ` : '0' ;
44
40
}
45
41
46
42
function getColorCodeFromPreset ( colorMixPreset ) {
@@ -182,6 +178,17 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
182
178
shaders . Geometry = '' ;
183
179
} ;
184
180
181
+ publicAPI . useIndependentComponents = ( actor ) => {
182
+ const iComps = actor . getProperty ( ) . getIndependentComponents ( ) ;
183
+ const image = model . currentInput ;
184
+ const numComp = image
185
+ ?. getPointData ( )
186
+ ?. getScalars ( )
187
+ ?. getNumberOfComponents ( ) ;
188
+ const colorMixPreset = actor . getProperty ( ) . getColorMixPreset ( ) ;
189
+ return ( iComps && numComp >= 2 ) || ! ! colorMixPreset ;
190
+ } ;
191
+
185
192
publicAPI . replaceShaderValues = ( shaders , ren , actor ) => {
186
193
let FSSource = shaders . Fragment ;
187
194
@@ -211,12 +218,12 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
211
218
`#define vtkNumComponents ${ numComp } `
212
219
) . result ;
213
220
214
- const iComps = actor . getProperty ( ) . getIndependentComponents ( ) ;
215
- if ( iComps ) {
221
+ const useIndependentComps = publicAPI . useIndependentComponents ( actor ) ;
222
+ if ( useIndependentComps ) {
216
223
FSSource = vtkShaderProgram . substitute (
217
224
FSSource ,
218
225
'//VTK::IndependentComponentsOn' ,
219
- '#define vtkIndependentComponentsOn '
226
+ '#define UseIndependentComponents '
220
227
) . result ;
221
228
222
229
// Define any proportional components
@@ -282,11 +289,11 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
282
289
FSSource = vtkShaderProgram . substitute (
283
290
FSSource ,
284
291
'//VTK::LightComplexity' ,
285
- `#define vtkLightComplexity ${ model . lastLightComplexity } `
292
+ `#define vtkLightComplexity ${ model . lightComplexity } `
286
293
) . result ;
287
294
288
295
// set shadow blending flag
289
- if ( model . lastLightComplexity > 0 ) {
296
+ if ( model . lightComplexity > 0 ) {
290
297
if ( model . renderable . getVolumetricScatteringBlending ( ) > 0.0 ) {
291
298
FSSource = vtkShaderProgram . substitute (
292
299
FSSource ,
@@ -314,11 +321,10 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
314
321
}
315
322
316
323
// if using gradient opacity define that
317
- model . gopacity = actor . getProperty ( ) . getUseGradientOpacity ( 0 ) ;
318
- for ( let nc = 1 ; iComps && ! model . gopacity && nc < numComp ; ++ nc ) {
319
- if ( actor . getProperty ( ) . getUseGradientOpacity ( nc ) ) {
320
- model . gopacity = true ;
321
- }
324
+ const numIComps = useIndependentComps ? numComp : 1 ;
325
+ model . gopacity = false ;
326
+ for ( let nc = 0 ; ! model . gopacity && nc < numIComps ; ++ nc ) {
327
+ model . gopacity ||= actor . getProperty ( ) . getUseGradientOpacity ( nc ) ;
322
328
}
323
329
if ( model . gopacity ) {
324
330
FSSource = vtkShaderProgram . substitute (
@@ -371,7 +377,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
371
377
} ;
372
378
373
379
publicAPI . replaceShaderLight = ( shaders , ren , actor ) => {
374
- if ( model . lastLightComplexity === 0 ) {
380
+ if ( model . lightComplexity === 0 ) {
375
381
return ;
376
382
}
377
383
let FSSource = shaders . Fragment ;
@@ -401,7 +407,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
401
407
false
402
408
) . result ;
403
409
// support any number of lights
404
- if ( model . lastLightComplexity === 3 ) {
410
+ if ( model . lightComplexity === 3 ) {
405
411
FSSource = vtkShaderProgram . substitute (
406
412
FSSource ,
407
413
'//VTK::Light::Dec' ,
@@ -492,7 +498,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
492
498
shaders . Fragment = FSSource ;
493
499
} ;
494
500
495
- publicAPI . getNeedToRebuildShaders = ( cellBO , ren , actor ) => {
501
+ const recomputeLightComplexity = ( actor , lights ) => {
496
502
// do we need lighting?
497
503
let lightComplexity = 0 ;
498
504
if (
@@ -504,7 +510,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
504
510
lightComplexity = 0 ;
505
511
model . numberOfLights = 0 ;
506
512
507
- ren . getLights ( ) . forEach ( ( light ) => {
513
+ lights . forEach ( ( light ) => {
508
514
const status = light . getSwitch ( ) ;
509
515
if ( status > 0 ) {
510
516
model . numberOfLights ++ ;
@@ -526,26 +532,22 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
526
532
}
527
533
} ) ;
528
534
}
529
-
530
- let needRebuild = false ;
531
- if ( model . lastLightComplexity !== lightComplexity ) {
532
- model . lastLightComplexity = lightComplexity ;
533
- needRebuild = true ;
535
+ if ( lightComplexity !== model . lightComplexity ) {
536
+ model . lightComplexity = lightComplexity ;
537
+ publicAPI . modified ( ) ;
534
538
}
539
+ } ;
535
540
536
- const numComp = model . scalarTexture . getComponents ( ) ;
537
- const iComps = actor . getProperty ( ) . getIndependentComponents ( ) ;
538
- let usesProportionalComponents = false ;
539
- const proportionalComponents = [ ] ;
540
- if ( iComps ) {
541
- // Define any proportional components
542
- for ( let nc = 0 ; nc < numComp ; nc ++ ) {
543
- proportionalComponents . push ( actor . getProperty ( ) . getOpacityMode ( nc ) ) ;
544
- }
541
+ publicAPI . getNeedToRebuildShaders = ( cellBO , ren , actor ) => {
542
+ const actorProps = actor . getProperty ( ) ;
545
543
546
- if ( proportionalComponents . length > 0 ) {
547
- usesProportionalComponents = true ;
548
- }
544
+ recomputeLightComplexity ( actor , ren . getLights ( ) ) ;
545
+
546
+ const numComp = model . scalarTexture . getComponents ( ) ;
547
+ const iComps = actorProps . getIndependentComponents ( ) ;
548
+ const opacityModes = [ ] ;
549
+ for ( let nc = 0 ; nc < numComp ; nc ++ ) {
550
+ opacityModes . push ( actorProps . getOpacityMode ( nc ) ) ;
549
551
}
550
552
551
553
const ext = model . currentInput . getSpatialExtent ( ) ;
@@ -561,46 +563,38 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
561
563
const maxSamples =
562
564
vec3 . length ( vsize ) / publicAPI . getCurrentSampleDistance ( ren ) ;
563
565
566
+ const hasZBufferTexture = ! ! model . zBufferTexture ;
567
+
564
568
const state = {
565
- colorMixPreset : actor . getProperty ( ) . getColorMixPreset ( ) ,
566
- interpolationType : actor . getProperty ( ) . getInterpolationType ( ) ,
567
- useLabelOutline : actor . getProperty ( ) . getUseLabelOutline ( ) ,
569
+ colorMixPreset : actorProps . getColorMixPreset ( ) ,
570
+ interpolationType : actorProps . getInterpolationType ( ) ,
571
+ useLabelOutline : actorProps . getUseLabelOutline ( ) ,
568
572
numComp,
569
- usesProportionalComponents,
570
573
iComps,
571
574
maxSamples,
572
- useGradientOpacity : actor . getProperty ( ) . getUseGradientOpacity ( 0 ) ,
575
+ useGradientOpacity : actorProps . getUseGradientOpacity ( 0 ) ,
573
576
blendMode : model . renderable . getBlendMode ( ) ,
574
- proportionalComponents,
577
+ hasZBufferTexture,
578
+ opacityModes,
575
579
} ;
576
580
577
- // We only need to rebuild the shader if one of these variables has changed,
581
+ // We need to rebuild the shader if one of these variables has changed,
578
582
// since they are used in the shader template replacement step.
579
- if ( ! model . previousState || ! DeepEqual ( model . previousState , state ) ) {
580
- model . previousState = state ;
581
-
582
- return true ;
583
- }
584
-
585
- // has something changed that would require us to recreate the shader?
583
+ // We also need to rebuild if the shader source time is outdated.
586
584
if (
587
585
cellBO . getProgram ( ) ?. getHandle ( ) === 0 ||
588
- needRebuild ||
589
- model . lastHaveSeenDepthRequest !== model . haveSeenDepthRequest ||
590
- ! ! model . lastZBufferTexture !== ! ! model . zBufferTexture ||
591
586
cellBO . getShaderSourceTime ( ) . getMTime ( ) < publicAPI . getMTime ( ) ||
592
- cellBO . getShaderSourceTime ( ) . getMTime ( ) < model . renderable . getMTime ( )
587
+ cellBO . getShaderSourceTime ( ) . getMTime ( ) < model . renderable . getMTime ( ) ||
588
+ ! model . previousState ||
589
+ ! DeepEqual ( model . previousState , state )
593
590
) {
594
- model . lastZBufferTexture = model . zBufferTexture ;
591
+ model . previousState = state ;
595
592
return true ;
596
593
}
597
-
598
594
return false ;
599
595
} ;
600
596
601
597
publicAPI . updateShaders = ( cellBO , ren , actor ) => {
602
- model . lastBoundBO = cellBO ;
603
-
604
598
// has something changed that would require us to recreate the shader?
605
599
if ( publicAPI . getNeedToRebuildShaders ( cellBO , ren , actor ) ) {
606
600
const shaders = { Vertex : null , Fragment : null , Geometry : null } ;
@@ -931,7 +925,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
931
925
program . setUniformMatrix ( 'PCVCMatrix' , model . projectionToView ) ;
932
926
933
927
// handle lighting values
934
- if ( model . lastLightComplexity === 0 ) {
928
+ if ( model . lightComplexity === 0 ) {
935
929
return ;
936
930
}
937
931
let lightNum = 0 ;
@@ -966,7 +960,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
966
960
program . setUniform3fv ( 'lightDirectionVC' , lightDir ) ;
967
961
program . setUniform3fv ( 'lightHalfAngleVC' , halfAngle ) ;
968
962
969
- if ( model . lastLightComplexity === 3 ) {
963
+ if ( model . lightComplexity === 3 ) {
970
964
lightNum = 0 ;
971
965
const lightPositionVC = [ ] ;
972
966
const lightAttenuation = [ ] ;
@@ -1051,8 +1045,8 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1051
1045
1052
1046
// set the component mix when independent
1053
1047
const numComp = model . scalarTexture . getComponents ( ) ;
1054
- const iComps = actor . getProperty ( ) . getIndependentComponents ( ) ;
1055
- if ( iComps && numComp >= 2 ) {
1048
+ const useIndependentComps = publicAPI . useIndependentComponents ( actor ) ;
1049
+ if ( useIndependentComps ) {
1056
1050
for ( let i = 0 ; i < numComp ; i ++ ) {
1057
1051
program . setUniformf (
1058
1052
`mix${ i } ` ,
@@ -1064,7 +1058,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1064
1058
// three levels of shift scale combined into one
1065
1059
// for performance in the fragment shader
1066
1060
for ( let i = 0 ; i < numComp ; i ++ ) {
1067
- const target = iComps ? i : 0 ;
1061
+ const target = useIndependentComps ? i : 0 ;
1068
1062
const sscale = volInfo . scale [ i ] ;
1069
1063
const ofun = vprop . getScalarOpacity ( target ) ;
1070
1064
const oRange = ofun . getRange ( ) ;
@@ -1082,7 +1076,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1082
1076
}
1083
1077
1084
1078
if ( model . gopacity ) {
1085
- if ( iComps ) {
1079
+ if ( useIndependentComps ) {
1086
1080
for ( let nc = 0 ; nc < numComp ; ++ nc ) {
1087
1081
const sscale = volInfo . scale [ nc ] ;
1088
1082
const useGO = vprop . getUseGradientOpacity ( nc ) ;
@@ -1138,7 +1132,7 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1138
1132
program . setUniformf ( 'outlineOpacity' , labelOutlineOpacity ) ;
1139
1133
}
1140
1134
1141
- if ( model . lastLightComplexity > 0 ) {
1135
+ if ( model . lightComplexity > 0 ) {
1142
1136
program . setUniformf ( 'vAmbient' , vprop . getAmbient ( ) ) ;
1143
1137
program . setUniformf ( 'vDiffuse' , vprop . getDiffuse ( ) ) ;
1144
1138
program . setUniformf ( 'vSpecular' , vprop . getSpecular ( ) ) ;
@@ -1312,9 +1306,6 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1312
1306
model . scalarTexture . setMagnificationFilter ( Filter . LINEAR ) ;
1313
1307
}
1314
1308
1315
- // Bind the OpenGL, this is shared between the different primitive/cell types.
1316
- model . lastBoundBO = null ;
1317
-
1318
1309
// if we have a zbuffer texture then activate it
1319
1310
if ( model . zBufferTexture !== null ) {
1320
1311
model . zBufferTexture . activate ( ) ;
@@ -1519,13 +1510,17 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1519
1510
}
1520
1511
1521
1512
const numComp = scalars . getNumberOfComponents ( ) ;
1522
- const iComps = vprop . getIndependentComponents ( ) ;
1523
- const numIComps = iComps ? numComp : 1 ;
1513
+ const useIndependentComps = publicAPI . useIndependentComponents ( actor ) ;
1514
+ const numIComps = useIndependentComps ? numComp : 1 ;
1524
1515
1525
1516
const scalarOpacityFunc = vprop . getScalarOpacity ( ) ;
1526
1517
const opTex =
1527
1518
model . _openGLRenderWindow . getGraphicsResourceForObject ( scalarOpacityFunc ) ;
1528
- let toString = computeFnToString ( vprop , scalarOpacityFunc , numIComps ) ;
1519
+ let toString = computeFnToString (
1520
+ scalarOpacityFunc ,
1521
+ useIndependentComps ,
1522
+ numIComps
1523
+ ) ;
1529
1524
const reBuildOp =
1530
1525
! opTex . vtkObj ||
1531
1526
opTex . hash !== toString ||
@@ -1602,7 +1597,11 @@ function vtkOpenGLVolumeMapper(publicAPI, model) {
1602
1597
1603
1598
// rebuild color tfun?
1604
1599
const colorTransferFunc = vprop . getRGBTransferFunction ( ) ;
1605
- toString = computeFnToString ( vprop , colorTransferFunc , numIComps ) ;
1600
+ toString = computeFnToString (
1601
+ colorTransferFunc ,
1602
+ useIndependentComps ,
1603
+ numIComps
1604
+ ) ;
1606
1605
const cTex =
1607
1606
model . _openGLRenderWindow . getGraphicsResourceForObject ( colorTransferFunc ) ;
1608
1607
const reBuildC =
@@ -1841,7 +1840,7 @@ const DEFAULT_VALUES = {
1841
1840
targetXYF : 1.0 ,
1842
1841
zBufferTexture : null ,
1843
1842
lastZBufferTexture : null ,
1844
- lastLightComplexity : 0 ,
1843
+ lightComplexity : 0 ,
1845
1844
fullViewportTime : 1.0 ,
1846
1845
idxToView : null ,
1847
1846
idxNormalMatrix : null ,
0 commit comments