@@ -5,6 +5,20 @@ import {
55} from "three/examples/jsm/postprocessing/Pass.js" ;
66import * as OBC from "@thatopen/components" ;
77
8+ /**
9+ * The mode of the edge detection pass.
10+ */
11+ export enum EdgeDetectionPassMode {
12+ /**
13+ * Looks good, including LODs, but less performant.
14+ */
15+ DEFAULT ,
16+ /**
17+ * Doesn't include LODs, but much more performant.
18+ */
19+ GLOBAL ,
20+ }
21+
822export class EdgeDetectionPass extends Pass {
923 private _edgeMaterial : THREE . ShaderMaterial ;
1024 private _combineMaterial : THREE . ShaderMaterial ;
@@ -17,6 +31,19 @@ export class EdgeDetectionPass extends Pass {
1731 private _overrideMaterial : THREE . ShaderMaterial ;
1832 private _depthBiasStrength = 0.001 ; // Adjustable depth bias strength
1933
34+ private _mode = EdgeDetectionPassMode . DEFAULT ;
35+
36+ get mode ( ) {
37+ return this . _mode ;
38+ }
39+
40+ set mode ( value : EdgeDetectionPassMode ) {
41+ this . _mode = value ;
42+ const currentWorld = this . _renderer . currentWorld as OBC . World ;
43+ const scene = currentWorld ! . scene . three as THREE . Scene ;
44+ scene . traverse ( ( child ) => this . setMaterialToMesh ( child , false ) ) ;
45+ }
46+
2047 get width ( ) {
2148 return this . _edgeMaterial . uniforms . width . value ;
2249 }
@@ -201,11 +228,18 @@ export class EdgeDetectionPass extends Pass {
201228 currentScene . fog = null ;
202229 currentScene . background = null ;
203230
204- const previousOverrideMaterial = scene . overrideMaterial ;
205- scene . overrideMaterial = this . _overrideMaterial ;
206- renderer . setRenderTarget ( this . _vertexColorRenderTarget ) ;
207- renderer . render ( scene , currentWorld ! . camera . three ) ;
208- scene . overrideMaterial = previousOverrideMaterial ;
231+ if ( this . _mode === EdgeDetectionPassMode . DEFAULT ) {
232+ scene . traverse ( ( child ) => this . setMaterialToMesh ( child , true ) ) ;
233+ renderer . setRenderTarget ( this . _vertexColorRenderTarget ) ;
234+ renderer . render ( scene , currentWorld ! . camera . three ) ;
235+ scene . traverse ( ( child ) => this . setMaterialToMesh ( child , false ) ) ;
236+ } else if ( this . _mode === EdgeDetectionPassMode . GLOBAL ) {
237+ const previousOverrideMaterial = scene . overrideMaterial ;
238+ scene . overrideMaterial = this . _overrideMaterial ;
239+ renderer . setRenderTarget ( this . _vertexColorRenderTarget ) ;
240+ renderer . render ( scene , currentWorld ! . camera . three ) ;
241+ scene . overrideMaterial = previousOverrideMaterial ;
242+ }
209243
210244 currentScene . fog = prevFog ;
211245 currentScene . background = prevBackground ;
@@ -240,4 +274,27 @@ export class EdgeDetectionPass extends Pass {
240274 this . _edgeRenderTarget . dispose ( ) ;
241275 this . _vertexColorRenderTarget . dispose ( ) ;
242276 }
277+
278+ private setMaterialToMesh ( object : THREE . Object3D , apply : boolean ) {
279+ if ( ! ( "isMesh" in object ) ) {
280+ return ;
281+ }
282+
283+ const mesh = object as THREE . Mesh ;
284+
285+ if ( ! ( "geometry" in mesh ) ) {
286+ return ;
287+ }
288+
289+ if ( "isLODGeometry" in mesh . geometry ) {
290+ return ;
291+ }
292+
293+ if ( apply ) {
294+ mesh . userData . edgePassPreviousMaterial = mesh . material ;
295+ mesh . material = this . _overrideMaterial ;
296+ } else if ( "edgePassPreviousMaterial" in mesh . userData ) {
297+ mesh . material = mesh . userData . edgePassPreviousMaterial ;
298+ }
299+ }
243300}
0 commit comments