@@ -11,13 +11,18 @@ import vtkWebGPUShaderCache from 'vtk.js/Sources/Rendering/WebGPU/ShaderCache';
1111import vtkWebGPUUniformBuffer from 'vtk.js/Sources/Rendering/WebGPU/UniformBuffer' ;
1212import vtkWebGPUSimpleMapper from 'vtk.js/Sources/Rendering/WebGPU/SimpleMapper' ;
1313import vtkWebGPUTypes from 'vtk.js/Sources/Rendering/WebGPU/Types' ;
14+ import {
15+ addClipPlaneEntries ,
16+ getClippingPlaneEquationsInCoords ,
17+ getClipPlaneShaderChecks ,
18+ MAX_CLIPPING_PLANES ,
19+ } from 'vtk.js/Sources/Rendering/WebGPU/Helpers/ClippingPlanes' ;
1420
1521const { BufferUsage, PrimitiveTypes } = vtkWebGPUBufferManager ;
1622const { Representation } = vtkProperty ;
1723const { ScalarMode } = vtkMapper ;
1824const { CoordinateSystem } = vtkProp ;
1925const { DisplayLocation } = vtkProperty2D ;
20-
2126const vtkWebGPUPolyDataVS = `
2227//VTK::Renderer::Dec
2328
@@ -380,6 +385,8 @@ fn main(
380385}
381386` ;
382387
388+ const tmp2Mat4 = new Float64Array ( 16 ) ;
389+
383390function isEdges ( hash ) {
384391 // edge pipelines have "edge" in them
385392 return hash . indexOf ( 'edge' ) >= 0 ;
@@ -432,13 +439,15 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
432439 publicAPI . updateUBO = ( ) => {
433440 const actor = model . WebGPUActor . getRenderable ( ) ;
434441 const ppty = actor . getProperty ( ) ;
442+ const clippingPlanesMTime = model . renderable . getClippingPlanesMTime ( ) ;
435443 const backfaceProperty = actor . getBackfaceProperty ?. ( ) ?? ppty ;
436444 const utime = model . UBO . getSendTime ( ) ;
437445 if (
438446 publicAPI . getMTime ( ) <= utime &&
439447 ppty . getMTime ( ) <= utime &&
440448 backfaceProperty . getMTime ( ) <= utime &&
441- model . renderable . getMTime ( ) <= utime
449+ model . renderable . getMTime ( ) <= utime &&
450+ clippingPlanesMTime <= utime
442451 ) {
443452 return ;
444453 }
@@ -541,6 +550,28 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
541550 model . UBO . setValue ( 'LineWidth' , ppty . getLineWidth ( ) ) ;
542551 model . UBO . setValue ( 'Opacity' , ppty . getOpacity ( ) ) ;
543552 model . UBO . setValue ( 'PropID' , model . WebGPUActor . getPropID ( ) ) ;
553+ model . UBO . setValue ( 'NumClipPlanes' , 0 ) ;
554+
555+ if ( ! model . is2D && model . useRendererMatrix ) {
556+ const center = model . WebGPURenderer . getStabilizedCenterByReference ( ) ;
557+ mat4 . fromTranslation ( tmp2Mat4 , [
558+ - center [ 0 ] ,
559+ - center [ 1 ] ,
560+ - center [ 2 ] ,
561+ ] ) ;
562+ const numClipPlanes = getClippingPlaneEquationsInCoords (
563+ model . renderable ,
564+ tmp2Mat4 ,
565+ model . clipPlanes
566+ ) ;
567+ model . UBO . setValue ( 'NumClipPlanes' , numClipPlanes ) ;
568+
569+ if ( numClipPlanes > 0 ) {
570+ for ( let i = 0 ; i < numClipPlanes ; i ++ ) {
571+ model . UBO . setArray ( `ClipPlane${ i } ` , model . clipPlanes [ i ] ) ;
572+ }
573+ }
574+ }
544575
545576 // Only send if needed
546577 model . UBO . sendIfNeeded ( model . WebGPURenderWindow . getDevice ( ) ) ;
@@ -586,9 +617,11 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
586617 const vDesc = pipeline . getShaderDescription ( 'vertex' ) ;
587618 vDesc . addBuiltinOutput ( 'vec4<f32>' , '@builtin(position) Position' ) ;
588619 if ( ! vDesc . hasOutput ( 'vertexVC' ) ) vDesc . addOutput ( 'vec4<f32>' , 'vertexVC' ) ;
620+ if ( ! vDesc . hasOutput ( 'vertexSC' ) ) vDesc . addOutput ( 'vec4<f32>' , 'vertexSC' ) ;
589621 let code = vDesc . getCode ( ) ;
590622 if ( model . useRendererMatrix ) {
591623 code = vtkWebGPUShaderCache . substitute ( code , '//VTK::Position::Impl' , [
624+ ' output.vertexSC = mapperUBO.BCSCMatrix * vec4<f32>(vertexBC.xyz, 1.0);' ,
592625 ' var pCoord: vec4<f32> = rendererUBO.SCPCMatrix*mapperUBO.BCSCMatrix*vertexBC;' ,
593626 ' output.vertexVC = rendererUBO.SCVCMatrix * mapperUBO.BCSCMatrix * vec4<f32>(vertexBC.xyz, 1.0);' ,
594627 '//VTK::Position::Impl' ,
@@ -635,6 +668,19 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
635668 ] ) . result ;
636669
637670 vDesc . setCode ( code ) ;
671+
672+ const fDesc = pipeline . getShaderDescription ( 'fragment' ) ;
673+ code = fDesc . getCode ( ) ;
674+ const clipPlaneChecks = getClipPlaneShaderChecks ( {
675+ countName : 'mapperUBO.NumClipPlanes' ,
676+ planePrefix : 'mapperUBO.ClipPlane' ,
677+ positionName : 'input.vertexSC' ,
678+ } ) ;
679+ code = vtkWebGPUShaderCache . substitute ( code , '//VTK::Position::Impl' , [
680+ ...clipPlaneChecks ,
681+ '//VTK::Position::Impl' ,
682+ ] ) . result ;
683+ fDesc . setCode ( code ) ;
638684 } ;
639685 model . shaderReplacements . set (
640686 'replaceShaderPosition' ,
@@ -1451,7 +1497,6 @@ export function extend(publicAPI, model, initiaLalues = {}) {
14511497 model . vertexShaderTemplate = vtkWebGPUPolyDataVS ;
14521498
14531499 model . _tmpMat3 = mat3 . identity ( new Float64Array ( 9 ) ) ;
1454- model . _tmpMat4 = mat4 . identity ( new Float64Array ( 16 ) ) ;
14551500
14561501 // UBO
14571502 model . UBO = vtkWebGPUUniformBuffer . newInstance ( { label : 'mapperUBO' } ) ;
@@ -1491,6 +1536,8 @@ export function extend(publicAPI, model, initiaLalues = {}) {
14911536 model . UBO . addEntry ( 'ClipNear' , 'f32' ) ;
14921537 model . UBO . addEntry ( 'ClipFar' , 'f32' ) ;
14931538 model . UBO . addEntry ( 'Time' , 'u32' ) ;
1539+ addClipPlaneEntries ( model . UBO , 'ClipPlane' ) ;
1540+ model . UBO . addEntry ( 'NumClipPlanes' , 'u32' ) ;
14941541
14951542 // Build VTK API
14961543 macro . setGet ( publicAPI , model , [
@@ -1503,6 +1550,9 @@ export function extend(publicAPI, model, initiaLalues = {}) {
15031550 ] ) ;
15041551
15051552 model . textures = [ ] ;
1553+ model . clipPlanes = Array . from ( { length : MAX_CLIPPING_PLANES } , ( ) => [
1554+ 0.0 , 0.0 , 0.0 , 0.0 ,
1555+ ] ) ;
15061556
15071557 // Object methods
15081558 vtkWebGPUCellArrayMapper ( publicAPI , model ) ;
0 commit comments