11import { mat3 , mat4 } from 'gl-matrix' ;
22
33import * as macro from 'vtk.js/Sources/macros' ;
4+ import CoincidentTopologyHelper from 'vtk.js/Sources/Rendering/Core/Mapper/CoincidentTopologyHelper' ;
45import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper' ;
56import vtkProp from 'vtk.js/Sources/Rendering/Core/Prop' ;
67import vtkProperty from 'vtk.js/Sources/Rendering/Core/Property' ;
@@ -12,6 +13,7 @@ import vtkWebGPUUniformBuffer from 'vtk.js/Sources/Rendering/WebGPU/UniformBuffe
1213import vtkWebGPUSimpleMapper from 'vtk.js/Sources/Rendering/WebGPU/SimpleMapper' ;
1314import vtkWebGPUTypes from 'vtk.js/Sources/Rendering/WebGPU/Types' ;
1415
16+ const { Resolve } = CoincidentTopologyHelper ;
1517const { BufferUsage, PrimitiveTypes } = vtkWebGPUBufferManager ;
1618const { Representation } = vtkProperty ;
1719const { ScalarMode } = vtkMapper ;
@@ -541,6 +543,9 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
541543 model . UBO . setValue ( 'LineWidth' , ppty . getLineWidth ( ) ) ;
542544 model . UBO . setValue ( 'Opacity' , ppty . getOpacity ( ) ) ;
543545 model . UBO . setValue ( 'PropID' , model . WebGPUActor . getPropID ( ) ) ;
546+ const cp = publicAPI . getCoincidentParameters ( ) ;
547+ model . UBO . setValue ( 'CoincidentFactor' , cp . factor ) ;
548+ model . UBO . setValue ( 'CoincidentOffset' , cp . offset ) ;
544549
545550 // Only send if needed
546551 model . UBO . sendIfNeeded ( model . WebGPURenderWindow . getDevice ( ) ) ;
@@ -582,6 +587,57 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
582587 } ,
583588 } ) ;
584589
590+ publicAPI . getCoincidentParameters = ( ) => {
591+ let cp = {
592+ factor : 0.0 ,
593+ offset : 0.0 ,
594+ } ;
595+
596+ const actor = model . WebGPUActor ?. getRenderable ( ) ;
597+ const prop = actor ?. getProperty ?. ( ) ;
598+ if ( ! prop ) {
599+ return cp ;
600+ }
601+
602+ if (
603+ // backwards compat with code that (errorneously) set this to boolean
604+ // eslint-disable-next-line eqeqeq
605+ model . renderable . getResolveCoincidentTopology ( ) ==
606+ Resolve . PolygonOffset ||
607+ ( prop . getEdgeVisibility ( ) &&
608+ prop . getRepresentation ( ) === Representation . SURFACE )
609+ ) {
610+ const primType = model . primitiveType ;
611+ if (
612+ primType === PrimitiveTypes . Verts ||
613+ prop . getRepresentation ( ) === Representation . POINTS
614+ ) {
615+ cp = model . renderable . getCoincidentTopologyPointOffsetParameter ( ) ;
616+ } else if (
617+ primType === PrimitiveTypes . Lines ||
618+ prop . getRepresentation ( ) === Representation . WIREFRAME
619+ ) {
620+ cp = model . renderable . getCoincidentTopologyLineOffsetParameters ( ) ;
621+ } else if (
622+ primType === PrimitiveTypes . Triangles ||
623+ primType === PrimitiveTypes . TriangleStrips
624+ ) {
625+ cp = model . renderable . getCoincidentTopologyPolygonOffsetParameters ( ) ;
626+ }
627+
628+ if (
629+ primType === PrimitiveTypes . TriangleEdges ||
630+ primType === PrimitiveTypes . TriangleStripEdges
631+ ) {
632+ cp = model . renderable . getCoincidentTopologyPolygonOffsetParameters ( ) ;
633+ cp . factor /= 2.0 ;
634+ cp . offset /= 2.0 ;
635+ }
636+ }
637+
638+ return cp ;
639+ } ;
640+
585641 publicAPI . replaceShaderPosition = ( hash , pipeline , vertexInput ) => {
586642 const vDesc = pipeline . getShaderDescription ( 'vertex' ) ;
587643 vDesc . addBuiltinOutput ( 'vec4<f32>' , '@builtin(position) Position' ) ;
@@ -631,16 +687,41 @@ function vtkWebGPUCellArrayMapper(publicAPI, model) {
631687 ] ) . result ;
632688 }
633689 code = vtkWebGPUShaderCache . substitute ( code , '//VTK::Position::Impl' , [
690+ ' pCoord.z = clamp(pCoord.z - 0.000016 * mapperUBO.CoincidentOffset * pCoord.w, 0.0, pCoord.w);' ,
634691 ' output.Position = pCoord;' ,
635692 ] ) . result ;
636-
637693 vDesc . setCode ( code ) ;
638694 } ;
639695 model . shaderReplacements . set (
640696 'replaceShaderPosition' ,
641697 publicAPI . replaceShaderPosition
642698 ) ;
643699
700+ publicAPI . replaceShaderCoincidentOffset = ( hash , pipeline , vertexInput ) => {
701+ const fDesc = pipeline . getShaderDescription ( 'fragment' ) ;
702+ if ( ! fDesc ) {
703+ return ;
704+ }
705+
706+ fDesc . addBuiltinInput ( 'vec4<f32>' , '@builtin(position) fragPos' ) ;
707+ fDesc . addBuiltinOutput ( 'f32' , '@builtin(frag_depth) fragDepth' ) ;
708+
709+ let code = fDesc . getCode ( ) ;
710+ code = vtkWebGPUShaderCache . substitute ( code , '//VTK::Position::Impl' , [
711+ ' var coincidentDepth: f32 = input.fragPos.z;' ,
712+ ' if (mapperUBO.CoincidentFactor != 0.0) {' ,
713+ ' let cscale = length(vec2<f32>(dpdx(input.fragPos.z), dpdy(input.fragPos.z)));' ,
714+ ' coincidentDepth = coincidentDepth - mapperUBO.CoincidentFactor * cscale;' ,
715+ ' }' ,
716+ ' output.fragDepth = clamp(coincidentDepth, 0.0, 1.0);' ,
717+ ] ) . result ;
718+ fDesc . setCode ( code ) ;
719+ } ;
720+ model . shaderReplacements . set (
721+ 'replaceShaderCoincidentOffset' ,
722+ publicAPI . replaceShaderCoincidentOffset
723+ ) ;
724+
644725 publicAPI . replaceShaderNormal = ( hash , pipeline , vertexInput ) => {
645726 const normalBuffer = vertexInput . getBuffer ( 'normalMC' ) ;
646727 const actor = model . WebGPUActor . getRenderable ( ) ;
@@ -1487,6 +1568,8 @@ export function extend(publicAPI, model, initiaLalues = {}) {
14871568 model . UBO . addEntry ( 'Opacity' , 'f32' ) ;
14881569 model . UBO . addEntry ( 'OpacityBF' , 'f32' ) ;
14891570 model . UBO . addEntry ( 'ZValue' , 'f32' ) ;
1571+ model . UBO . addEntry ( 'CoincidentFactor' , 'f32' ) ;
1572+ model . UBO . addEntry ( 'CoincidentOffset' , 'f32' ) ;
14901573 model . UBO . addEntry ( 'PropID' , 'u32' ) ;
14911574 model . UBO . addEntry ( 'ClipNear' , 'f32' ) ;
14921575 model . UBO . addEntry ( 'ClipFar' , 'f32' ) ;
0 commit comments