77
88import { createSystem , Entity , Types } from '../ecs/index.js' ;
99import { Mesh , Vector2 } from '../runtime/three.js' ;
10- import { DepthOccludable } from './depth-occludable.js' ;
10+ import { DepthOccludable , OcclusionShadersMode } from './depth-occludable.js' ;
1111import { DepthTextures } from './depth-textures.js' ;
1212import type { Shader , ShaderUniforms } from './types.js' ;
1313
@@ -65,7 +65,6 @@ export class DepthSensingSystem extends createSystem(
6565 private depthTextures ?: DepthTextures ;
6666
6767 // Occlusion
68- private occludableShaders = new Set < ShaderUniforms > ( ) ;
6968 private entityShaderMap = new Map < Entity , Set < ShaderUniforms > > ( ) ;
7069
7170 /**
@@ -139,21 +138,14 @@ export class DepthSensingSystem extends createSystem(
139138 }
140139 material . userData . shader = shader ;
141140 entityUniforms . add ( shader . uniforms ) ;
142- this . occludableShaders . add ( shader . uniforms ) ;
143141 } ;
144142 material . needsUpdate = true ;
145143 }
146144 } ) ;
147145 }
148146
149147 private detachOcclusionFromEntity ( entity : Entity ) : void {
150- const entityUniforms = this . entityShaderMap . get ( entity ) ;
151- if ( entityUniforms ) {
152- for ( const uniforms of entityUniforms ) {
153- this . occludableShaders . delete ( uniforms ) ;
154- }
155- this . entityShaderMap . delete ( entity ) ;
156- }
148+ this . entityShaderMap . delete ( entity ) ;
157149 }
158150
159151 /**
@@ -172,6 +164,7 @@ export class DepthSensingSystem extends createSystem(
172164 shader . uniforms . uDepthNear = { value : 0 } ;
173165 shader . uniforms . uViewportSize = { value : new Vector2 ( ) } ;
174166 shader . uniforms . uOcclusionBlurRadius = { value : 20.0 } ;
167+ shader . uniforms . uOcclusionHardMode = { value : false } ;
175168
176169 shader . defines = {
177170 ...( shader . defines ?? { } ) ,
@@ -205,6 +198,7 @@ export class DepthSensingSystem extends createSystem(
205198 'uniform float uDepthNear;' ,
206199 'uniform vec2 uViewportSize;' ,
207200 'uniform float uOcclusionBlurRadius;' ,
201+ 'uniform bool uOcclusionHardMode;' ,
208202 'varying float vOcclusionViewDepth;' ,
209203 '' ,
210204 'uniform sampler2DArray uXRDepthTextureArray;' ,
@@ -235,25 +229,30 @@ export class DepthSensingSystem extends createSystem(
235229 'if (occlusionEnabled) {' ,
236230 ' vec2 screenUV = gl_FragCoord.xy / uViewportSize;' ,
237231 ' vec2 depthUV = uIsGPUDepth ? screenUV : vec2(screenUV.x, 1.0 - screenUV.y);' ,
238- ' vec2 texelSize = uOcclusionBlurRadius / uViewportSize;' ,
239- ' // 13-tap two-ring sampling pattern for smooth occlusion edges' ,
240- ' // Center sample' ,
241- ' float occlusion_value = OcclusionGetSample(depthUV, vec2(0.0));' ,
242- ' // Inner ring: 6 samples at 40% radius, 60 degree intervals' ,
243- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.4, 0.0));' ,
244- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.2, 0.346));' ,
245- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.2, 0.346));' ,
246- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.4, 0.0));' ,
247- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.2, -0.346));' ,
248- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.2, -0.346));' ,
249- ' // Outer ring: 6 samples at full radius, offset 30 degrees' ,
250- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.866, 0.5));' ,
251- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.0, 1.0));' ,
252- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.866, 0.5));' ,
253- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.866, -0.5));' ,
254- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.0, -1.0));' ,
255- ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.866, -0.5));' ,
256- ' occlusion_value /= 13.0;' ,
232+ ' float occlusion_value;' ,
233+ ' if (uOcclusionHardMode) {' ,
234+ ' occlusion_value = OcclusionGetSample(depthUV, vec2(0.0));' ,
235+ ' } else {' ,
236+ ' vec2 texelSize = uOcclusionBlurRadius / uViewportSize;' ,
237+ ' // 13-tap two-ring sampling pattern for smooth occlusion edges' ,
238+ ' // Center sample' ,
239+ ' occlusion_value = OcclusionGetSample(depthUV, vec2(0.0));' ,
240+ ' // Inner ring: 6 samples at 40% radius, 60 degree intervals' ,
241+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.4, 0.0));' ,
242+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.2, 0.346));' ,
243+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.2, 0.346));' ,
244+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.4, 0.0));' ,
245+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.2, -0.346));' ,
246+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.2, -0.346));' ,
247+ ' // Outer ring: 6 samples at full radius, offset 30 degrees' ,
248+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.866, 0.5));' ,
249+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.0, 1.0));' ,
250+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.866, 0.5));' ,
251+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2(-0.866, -0.5));' ,
252+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.0, -1.0));' ,
253+ ' occlusion_value += OcclusionGetSample(depthUV, texelSize * vec2( 0.866, -0.5));' ,
254+ ' occlusion_value /= 13.0;' ,
255+ ' }' ,
257256 ' diffuseColor.a *= occlusion_value;' ,
258257 '}' ,
259258 ] . join ( '\n' ) ,
@@ -376,14 +375,21 @@ export class DepthSensingSystem extends createSystem(
376375 const viewportSize = new Vector2 ( ) ;
377376 this . renderer . getDrawingBufferSize ( viewportSize ) ;
378377
379- for ( const uniforms of this . occludableShaders ) {
380- uniforms . uXRDepthTextureArray . value = depthTextureArray ;
381- uniforms . uRawValueToMeters . value = this . rawValueToMeters ;
382- uniforms . uIsGPUDepth . value = isGPUDepth ;
383- uniforms . uDepthNear . value = depthNear ;
384- ( uniforms . uViewportSize . value as Vector2 ) . copy ( viewportSize ) ;
385- uniforms . uOcclusionBlurRadius . value = this . config . blurRadius . value ;
386- uniforms . occlusionEnabled . value = this . config . enableOcclusion . value ;
378+ for ( const [ entity , entityUniforms ] of this . entityShaderMap ) {
379+ const isHardMode =
380+ DepthOccludable . data . mode [ entity . index ] ===
381+ OcclusionShadersMode . HardOcclusion ;
382+
383+ for ( const uniforms of entityUniforms ) {
384+ uniforms . uXRDepthTextureArray . value = depthTextureArray ;
385+ uniforms . uRawValueToMeters . value = this . rawValueToMeters ;
386+ uniforms . uIsGPUDepth . value = isGPUDepth ;
387+ uniforms . uDepthNear . value = depthNear ;
388+ ( uniforms . uViewportSize . value as Vector2 ) . copy ( viewportSize ) ;
389+ uniforms . uOcclusionBlurRadius . value = this . config . blurRadius . value ;
390+ uniforms . uOcclusionHardMode . value = isHardMode ;
391+ uniforms . occlusionEnabled . value = this . config . enableOcclusion . value ;
392+ }
387393 }
388394 }
389395}
0 commit comments