@hology/core 0.0.274 → 0.0.276

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/effects/sequence/sequence-player.d.ts +1 -0
  2. package/dist/effects/sequence/sequence-player.js +1 -1
  3. package/dist/gameplay/actors/builtin/components/index.d.ts +6 -0
  4. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  5. package/dist/gameplay/actors/builtin/components/primitive-mesh-component.d.ts +66 -0
  6. package/dist/gameplay/actors/builtin/components/primitive-mesh-component.js +4 -0
  7. package/dist/gameplay/actors/builtin/index.d.ts +6 -0
  8. package/dist/gameplay/actors/builtin/index.js +1 -1
  9. package/dist/gameplay/actors/builtin/light-actor.d.ts +54 -0
  10. package/dist/gameplay/actors/builtin/light-actor.js +4 -0
  11. package/dist/gameplay/actors/builtin/mesh-actor.d.ts +9 -0
  12. package/dist/gameplay/actors/builtin/mesh-actor.js +4 -0
  13. package/dist/gameplay/actors/factory.js +1 -1
  14. package/dist/gameplay/actors/index.d.ts +5 -0
  15. package/dist/gameplay/actors/index.js +1 -1
  16. package/dist/gameplay/index.d.ts +1 -0
  17. package/dist/gameplay/index.js +1 -1
  18. package/dist/gameplay/initiate.js +1 -1
  19. package/dist/gameplay/rendering-host.d.ts +1 -0
  20. package/dist/gameplay/rendering-host.js +1 -1
  21. package/dist/gameplay/services/asset-loader.d.ts +3 -0
  22. package/dist/gameplay/services/asset-loader.js +1 -1
  23. package/dist/gameplay/services/physics/physics-system.js +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1 -1
  26. package/dist/rendering/node-material-webgpu-resolver.d.ts +5 -1
  27. package/dist/rendering/node-material-webgpu-resolver.js +1 -1
  28. package/dist/rendering/post-process-color.d.ts +9 -0
  29. package/dist/rendering/post-process-color.js +4 -0
  30. package/dist/rendering/sdfgi-settings.d.ts +8 -0
  31. package/dist/rendering/sdfgi-settings.js +4 -0
  32. package/dist/rendering/sdfgi-surface-material.d.ts +8 -0
  33. package/dist/rendering/sdfgi-surface-material.js +4 -0
  34. package/dist/rendering/webgl-backend.d.ts +243 -9
  35. package/dist/rendering/webgl-backend.js +1 -1
  36. package/dist/rendering/webgpu-experimental-backend.d.ts +14 -3
  37. package/dist/rendering/webgpu-experimental-backend.js +1 -1
  38. package/dist/rendering.d.ts +56 -208
  39. package/dist/rendering.js +1 -1
  40. package/dist/scene/actor-material-parameters.d.ts +19 -0
  41. package/dist/scene/actor-material-parameters.js +4 -0
  42. package/dist/scene/actor-mesh-provider.d.ts +2 -0
  43. package/dist/scene/actor-mesh-provider.js +4 -0
  44. package/dist/scene/actor-mesh-renderer.d.ts +40 -0
  45. package/dist/scene/actor-mesh-renderer.js +4 -0
  46. package/dist/scene/asset-resource-loader.d.ts +2 -0
  47. package/dist/scene/asset-resource-loader.js +1 -1
  48. package/dist/scene/batched-mesh-2.js +1 -1
  49. package/dist/scene/custom-param-deserialize.js +1 -1
  50. package/dist/scene/custom-param-runtime-types.js +1 -1
  51. package/dist/scene/material-ref.d.ts +7 -0
  52. package/dist/scene/material-ref.js +4 -0
  53. package/dist/scene/materializer.d.ts +18 -0
  54. package/dist/scene/materializer.js +1 -1
  55. package/dist/scene/model.d.ts +4 -1
  56. package/dist/scene/model.js +1 -1
  57. package/dist/scene/runtime-bundled-backend-service.d.ts +1 -0
  58. package/dist/scene/runtime-bundled-backend-service.js +1 -1
  59. package/dist/scene/scene-data-service.js +1 -1
  60. package/dist/scene/scene-object-actor-conversion.d.ts +10 -0
  61. package/dist/scene/scene-object-actor-conversion.js +4 -0
  62. package/dist/shader/parameter.d.ts +5 -2
  63. package/dist/shader-nodes/particle.d.ts +2 -2
  64. package/dist/shader-nodes/surface-reflection.d.ts +1 -0
  65. package/dist/shader-nodes/surface-reflection.js +1 -1
  66. package/dist/test/actor-mesh-renderer.test.d.ts +2 -0
  67. package/dist/test/actor-mesh-renderer.test.js +4 -0
  68. package/dist/test/actor-persistence-runtime.test.js +1 -1
  69. package/dist/test/asset-resource-loader-converted-fbx.test.js +1 -1
  70. package/dist/test/asset-resource-loader-skinned-merge.test.js +1 -1
  71. package/dist/test/landscape-static-draw-sets.test.js +1 -1
  72. package/dist/test/node-material-webgpu-resolver.test.js +1 -1
  73. package/dist/test/physics-ray-object.test.js +1 -1
  74. package/dist/test/primitive-actors.test.d.ts +2 -0
  75. package/dist/test/primitive-actors.test.js +4 -0
  76. package/dist/test/rendering-host.test.js +1 -1
  77. package/dist/test/runtime-bundled-backend-service.test.d.ts +2 -0
  78. package/dist/test/runtime-bundled-backend-service.test.js +4 -0
  79. package/dist/test/scene-object-actor-conversion.test.d.ts +2 -0
  80. package/dist/test/scene-object-actor-conversion.test.js +4 -0
  81. package/dist/test/sdfgi-settings.test.d.ts +2 -0
  82. package/dist/test/sdfgi-settings.test.js +4 -0
  83. package/dist/test/shader-graph.test.js +1 -1
  84. package/dist/test/surface-reflection.test.js +1 -1
  85. package/dist/test/webgl-backend.test.d.ts +2 -0
  86. package/dist/test/webgl-backend.test.js +4 -0
  87. package/dist/utils/async.d.ts +2 -0
  88. package/dist/utils/async.js +1 -1
  89. package/dist/utils/mesh.js +1 -1
  90. package/package.json +3 -3
  91. package/tsconfig.tsbuildinfo +1 -1
@@ -4,8 +4,8 @@ import type { WorldEnvironmentState } from './environment.js';
4
4
  import type { RenderingBackendDriver } from './rendering-backend.js';
5
5
  import type { PostProcessEffectStage } from './post-process-effect.js';
6
6
  import type { DlssQualityMode } from './upscaling-pass.js';
7
- import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, FrameGraphBuilder, GTAOOptions, GTAOQuality, OutlineOptions, OutlineInstanceSelection, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, SSROptions, RendererFrameProfile, RendererSceneCapture, SMAAOptions, TemporalAAOptions, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
8
- export type { RendererFrameProfile, RendererSceneCapture, RendererSceneCaptureOptions, RendererSceneCapturePostProcessContext, GTAOOptions, GTAOQuality, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
7
+ import type { BloomOptions, ColorGradingOptions, DepthOfFieldOptions, FXAAOptions, FrameGraphBuilder, GTAOOptions, GTAOQuality, OutlineOptions, OutlineInstanceSelection, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, SSROptions, SDFGIOptions, SDFGIStats, RendererFrameProfile, RendererSceneCapture, SMAAOptions, TemporalAAOptions, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
8
+ export type { SDFGICascadeOptions, SDFGIOptions, SDFGIStats, RendererFrameProfile, RendererSceneCapture, RendererSceneCaptureOptions, RendererSceneCapturePostProcessContext, GTAOOptions, GTAOQuality, SSROptions, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, VolumetricFogOptions, VolumetricFogQuality } from '@hology/webgpu-renderer';
9
9
  type SupportedCamera = THREE.PerspectiveCamera | THREE.OrthographicCamera;
10
10
  export type AntiAliasingMode = 'off' | 'fxaa' | 'smaa' | 'taa';
11
11
  export type ExperimentalWebGpuRenderGraphExtension = ((graph: FrameGraphBuilder, color: string) => void) & {
@@ -23,6 +23,8 @@ export type WebGpuPresentationExtensionContext = {
23
23
  };
24
24
  export type WebGpuPresentationExtension = (context: WebGpuPresentationExtensionContext) => void;
25
25
  export interface ExperimentalWebGpuPostProcessingOptions {
26
+ /** Experimental world-space indirect diffuse lighting. Disabled by default. */
27
+ readonly sdfgi?: false | SDFGIOptions;
26
28
  /** Request native DLSS-SR when supported by the host. Falls back to TAA. */
27
29
  readonly nativeUpscaling?: false | {
28
30
  readonly method: 'dlss';
@@ -73,6 +75,7 @@ export interface ExperimentalWebGpuStaticDrawSet {
73
75
  readonly label: string;
74
76
  readonly drawCount: number;
75
77
  readonly instanceCount: number;
78
+ updateTransforms(): void;
76
79
  dispose(): void;
77
80
  }
78
81
  export interface WebGpuSceneCapabilitySummary {
@@ -111,6 +114,8 @@ export declare class ExperimentalWebGpuBackend implements RenderingBackendDriver
111
114
  private readonly antiAliasingState;
112
115
  private readonly directionalShadowState;
113
116
  private readonly nativeDlss;
117
+ private sdfgi;
118
+ private readonly createSDFGI;
114
119
  readonly kind: "webgpu";
115
120
  readonly canvas: HTMLCanvasElement;
116
121
  private renderScale;
@@ -138,6 +143,9 @@ export declare class ExperimentalWebGpuBackend implements RenderingBackendDriver
138
143
  setPresentationExtensions(extensions: Iterable<WebGpuPresentationExtension>): void;
139
144
  setEnableOutlines(enabled: boolean): void;
140
145
  setTiledLightingEnabled(enabled: boolean): void;
146
+ setSDFGIOptions(options: SDFGIOptions): void;
147
+ invalidateSDFGI(): void;
148
+ getSDFGIStats(): Readonly<SDFGIStats> | null;
141
149
  setDynamicBatchingEnabled(enabled: boolean): void;
142
150
  setSelectedObjects(objects: Iterable<THREE.Object3D>): void;
143
151
  setSelectedObjectInstances(selections: Iterable<OutlineInstanceSelection>): void;
@@ -156,10 +164,13 @@ export declare class ExperimentalWebGpuBackend implements RenderingBackendDriver
156
164
  */
157
165
  resetViewHistory(): void;
158
166
  compile(scene: THREE.Scene, camera: SupportedCamera): Promise<void>;
159
- createStaticDrawSet(root: THREE.Object3D, label: string, allowUnsortedLateDraws?: boolean, onUnsupported?: 'throw' | 'skip'): ExperimentalWebGpuStaticDrawSet | null;
167
+ createStaticDrawSet(root: THREE.Object3D, label: string, allowUnsortedLateDraws?: boolean, onUnsupported?: 'throw' | 'skip', mutableTransforms?: boolean): ExperimentalWebGpuStaticDrawSet | null;
160
168
  registerStaticSpatialObject(root: THREE.Object3D): import('@hology/webgpu-renderer').StaticSpatialObject;
161
169
  render(scene: THREE.Scene, camera: SupportedCamera, timeSeconds: number): void;
170
+ prepareSceneGeometry(scene: THREE.Scene, camera: SupportedCamera): Promise<void>;
171
+ renderPresentationOnly(extensions: Iterable<WebGpuPresentationExtension>): void;
162
172
  setMotionBlurOptions(options: MotionBlurOptions): void;
173
+ setSSROptions(options: SSROptions): void;
163
174
  setGTAOOptions(options: GTAOOptions): void;
164
175
  setAntiAliasingMode(mode: AntiAliasingMode): void;
165
176
  setGTAOQuality(quality: GTAOQuality): void;
@@ -1,4 +1,4 @@
1
- import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{configureWebGpuRuntimeBindings as i}from"./webgpu-runtime-bridge.js";import{float as n,varyingTransformed as r,vec4 as a}from"three-shader-graph";import{NodeShaderMaterial as o}from"../shader-nodes/index.js";import{sceneMapUniformName as s}from"../shader-nodes/scene-sample.js";import{depthUniformName as l}from"../shader-nodes/depth.js";import{MATERIAL_FLAG_ALPHA_TEST as d,MATERIAL_FLAG_RECEIVE_DECALS as c}from"../shader-nodes/material-flags.js";import{createMotionVectorOutput as h}from"./motion-vector-node.js";export class ExperimentalWebGpuBackend{constructor(e,t,i,n,r,a,o,s,l,d,c,h,u,p,m,g,f,v,S,b,P,x){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=i,this.gBufferFallbackSource=n,this.bloom=r,this.fxaa=a,this.smaa=o,this.gtao=s,this.ssr=l,this.taa=d,this.motionBlur=c,this.volumetricFog=h,this.colorGrading=u,this.depthOfField=p,this.outline=m,this.postProcessEffects=g,this.renderGraphExtensions=f,this.presentationExtensions=v,this.antiAliasingState=S,this.directionalShadowState=b,this.nativeDlss=P,this.kind="webgpu",this.renderScale=1,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.secondaryMotionPrepared=!1,this.canvas=x}static async probeAvailability(){if("undefined"==typeof navigator||!("gpu"in navigator))return{available:!1,reason:"The runtime does not expose navigator.gpu."};try{const e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return null==e?{available:!1,reason:"No WebGPU adapter is available."}:{available:!0,adapter:e}}catch(e){return{available:!1,reason:`Requesting a WebGPU adapter failed: ${e instanceof Error?e.message:String(e)}`}}}static async create(m={},g){const f=await import("@hology/webgpu-renderer");i({registerPipelineDiagnosticOrigin:f.registerPipelineDiagnosticOrigin,createComputeKernel:(e,t)=>new f.ComputeKernel(e,t),buildParticleLightingShaderHeader:f.buildParticleLightingShaderHeader});const v=document.createElement("canvas");v.dataset.hologyRenderer="webgpu-experimental";const S=new f.WGSLShaderMaterial({vertexShader:u,fragmentShader:p}),b=!1!==m.nativeUpscaling&&"dlss"===m.nativeUpscaling?.method,P=b?(await import("./native-dlss-upscaler.js")).createNativeDlssUpscaler(m.nativeUpscaling?.mode??"quality"):null,x=null!=P;S.side=f.DoubleSide;const w=f,y=null!=m.motionBlur&&!1!==m.motionBlur,D=!1!==m.gtao&&(null==m.gtao||!1!==m.gtao.temporal),M=!1!==m.volumetricFog&&(null==m.volumetricFog||!1!==m.volumetricFog.temporal),O=x?"off":b?"taa":null!=(E=m).antiAliasing?E.antiAliasing:null!=E.taa&&!1!==E.taa?"taa":null!=E.smaa&&!1!==E.smaa?"smaa":null!=E.fxaa&&!1!==E.fxaa?"fxaa":!1===E.taa?"off":"taa";var E;const F=null!=m.antiAliasing,C=y||D||M||(F||"taa"===O)||x;let L=null;const G=new t(w,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(n(e.alphaTest>0?d:0).add(!1===e.userData.receiveDecals?0:c)),a((e.outputNormal??r.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1)),...C?[h(e)]:[]]:void 0,e=>L?.getEnvironmentTexture(e)??e),R=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==G.resolve(R,"opaque"))throw S.dispose(),R.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const T=!1===m.gtao?null:new f.GTAOEffect({normalSpace:"view",...f.GTAO_PRESETS.high,...m.gtao??{}}),A=!1===m.ssr||null==m.ssr?null:new f.SSREffect({normalSpace:"view",resolutionScale:.5,...m.ssr??{}}),B=!1===m.bloom?null:new f.BloomEffect({threshold:1,strength:.9,radius:.2,...m.bloom??{}}),U=F||!1!==m.fxaa&&"fxaa"===O?new f.FXAAEffect(!1===m.fxaa?{}:m.fxaa):null,W=F||!1!==m.smaa&&"smaa"===O?new f.SMAAEffect(!1===m.smaa?{}:m.smaa):null,k=x||F||!1!==m.taa&&"taa"===O?new f.TemporalAAEffect({renderScale:1,...!1===m.taa?{}:m.taa}):null,V={mode:O},I=!1===m.motionBlur||null==m.motionBlur?null:new f.MotionBlurEffect(m.motionBlur),j=m.volumetricFog||void 0,N=!1===m.volumetricFog?null:new f.VolumetricFogEffect(void 0,{...f.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...j,temporal:!1!==j?.temporal&&{...f.VOLUMETRIC_FOG_PRESETS.high.temporal,...j?.temporal},blur:!1!==j?.blur&&{...!1===f.VOLUMETRIC_FOG_PRESETS.high.blur?{}:f.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...j?.blur}}),H=!1===m.colorGrading?null:new f.ColorGradingEffect({enabled:!1,...m.colorGrading??{}}),$=!1===m.depthOfField?null:new f.DepthOfFieldEffect({enabled:!1,...m.depthOfField??{}}),_=!1===m.outline?null:new f.OutlineEffect({enabled:!1,...m.outline??{}}),q=[],z=new WeakMap,J=new Set,K=[],Z=[],Q=(e,t,i)=>{let n=i;const r=q.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof o)){const e=`${t.id}:material`;J.has(e)||(J.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let i=z.get(t.material);null!=i&&i.version===t.material.version||(i={version:t.material.version,shader:G.compileFullscreen(t.material),diagnosticOrigin:{key:"post-process:"+String(t.material.userData.assetId??(t.material.name||t.material.uuid)),material:{name:t.material.name,uuid:t.material.uuid,version:t.material.version,assetId:t.material.userData.assetId,assetName:t.material.userData.assetName}}},z.set(t.material,i));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,diagnosticOrigin:i.diagnosticOrigin,shader:i.shader,inputOverrides:{[s]:n},outputs:r}),n=r}catch(e){const i=`${t.id}:compile:${t.material.version}`;J.has(i)||(J.add(i),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return n},X={enabled:!0},Y=new f.WebGpuRenderer({canvas:v,fallbackMaterial:S,materialResolver:(e,t)=>G.resolve(e,t),invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1,nativePostSubmit:P?.postSubmit,presentationOverlay:e=>{for(const t of Z)t(e)}});Y.setRenderScale("taa"===O?k?.renderScale??1:1),Y.setRenderGraphBuilder((e,t)=>{const i=new f.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=C?i.createColorTarget("hologyMotionVectors",{format:"rgba16float"}):null;for(const e of K)"beforeScene"===e.stage&&e(i,i.sceneColor);X.enabled&&i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let a=i.sceneColor;if(T?.enabled){const e=T.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});a=T.addCompositePass(i,a,e)}null!=A&&(a=A.addPasses(i,{sceneColor:a,depth:i.mainDepth,normalRoughness:n}));const o=new Set(K.flatMap(e=>e.getSceneTextureReads?.()??[]));i.addSceneTextureCopyPass(a,{sceneColor:o.has("sceneColorSnapshot"),sceneDepth:o.has("sceneDepthSnapshot")||q.some(e=>e.enabled&&null!=e.material.uniforms[l])}),i.addLatePass(a);for(const e of K)null!=e.stage&&"afterScene"!==e.stage||e(i,a);a=Q(i,"beforeFog",a),null!=N&&(a=N.addPasses(i,{sceneColor:a,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=I&&null!=r&&(a=I.addPass(i,a,r,i.mainDepth)),null!=B&&(a=B.addPass(i,a)),a=Q(i,"beforeOutline",a),null!=_&&(a=_.addPass(i,a)),a=Q(i,"beforeDepthOfField",a),null!=$&&(a=$.addPass(i,a,i.mainDepth)),a=Q(i,"beforeColorAdjustment",a),null!=H&&(a=H.addPass(i,a)),a=Q(i,"beforeAntiAliasing",a);let s="taa"===V.mode&&null!=k?k.addPass(i,a,i.mainDepth,r??void 0):a;"smaa"===V.mode&&null!=W?s=W.addPass(i,s):"fxaa"===V.mode&&null!=U&&(s=U.addPass(i,s)),s=Q(i,"beforeOutput",s);for(const e of K)"beforePresent"===e.stage&&e(i,s);!0===P?.enabled&&null!=r?P.addInputPass(i,s,r):i.present(s)});try{return await Y.initialize(g),L=new ExperimentalWebGpuBackend(Y,S,G,R,B,U,W,T,A,k,I,N,H,$,_,q,K,Z,V,X,P,v),L}catch(e){throw Y.destroy(),S.dispose(),G.dispose(),R.dispose(),T?.dispose(),W?.dispose(),I?.dispose(),N?.dispose(),_?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,i,n=1){const r=this.canvas.width,a=this.canvas.height;let o=Math.min(1,Math.max(.25,n));if(!0===this.nativeDlss?.enabled){const n=Math.max(1,Math.floor(e*i)),r=Math.max(1,Math.floor(t*i));o=this.nativeDlss.getRenderScale(n,r)}const s=o!==this.renderScale;this.renderScale=o,this.renderer.setRenderScale(o),this.taa?.setRenderScale(o),this.renderer.setSize(e,t,i),(s||this.canvas.width!==r||this.canvas.height!==a)&&this.resetViewHistory()}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}getDevice(){return this.renderer.getDevice()}createSceneCapture(e,t,i){return this.renderer.createSceneCapture(e,t,i)}setRenderGraphExtensions(e){this.renderGraphExtensions.length=0;for(const t of e)this.renderGraphExtensions.push(t)}setPresentationExtensions(e){this.presentationExtensions.length=0;for(const t of e)this.presentationExtensions.push(t)}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setTiledLightingEnabled(e){this.renderer.setTiledLightingEnabled(e)}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t)}setDirectionalShadowUpdateOptions(e){this.renderer.setDirectionalShadowUpdateOptions(e)}invalidateDirectionalShadows(){this.renderer.invalidateDirectionalShadows()}setDirectionalShadowOptions(e,t){this.directionalShadowState.enabled=e,this.renderer.setDirectionalShadowsEnabled(e),this.renderer.setDirectionalShadowMapSize(t)}setWorldEnvironment(e){if(null==e)return void this.nodeMaterialResolver.setWorldEnvironment(null);const t=this.getEnvironmentTexture(e.source);this.nodeMaterialResolver.setWorldEnvironment({texture:t,intensity:e.intensity})}getEnvironmentTexture(t){if(t.mapping===e.CubeUVReflectionMapping)return t;let i=this.pmremResults.get(t);return null==i&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),i=this.pmremGenerator.fromEquirectangular(t),this.pmremResults.set(t,i),this.ownedPmremResults.add(i)),i.texture}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.nativeDlss?.reset()}async compile(e,t){if(!this.secondaryMotionPrepared){let t=!1;e.traverse(e=>{const i=e.userData.secondaryMotion?.regions;Array.isArray(i)&&i.some(e=>e.enabled)&&(t=!0)});const i=this.renderer.getDevice();if(t&&i){const{prepareSecondaryMotionRuntime:e}=await import("../secondary-motion/runtime.js");e(i),this.secondaryMotionPrepared=!0}}await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t,i=!1,n="skip"){this.renderer.setHiZOcclusionCullingEnabled(!0);const r=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:n,allowUnsortedLateDraws:i});return 0===r.drawCount?(r.dispose(),null):r}registerStaticSpatialObject(e){return this.renderer.registerStaticSpatialObject(e)}render(e,t,i){const n="taa"===this.antiAliasingState.mode?this.taa:null;this.volumetricFog?.setScene(e),this.renderer.setMotionVectorProjection(t.projectionMatrix),this.motionBlur?.prepareCamera(t,this.canvas.width,this.canvas.height,i),this.motionBlur?.requiresRendererHistoryReset()&&(this.renderer.resetViewHistory(),this.gtao?.reset(),this.volumetricFog?.reset()),n?.prepareCamera(t,this.canvas.width,this.canvas.height),this.nativeDlss?.prepareFrame(t);const r=!0===this.nativeDlss?.enabled?this.nativeDlss.jitter:null;this.motionBlur?.setJitterUv(n?.currentJitterUv.x??(null==r?0:r.x/Math.max(1,this.canvas.width*this.renderScale)),n?.currentJitterUv.y??(null==r?0:-r.y/Math.max(1,this.canvas.height*this.renderScale))),null!=r&&this.renderer.setProjectionJitter(r.x,r.y);let a=!1;try{this.renderer.render(e,t,i),a=!0}finally{null!=r&&this.renderer.clearProjectionJitter(),n?.finishCamera(t),a&&this.motionBlur?.commitCamera(),a&&this.nativeDlss?.finishFrame(t)}}setMotionBlurOptions(e){null!=this.motionBlur&&Object.assign(this.motionBlur.options,e)}setGTAOOptions(e){this.gtao?.setOptions(e)}setAntiAliasingMode(e){e!==this.antiAliasingState.mode&&("taa"===e&&null==this.taa||"smaa"===e&&null==this.smaa||"fxaa"===e&&null==this.fxaa?console.warn(`[Hology WebGPU experiment] Anti-aliasing mode "${e}" was not initialized. Set webgpuPostProcessing.antiAliasing in the initial rendering configuration to enable runtime switching.`):(this.antiAliasingState.mode=e,this.resetTemporalHistory()))}setGTAOQuality(e){this.gtao?.applyPreset(e)}setVolumetricFogOptions(e){this.volumetricFog?.setOptions(e)}setVolumetricFogQuality(e){this.volumetricFog?.applyPreset(e)}pushMotionBlurOverride(e){return this.motionBlur?.pushOverride(e)??null}invalidateObjectMotion(e){this.renderer.invalidateObjectMotion(e)}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.renderer.resetViewHistory(),this.nativeDlss?.reset()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.nativeDlss?.dispose(),this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.motionBlur?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,i){const n={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void n.sprites++;if(e.isPoints)return void n.points++;if(e.isLine)return void n.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?n.batchedMeshes++:t.isInstancedMesh?n.instancedMeshes++:t.isSkinnedMesh?n.skinnedMeshes++:n.meshes++,null==t.geometry?.getAttribute("position")&&n.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&n.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===i?.canResolve(e);t||r||(n.materialsReplaced++,e.isShaderMaterial&&n.shaderMaterialsReplaced++)}}),n}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const u="\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",p="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, cutoffDistance: f32, decayExponent: f32) -> f32 {\n var distanceFalloff = 1.0 / max(pow(distanceToLight, decayExponent), 0.01);\n if (cutoffDistance > 0.0) {\n let ratio = distanceToLight / cutoffDistance;\n let cutoff = clamp(1.0 - ratio * ratio * ratio * ratio, 0.0, 1.0);\n distanceFalloff *= cutoff * cutoff;\n }\n return distanceFalloff;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index), rendererPointLightDecayForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index), rendererSpotLightDecayForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
1
+ import*as e from"three";import{NodeMaterialWebGpuResolver as t}from"./node-material-webgpu-resolver.js";import{configureWebGpuRuntimeBindings as i}from"./webgpu-runtime-bridge.js";import{float as n,varyingTransformed as r,vec4 as s}from"three-shader-graph";import{NodeShaderMaterial as a}from"../shader-nodes/index.js";import{sceneMapUniformName as o}from"../shader-nodes/scene-sample.js";import{surfaceReflectionStepsUniformName as l}from"../shader-nodes/surface-reflection.js";import{depthUniformName as d}from"../shader-nodes/depth.js";import{MATERIAL_FLAG_ALPHA_TEST as c,MATERIAL_FLAG_RECEIVE_DECALS as h}from"../shader-nodes/material-flags.js";import{createMotionVectorOutput as u}from"./motion-vector-node.js";export class ExperimentalWebGpuBackend{constructor(e,t,i,n,r,s,a,o,l,d,c,h,u,p,m,g,f,S,v,b,P,w,x,y){this.renderer=e,this.fallbackMaterial=t,this.nodeMaterialResolver=i,this.gBufferFallbackSource=n,this.bloom=r,this.fxaa=s,this.smaa=a,this.gtao=o,this.ssr=l,this.taa=d,this.motionBlur=c,this.volumetricFog=h,this.colorGrading=u,this.depthOfField=p,this.outline=m,this.postProcessEffects=g,this.renderGraphExtensions=f,this.presentationExtensions=S,this.antiAliasingState=v,this.directionalShadowState=b,this.nativeDlss=P,this.sdfgi=w,this.createSDFGI=x,this.kind="webgpu",this.renderScale=1,this.pmremGenerator=null,this.pmremResults=new WeakMap,this.ownedPmremResults=new Set,this.warnedUnsupportedPostProcessStages=new Set,this.secondaryMotionPrepared=!1,this.canvas=y}static async probeAvailability(){if("undefined"==typeof navigator||!("gpu"in navigator))return{available:!1,reason:"The runtime does not expose navigator.gpu."};try{const e=await navigator.gpu.requestAdapter({powerPreference:"high-performance"});return null==e?{available:!1,reason:"No WebGPU adapter is available."}:{available:!0,adapter:e}}catch(e){return{available:!1,reason:`Requesting a WebGPU adapter failed: ${e instanceof Error?e.message:String(e)}`}}}static async create(g={},f){const S=await import("@hology/webgpu-renderer");i({registerPipelineDiagnosticOrigin:S.registerPipelineDiagnosticOrigin,createComputeKernel:(e,t)=>new S.ComputeKernel(e,t),buildParticleLightingShaderHeader:S.buildParticleLightingShaderHeader});const v=document.createElement("canvas");v.dataset.hologyRenderer="webgpu-experimental";const b=new S.WGSLShaderMaterial({vertexShader:p,fragmentShader:m}),P=!1!==g.nativeUpscaling&&"dlss"===g.nativeUpscaling?.method,w=P?(await import("./native-dlss-upscaler.js")).createNativeDlssUpscaler(g.nativeUpscaling?.mode??"quality"):null,x=null!=w;b.side=S.DoubleSide;const y=S,D=null!=g.motionBlur&&!1!==g.motionBlur,F=!1!==g.gtao&&(null==g.gtao||!1!==g.gtao.temporal),O=!1!==g.volumetricFog&&(null==g.volumetricFog||!1!==g.volumetricFog.temporal),M=x?"off":P?"taa":null!=(C=g).antiAliasing?C.antiAliasing:null!=C.taa&&!1!==C.taa?"taa":null!=C.smaa&&!1!==C.smaa?"smaa":null!=C.fxaa&&!1!==C.fxaa?"fxaa":!1===C.taa?"off":"taa";var C;const E=null!=g.antiAliasing,G=D||F||O||(E||"taa"===M)||x;let L=null;const R=new t(y,(e,t)=>"opaque"===t?[e.outputColor.xyz.rgba(n(e.alphaTest>0?c:0).add(!1===e.userData.receiveDecals?0:h)),s((e.outputNormal??r.normal).multiplyScalar(.5).addScalar(.5),e.outputRoughness??n(1)),...G?[u(e)]:[]]:void 0,e=>L?.getEnvironmentTexture(e)??e),T=new e.MeshStandardMaterial({color:8688803,roughness:1});if(null==R.resolve(T,"opaque"))throw b.dispose(),T.dispose(),new Error("Failed to compile the WebGPU G-buffer fallback material.");const A=!1===g.gtao?null:new S.GTAOEffect({normalSpace:"view",...S.GTAO_PRESETS.high,...g.gtao??{}}),I=new S.SSREffect({normalSpace:"view",enabled:null!=g.ssr&&!1!==g.ssr,...g.ssr||{}}),B=!1===g.bloom?null:new S.BloomEffect({threshold:1,strength:.9,radius:.2,...g.bloom??{}}),U=E||!1!==g.fxaa&&"fxaa"===M?new S.FXAAEffect(!1===g.fxaa?{}:g.fxaa):null,k=E||!1!==g.smaa&&"smaa"===M?new S.SMAAEffect(!1===g.smaa?{}:g.smaa):null,V=x||E||!1!==g.taa&&"taa"===M?new S.TemporalAAEffect({renderScale:1,...!1===g.taa?{}:g.taa}):null,W={mode:M},j=!1===g.motionBlur||null==g.motionBlur?null:new S.MotionBlurEffect(g.motionBlur),N=g.volumetricFog||void 0,H=!1===g.volumetricFog?null:new S.VolumetricFogEffect(void 0,{...S.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...N,temporal:!1!==N?.temporal&&{...S.VOLUMETRIC_FOG_PRESETS.high.temporal,...N?.temporal},blur:!1!==N?.blur&&{...!1===S.VOLUMETRIC_FOG_PRESETS.high.blur?{}:S.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...N?.blur}}),$=!1===g.colorGrading?null:new S.ColorGradingEffect({enabled:!1,...g.colorGrading??{}}),_=!1===g.depthOfField?null:new S.DepthOfFieldEffect({enabled:!1,...g.depthOfField??{}}),q=!1===g.outline?null:new S.OutlineEffect({enabled:!1,...g.outline??{}}),z=[],J=new WeakMap,K=new Set,Z=[],Q=[],X=(e,t,i)=>{let n=i;const r=z.filter(e=>e.enabled&&e.stage===t).sort((e,t)=>e.priority-t.priority||e.id-t.id);for(const t of r){if(!(t.material instanceof a)){const e=`${t.id}:material`;K.has(e)||(K.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: only NodeShaderMaterial effects are supported.`));continue}try{let i=J.get(t.material);null!=i&&i.version===t.material.version||(i={version:t.material.version,shader:R.compileFullscreen(t.material),diagnosticOrigin:{key:"post-process:"+String(t.material.userData.assetId??(t.material.name||t.material.uuid)),material:{name:t.material.name,uuid:t.material.uuid,version:t.material.version,assetId:t.material.userData.assetId,assetName:t.material.userData.assetName}}},J.set(t.material,i));const r=e.createColorTarget(`hologyCustomPostProcess${t.id}`);e.addNodeFullscreenPass({name:`HologyCustomPostProcess${t.id}`,diagnosticOrigin:i.diagnosticOrigin,shader:i.shader,inputOverrides:{[o]:n},outputs:r}),n=r}catch(e){const i=`${t.id}:compile:${t.material.version}`;K.has(i)||(K.add(i),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: ${e instanceof Error?e.message:String(e)}`,e))}}return n},Y={enabled:!0};let ee=null;const te=e=>{if(null!=ee)return ee;const t=g.sdfgi||{},i=new S.SDFGI(ie.getDevice(),{...t,...e});try{i.setSurfaceCaptureFactory(e=>new S.SDFGISurfaceCapture(ie,e,e=>R.resolveSDFGISurface(e)??null,e!==i))}catch(e){throw i.dispose(),e}return ee=i,i},ie=new S.WebGpuRenderer({canvas:v,fallbackMaterial:b,materialResolver:(e,t)=>{const i=R.resolve(e,t);if(null!=i&&"outline"!==t&&!0!==e.userData.isSky&&ee?.configureMaterial(i),null!=i){const e=i,t=e.uniforms[l];null!=t&&t.value!==I.surfaceRaySteps&&(t.value=I.surfaceRaySteps,e.uniformValuesNeedsUpdate=!0)}return i},invokeObjectRenderCallbacks:!1,hiZOcclusionCulling:!0,renderGraphProfiling:!1,sampleCount:1,multiDrawIndirect:!1,nativePostSubmit:w?.postSubmit,presentationOverlay:e=>{for(const t of Q)t(e)}});ie.setRenderScale("taa"===M?V?.renderScale??1:1),ie.setRenderGraphBuilder((e,t)=>{const i=new S.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=G?i.createColorTarget("hologyMotionVectors",{format:"rgba16float"}):null;for(const e of Z)"beforeScene"===e.stage&&e(i,i.sceneColor);const s=ee?.addPasses(i)??!1;Y.enabled&&i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",dependsOn:s?["SDFGIUpdate"]:void 0,outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let a=i.sceneColor;if(A?.enabled){const e=A.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});a=A.addCompositePass(i,a,e)}I.enabled&&(a=I.addPasses(i,{sceneColor:a,depth:i.mainDepth,normalRoughness:n}));const o=new Set(Z.flatMap(e=>e.getSceneTextureReads?.()??[]));i.addSceneTextureCopyPass(a,{sceneColor:o.has("sceneColorSnapshot"),sceneDepth:o.has("sceneDepthSnapshot")||z.some(e=>e.enabled&&null!=e.material.uniforms[d])}),i.addLatePass(a);for(const e of Z)null!=e.stage&&"afterScene"!==e.stage||e(i,a);a=X(i,"beforeFog",a),null!=H&&(a=H.addPasses(i,{sceneColor:a,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=j&&null!=r&&(a=j.addPass(i,a,r,i.mainDepth)),null!=B&&(a=B.addPass(i,a)),a=X(i,"beforeOutline",a),null!=q&&(a=q.addPass(i,a)),a=X(i,"beforeDepthOfField",a),null!=_&&(a=_.addPass(i,a,i.mainDepth)),a=X(i,"beforeColorAdjustment",a),null!=$&&(a=$.addPass(i,a)),a=X(i,"beforeAntiAliasing",a);let l="taa"===W.mode&&null!=V?V.addPass(i,a,i.mainDepth,r??void 0):a;"smaa"===W.mode&&null!=k?l=k.addPass(i,l):"fxaa"===W.mode&&null!=U&&(l=U.addPass(i,l)),l=X(i,"beforeOutput",l);for(const e of Z)"beforePresent"===e.stage&&e(i,l);!0===w?.enabled&&null!=r?w.addInputPass(i,l,r):i.present(l)});try{return await ie.initialize(f),null!=g.sdfgi&&!1!==g.sdfgi&&te(g.sdfgi),L=new ExperimentalWebGpuBackend(ie,b,R,T,B,U,k,A,I,V,j,H,$,_,q,z,Z,Q,W,Y,w,ee,te,v),L}catch(e){throw ee?.dispose(),ie.destroy(),b.dispose(),R.dispose(),T.dispose(),A?.dispose(),k?.dispose(),j?.dispose(),H?.dispose(),q?.dispose(),e}}static supportsCamera(t){return t instanceof e.PerspectiveCamera||t instanceof e.OrthographicCamera}setSize(e,t,i,n=1){const r=this.canvas.width,s=this.canvas.height;let a=Math.min(1,Math.max(.25,n));if(!0===this.nativeDlss?.enabled){const n=Math.max(1,Math.floor(e*i)),r=Math.max(1,Math.floor(t*i));a=this.nativeDlss.getRenderScale(n,r)}const o=a!==this.renderScale;this.renderScale=a,this.renderer.setRenderScale(a),this.taa?.setRenderScale(a),this.renderer.setSize(e,t,i),(o||this.canvas.width!==r||this.canvas.height!==s)&&this.resetViewHistory()}initTexture(e){this.renderer.initTexture(e)}setPostProcessEffects(e){this.postProcessEffects.splice(0,this.postProcessEffects.length,...e);for(const t of e){if("beforeLut"!==t.stage)continue;const e=`${t.id}:${t.stage}`;this.warnedUnsupportedPostProcessStages.has(e)||(this.warnedUnsupportedPostProcessStages.add(e),console.warn(`[Hology WebGPU experiment] Skipping custom post-process effect ${t.id}: stage "${t.stage}" has no native WebGPU anchor.`))}}getDevice(){return this.renderer.getDevice()}createSceneCapture(e,t,i){return this.renderer.createSceneCapture(e,t,i)}setRenderGraphExtensions(e){this.renderGraphExtensions.length=0;for(const t of e)this.renderGraphExtensions.push(t)}setPresentationExtensions(e){this.presentationExtensions.length=0;for(const t of e)this.presentationExtensions.push(t)}setEnableOutlines(e){null!=this.outline&&(this.outline.enabled=e)}setTiledLightingEnabled(e){this.renderer.setTiledLightingEnabled(e)}setSDFGIOptions(e){null==this.sdfgi&&!0===e.enabled&&(this.sdfgi=this.createSDFGI(e),this.renderer.invalidateMaterialResolution()),this.sdfgi?.setOptions(e)}invalidateSDFGI(){this.sdfgi?.invalidate()}getSDFGIStats(){return this.sdfgi?.stats??null}setDynamicBatchingEnabled(e){this.renderer.setDynamicBatchingEnabled(e)}setSelectedObjects(e){this.outline?.setSelectedObjects(e)}setSelectedObjectInstances(e){this.outline?.setSelectedInstances(e)}setCascadedShadowRanges(e,t=[]){this.renderer.setCascadedShadowRanges(e,t),this.volumetricFog?.setCascadedDirectionalLights(t),this.sdfgi?.setCascadedDirectionalLights(t)}setDirectionalShadowUpdateOptions(e){this.renderer.setDirectionalShadowUpdateOptions(e)}invalidateDirectionalShadows(){this.renderer.invalidateDirectionalShadows()}setDirectionalShadowOptions(e,t){this.directionalShadowState.enabled=e,this.renderer.setDirectionalShadowsEnabled(e),this.renderer.setDirectionalShadowMapSize(t)}setWorldEnvironment(e){if(null==e)return void this.nodeMaterialResolver.setWorldEnvironment(null);const t=this.getEnvironmentTexture(e.source);this.nodeMaterialResolver.setWorldEnvironment({texture:t,intensity:e.intensity})}getEnvironmentTexture(t){if(t.mapping===e.CubeUVReflectionMapping)return t;let i=this.pmremResults.get(t);return null==i&&(this.pmremGenerator??(this.pmremGenerator=this.renderer.createPMREMGenerator()),i=this.pmremGenerator.fromEquirectangular(t),this.pmremResults.set(t,i),this.ownedPmremResults.add(i)),i.texture}resetViewHistory(){this.renderer.resetViewHistory(),this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.nativeDlss?.reset()}async compile(e,t){if(!this.secondaryMotionPrepared){let t=!1;e.traverse(e=>{const i=e.userData.secondaryMotion?.regions;Array.isArray(i)&&i.some(e=>e.enabled)&&(t=!0)});const i=this.renderer.getDevice();if(t&&i){const{prepareSecondaryMotionRuntime:e}=await import("../secondary-motion/runtime.js");e(i),this.secondaryMotionPrepared=!0}}await this.renderer.compileAsync(e,t)}createStaticDrawSet(e,t,i=!1,n="skip",r=!1){this.renderer.setHiZOcclusionCullingEnabled(!0);const s=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:n,allowUnsortedLateDraws:i,mutableTransforms:r});if(0===s.drawCount)return s.dispose(),null;if(null==this.sdfgi)return s;let a=this.sdfgi.registerStaticDrawRoot(e);return{label:s.label,drawCount:s.drawCount,instanceCount:s.instanceCount,updateTransforms:()=>{s.updateTransforms(),a(),a=this.sdfgi.registerStaticDrawRoot(e)},dispose:()=>{a(),s.dispose()}}}registerStaticSpatialObject(e){return this.renderer.registerStaticSpatialObject(e)}render(e,t,i){this.sdfgi?.prepare(e,t);const n="taa"===this.antiAliasingState.mode?this.taa:null;this.volumetricFog?.setScene(e),this.renderer.setMotionVectorProjection(t.projectionMatrix),this.motionBlur?.prepareCamera(t,this.canvas.width,this.canvas.height,i),this.motionBlur?.requiresRendererHistoryReset()&&(this.renderer.resetViewHistory(),this.gtao?.reset(),this.volumetricFog?.reset()),n?.prepareCamera(t,this.canvas.width,this.canvas.height),this.nativeDlss?.prepareFrame(t);const r=!0===this.nativeDlss?.enabled?this.nativeDlss.jitter:null;this.motionBlur?.setJitterUv(n?.currentJitterUv.x??(null==r?0:r.x/Math.max(1,this.canvas.width*this.renderScale)),n?.currentJitterUv.y??(null==r?0:-r.y/Math.max(1,this.canvas.height*this.renderScale))),null!=r&&this.renderer.setProjectionJitter(r.x,r.y);let s=!1;try{this.renderer.render(e,t,i),s=!0}finally{null!=r&&this.renderer.clearProjectionJitter(),n?.finishCamera(t),s&&this.motionBlur?.commitCamera(),s&&this.nativeDlss?.finishFrame(t)}}prepareSceneGeometry(e,t){return this.renderer.prepareSceneGeometryAsync(e,t)}renderPresentationOnly(e){this.setPresentationExtensions(e),this.renderer.renderPresentationOnly()}setMotionBlurOptions(e){null!=this.motionBlur&&Object.assign(this.motionBlur.options,e)}setSSROptions(e){this.ssr?.setOptions(e)}setGTAOOptions(e){this.gtao?.setOptions(e)}setAntiAliasingMode(e){e!==this.antiAliasingState.mode&&("taa"===e&&null==this.taa||"smaa"===e&&null==this.smaa||"fxaa"===e&&null==this.fxaa?console.warn(`[Hology WebGPU experiment] Anti-aliasing mode "${e}" was not initialized. Set webgpuPostProcessing.antiAliasing in the initial rendering configuration to enable runtime switching.`):(this.antiAliasingState.mode=e,this.resetTemporalHistory()))}setGTAOQuality(e){this.gtao?.applyPreset(e)}setVolumetricFogOptions(e){this.volumetricFog?.setOptions(e)}setVolumetricFogQuality(e){this.volumetricFog?.applyPreset(e)}pushMotionBlurOverride(e){return this.motionBlur?.pushOverride(e)??null}invalidateObjectMotion(e){this.renderer.invalidateObjectMotion(e)}getLastFrameProfile(){return this.renderer.getLastFrameProfile()}setPostProcessState(e){null!=this.colorGrading&&(Object.assign(this.colorGrading.options,e??{enabled:!1}),this.colorGrading.options.enabled=!0===e?.enabled),null!=this.depthOfField&&(this.depthOfField.options.enabled=null!=e?.depthFocus||null!=e?.depthAperture||null!=e?.depthMaxBlur,this.depthOfField.options.focus=e?.depthFocus,this.depthOfField.options.aperture=e?.depthAperture,this.depthOfField.options.maxBlur=e?.depthMaxBlur)}setProfilingEnabled(e){this.renderer.setRenderGraphProfilingEnabled(e)}resetTemporalHistory(){this.taa?.reset(),this.motionBlur?.reset(),this.gtao?.reset(),this.volumetricFog?.reset(),this.renderer.resetViewHistory(),this.nativeDlss?.reset()}inspect(e,t){return inspectWebGpuScene(e,t,this.nodeMaterialResolver)}destroy(){this.sdfgi?.dispose(),this.nativeDlss?.dispose(),this.nodeMaterialResolver.dispose(),this.gBufferFallbackSource.dispose(),this.gtao?.dispose(),this.smaa?.dispose(),this.motionBlur?.dispose(),this.volumetricFog?.dispose();for(const e of this.ownedPmremResults)e.dispose();this.ownedPmremResults.clear(),this.renderer.destroy(),this.fallbackMaterial.dispose()}}export function inspectWebGpuScene(e,t,i){const n={meshes:0,skinnedMeshes:0,instancedMeshes:0,batchedMeshes:0,sprites:0,points:0,lines:0,missingPositionGeometry:0,transparentMaterials:0,shaderMaterialsReplaced:0,materialsReplaced:0,unsupportedCamera:ExperimentalWebGpuBackend.supportsCamera(t)?0:1};return e.traverse(e=>{if(e.isSprite)return void n.sprites++;if(e.isPoints)return void n.points++;if(e.isLine)return void n.lines++;if(!e.isMesh)return;const t=e;t.isBatchedMesh?n.batchedMeshes++:t.isInstancedMesh?n.instancedMeshes++:t.isSkinnedMesh?n.skinnedMeshes++:n.meshes++,null==t.geometry?.getAttribute("position")&&n.missingPositionGeometry++;const r=Array.isArray(t.material)?t.material:[t.material];for(const e of r){if(null==e)continue;e.transparent&&n.transparentMaterials++;const t=!0===e.isWGSLShaderMaterial||!0===e.isLineMaterial,r=!t&&!0===i?.canResolve(e);t||r||(n.materialsReplaced++,e.isShaderMaterial&&n.shaderMaterialsReplaced++)}}),n}export function formatWebGpuSceneCapabilitySummary(e){return`[Hology WebGPU experiment] ${JSON.stringify(e)}`}const p="\nstruct VertexInput {\n @location(0) position: vec3<f32>,\n @location(1) normal: vec3<f32>,\n @location(2) uv: vec2<f32>,\n @location(3) color: vec4<f32>,\n#ifdef USE_SKINNING\n @location(4) skinIndex: vec4<u32>,\n @location(5) skinWeight: vec4<f32>,\n#endif\n @builtin(instance_index) instanceIndex: u32,\n};\n\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\n@vertex\nfn vsMain(input: VertexInput) -> VertexOutput {\n var output: VertexOutput;\n#ifdef USE_SKINNING\n let localPosition = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight);\n let localNormal = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let localPosition = input.position;\n let localNormal = input.normal;\n#endif\n let world = rendererWorldPosition(localPosition, input.instanceIndex);\n output.position = rendererClipPosition(localPosition, input.instanceIndex);\n output.worldPosition = world.xyz;\n output.worldNormal = rendererWorldNormal(localNormal, input.instanceIndex);\n output.color = input.color * rendererObjectColor(input.instanceIndex);\n return output;\n}\n",m="\nstruct VertexOutput {\n @builtin(position) position: vec4<f32>,\n @location(0) worldPosition: vec3<f32>,\n @location(1) worldNormal: vec3<f32>,\n @location(2) color: vec4<f32>,\n};\n\nfn distanceAttenuation(distanceToLight: f32, cutoffDistance: f32, decayExponent: f32) -> f32 {\n var distanceFalloff = 1.0 / max(pow(distanceToLight, decayExponent), 0.01);\n if (cutoffDistance > 0.0) {\n let ratio = distanceToLight / cutoffDistance;\n let cutoff = clamp(1.0 - ratio * ratio * ratio * ratio, 0.0, 1.0);\n distanceFalloff *= cutoff * cutoff;\n }\n return distanceFalloff;\n}\n\n@fragment\nfn fsMain(input: VertexOutput) -> @location(0) vec4<f32> {\n let normal = normalize(input.worldNormal);\n let normalTint = normal * 0.5 + vec3<f32>(0.5);\n let base = mix(vec3<f32>(0.52, 0.58, 0.64), normalTint, 0.22) * input.color.rgb;\n var lighting = rendererIndirectDiffuse(normal) + vec3<f32>(0.08);\n var directionalLighting = vec3<f32>(0.0);\n let directionalCount = rendererDirectionalLightCount();\n\n for (var index: u32 = 0u; index < directionalCount; index = index + 1u) {\n let lightDirection = rendererDirectionalLightDirectionForLight(index);\n let shadow = rendererSampleDirectionalShadowForLightWithNormal(index, input.worldPosition, normal);\n directionalLighting += rendererDirectionalLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * shadow;\n }\n if (directionalCount > 0u) {\n lighting += directionalLighting / f32(directionalCount);\n }\n\n for (var index: u32 = 0u; index < rendererPointLightCount(); index = index + 1u) {\n let lightVector = rendererPointLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let shadow = rendererSamplePointShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererPointLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * distanceAttenuation(distanceToLight, rendererPointLightRangeForLight(index), rendererPointLightDecayForLight(index)) * shadow;\n }\n\n for (var index: u32 = 0u; index < rendererSpotLightCount(); index = index + 1u) {\n let lightVector = rendererSpotLightPositionForLight(index) - input.worldPosition;\n let distanceToLight = length(lightVector);\n let lightDirection = normalize(lightVector);\n let angleCos = dot(-lightDirection, rendererSpotLightDirectionForLight(index));\n let cone = smoothstep(rendererSpotLightConeCosForLight(index), rendererSpotLightPenumbraCosForLight(index), angleCos);\n let shadow = rendererSampleSpotShadowForLightWithNormal(index, input.worldPosition, normal);\n lighting += rendererSpotLightColorForLight(index) * max(dot(normal, lightDirection), 0.0) * cone * distanceAttenuation(distanceToLight, rendererSpotLightRangeForLight(index), rendererSpotLightDecayForLight(index)) * shadow;\n }\n\n return vec4<f32>(base * max(lighting, vec3<f32>(0.08)), input.color.a);\n}\n";/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,31 +1,28 @@
1
+ import type { DetailCullingSettings, DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
1
2
  import * as THREE from "three";
2
- import type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
3
- export type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
4
- import type { DetailCullingSettings } from "@hology/webgpu-renderer";
5
- export type { DetailCullingSettings } from "@hology/webgpu-renderer";
6
- import { Camera, Object3D, WebGLRenderer, WebGLRenderTarget, Texture } from 'three';
7
- import { ShaderPass } from "three-stdlib";
8
- import { IRgbNode, RgbaNode } from 'three-shader-graph';
9
- import { CSM } from "three/examples/jsm/csm/CSM.js";
10
- import { type RenderingStatsStyle } from './utils/three/frame-stats.js';
3
+ import { Camera, Object3D, Texture, WebGLRenderer } from 'three';
4
+ import { type SceneSDFGISettings } from './rendering/sdfgi-settings.js';
5
+ export type { DetailCullingSettings, DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
6
+ export type { SceneSDFGISettings } from './rendering/sdfgi-settings.js';
7
+ export { FogNode, isObjectInFrustum } from './rendering/webgl-backend.js';
11
8
  export type { RenderingStatsStyle } from './utils/three/frame-stats.js';
12
- import { GTAOPass } from "three/examples/jsm/postprocessing/GTAOPass.js";
13
- import { OutlinePass } from './utils/three/outline-pass.js';
14
- import { type PostProcessSettings, type PostProcessVolume } from "./gameplay/actors/builtin/post-process-volume-actor.js";
9
+ import { CSM } from "three/examples/jsm/csm/CSM.js";
10
+ import type { VfxBackendPreference } from './effects/vfx/gpu-sprite-compiler.js';
15
11
  import type { WaterPostProcessVolume } from './gameplay/actors/builtin/components/water-post-process-settings.js';
16
- import { type PostProcessEffect, type PostProcessEffectOptions } from "./rendering/post-process-effect.js";
12
+ import { type PostProcessSettings, type PostProcessVolume } from "./gameplay/actors/builtin/post-process-volume-actor.js";
17
13
  import { Cluster } from "./rendering/cluster-generator.js";
18
- import { LightVolume } from "./rendering/light-probes/light-volume-capture.js";
19
- import { type PostProcessMaterialSource } from "./shader/post-process-shader.js";
20
- import { type UpscalingOptions } from "./rendering/upscaling-pass.js";
21
- import { type AntiAliasingMode, type ExperimentalWebGpuPostProcessingOptions, type GTAOOptions, type GTAOQuality, type MotionBlurOptions, type MotionBlurOverride, type MotionBlurOverrideHandle, type RendererFrameProfile, type ExperimentalWebGpuRenderGraphExtension, type WebGpuPresentationExtension, type RendererSceneCapture, type VolumetricFogOptions, type VolumetricFogQuality } from './rendering/webgpu-experimental-backend.js';
22
14
  import type { WorldEnvironmentState } from './rendering/environment.js';
23
- import type { VfxBackendPreference } from './effects/vfx/gpu-sprite-compiler.js';
24
15
  import { type GraphicsRuntime } from './rendering/graphics-runtime.js';
16
+ import { LightVolume } from "./rendering/light-probes/light-volume-capture.js";
17
+ import { type PostProcessEffect, type PostProcessEffectOptions } from "./rendering/post-process-effect.js";
18
+ import { type UpscalingOptions } from "./rendering/upscaling-pass.js";
19
+ import { WebGlBackend } from './rendering/webgl-backend.js';
20
+ import { type AntiAliasingMode, type ExperimentalWebGpuPostProcessingOptions, type ExperimentalWebGpuRenderGraphExtension, type GTAOOptions, type GTAOQuality, type MotionBlurOptions, type MotionBlurOverride, type MotionBlurOverrideHandle, type RendererFrameProfile, type RendererSceneCapture, type SDFGIOptions, type SDFGIStats, type SSROptions, type VolumetricFogOptions, type VolumetricFogQuality, type WebGpuPresentationExtension } from './rendering/webgpu-experimental-backend.js';
21
+ import { type PostProcessMaterialSource } from "./shader/post-process-shader.js";
22
+ import { type RenderingStatsStyle } from './utils/three/frame-stats.js';
25
23
  export { GraphicsRuntime } from './rendering/graphics-runtime.js';
26
24
  export type { UpscalingOptions } from "./rendering/upscaling-pass.js";
27
- export type { AntiAliasingMode, ExperimentalWebGpuPostProcessingOptions, ExperimentalWebGpuRenderGraphExtension, WebGpuPresentationExtension, WebGpuPresentationExtensionContext, RendererSceneCapture, RendererSceneCaptureOptions, RendererSceneCapturePostProcessContext } from './rendering/webgpu-experimental-backend.js';
28
- export type { GTAOOptions, GTAOQuality, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, VolumetricFogOptions, VolumetricFogQuality } from './rendering/webgpu-experimental-backend.js';
25
+ export type { AntiAliasingMode, ExperimentalWebGpuPostProcessingOptions, ExperimentalWebGpuRenderGraphExtension, GTAOOptions, GTAOQuality, MotionBlurOptions, MotionBlurOverride, MotionBlurOverrideHandle, RendererSceneCapture, RendererSceneCaptureOptions, RendererSceneCapturePostProcessContext, SDFGICascadeOptions, SDFGIOptions, SDFGIStats, SSROptions, VolumetricFogOptions, VolumetricFogQuality, WebGpuPresentationExtension, WebGpuPresentationExtensionContext } from './rendering/webgpu-experimental-backend.js';
29
26
  /** Renderer requested by a view. `webgpu-experimental` is a deprecated alias. */
30
27
  export type RenderingBackend = 'webgl' | 'webgpu' | 'webgpu-experimental';
31
28
  export type ActiveRenderingBackend = 'webgl' | 'webgpu';
@@ -36,6 +33,10 @@ export interface DirectionalShadowOptions {
36
33
  maxDistance: number;
37
34
  }
38
35
  export type MotionBlurObjectMode = 'disabled' | 'cameraOnly' | 'objectAndCamera' | 'forceObjectBlur';
36
+ /** Callable disposer with an explicit resident-data refresh. */
37
+ export type StaticDrawSetRegistrationHandle = (() => void) & {
38
+ updateTransforms(): void;
39
+ };
39
40
  export type DynamicResolutionOptions = {
40
41
  enabled?: boolean;
41
42
  /**
@@ -176,7 +177,7 @@ export declare class RenderingView {
176
177
  * initialized. The source remains visible until its static draw set exists,
177
178
  * so WebGL fallback continues to render the normal Three.js objects.
178
179
  */
179
- registerExperimentalStaticDrawSet(root: THREE.Object3D, label: string, allowUnsortedLateDraws?: boolean, onUnsupported?: 'throw' | 'skip'): () => void;
180
+ registerExperimentalStaticDrawSet(root: THREE.Object3D, label: string, allowUnsortedLateDraws?: boolean, onUnsupported?: 'throw' | 'skip', mutableTransforms?: boolean): StaticDrawSetRegistrationHandle;
180
181
  /** @deprecated Use registerWebGpuRenderGraphExtension. */
181
182
  registerExperimentalWebGpuRenderGraphExtension(extension: ExperimentalWebGpuRenderGraphExtension): () => void;
182
183
  private isIntersecting;
@@ -187,25 +188,30 @@ export declare class RenderingView {
187
188
  camera: THREE.Camera;
188
189
  windowVisible: boolean;
189
190
  /** @deprecated WebGL-specific escape hatch. Use webGlRenderer and backend-neutral RenderingView APIs. */
190
- renderer: WebGLRenderer;
191
+ get renderer(): WebGLRenderer;
192
+ /** Legacy WebGL resources remain accessible through the facade. */
193
+ get rendererDepth(): WebGlBackend['rendererDepth'];
194
+ set rendererDepth(value: WebGlBackend['rendererDepth']);
195
+ get outlinePass(): WebGlBackend['outlinePass'];
196
+ set outlinePass(value: WebGlBackend['outlinePass']);
197
+ get fxaaPass(): WebGlBackend['fxaaPass'];
198
+ set fxaaPass(value: WebGlBackend['fxaaPass']);
199
+ get aoMaskDepthRenderTarget(): WebGlBackend['aoMaskDepthRenderTarget'];
200
+ set aoMaskDepthRenderTarget(value: WebGlBackend['aoMaskDepthRenderTarget']);
201
+ get depthRenderTarget(): WebGlBackend['depthRenderTarget'];
202
+ set depthRenderTarget(value: WebGlBackend['depthRenderTarget']);
203
+ get sceneColorRenderTarget(): WebGlBackend['sceneColorRenderTarget'];
204
+ set sceneColorRenderTarget(value: WebGlBackend['sceneColorRenderTarget']);
205
+ get sceneDepthRenderTarget(): WebGlBackend['sceneDepthRenderTarget'];
206
+ set sceneDepthRenderTarget(value: WebGlBackend['sceneDepthRenderTarget']);
207
+ get aoPass(): WebGlBackend['aoPass'];
208
+ set aoPass(value: WebGlBackend['aoPass']);
191
209
  /** Returns the WebGL renderer only when the active backend is WebGL. */
192
210
  get webGlRenderer(): WebGLRenderer | null;
193
211
  registerWebGpuRenderGraphExtension(extension: ExperimentalWebGpuRenderGraphExtension): () => void;
194
- rendererDepth: WebGLRenderer;
195
- private composer;
196
- private bloomComposer;
197
- outlinePass: OutlinePass;
198
- fxaaPass: ShaderPass;
199
- /** Copy pass is to copy the forward rendered result into the effect composer */
200
- private copyPass;
201
212
  scene: THREE.Scene;
202
- private queryScene;
203
213
  running: boolean;
204
214
  paused: boolean;
205
- aoMaskDepthRenderTarget: WebGLRenderTarget;
206
- depthRenderTarget: WebGLRenderTarget;
207
- sceneColorRenderTarget: WebGLRenderTarget;
208
- sceneDepthRenderTarget: WebGLRenderTarget;
209
215
  csm: CSM | null;
210
216
  private _fpsCap;
211
217
  private fpsCapRevision;
@@ -220,42 +226,18 @@ export declare class RenderingView {
220
226
  baseToneMapping: THREE.ToneMapping;
221
227
  baseToneMappingExposure: number;
222
228
  /** Tracks last update time (ms) for each CSM cascade. */
223
- private csmCascadeLastUpdate?;
224
- private csmUpdateInvervals;
225
229
  private webgpuDirectionalShadowUpdateOptions;
226
230
  private webgpuDirectionalShadowOptions;
227
- aoPass: GTAOPass;
228
- private bloomPass;
229
- private colorPass;
230
- private dofPass;
231
- private lutPass;
232
- private outputPass;
233
- private ssrPass;
234
- private volumetricFogPass;
235
231
  private postProcessEffectId;
236
232
  private postProcessEffects;
237
- private postProcessEffectResolution;
238
- private postProcessEffectUniformState;
239
- private transmissionColorRenderTarget?;
240
- private transmissionCopyQuad?;
241
- private fquadCopySceneColor;
242
- private fquadCopySceneDepth;
243
- private occlusionClusters;
244
233
  simulationTime: number;
245
234
  simulationTimeScale: number;
246
235
  lightVolume: LightVolume;
247
236
  lightProbeIntensity: number;
248
- /**
249
- * This should be used to multiply the AO with the opaque color.
250
- *
251
- * The reason for using an MRT for this is to be able to render the transparent
252
- * pass and add to the samt MRT for bloom and other effects.
253
- *
254
- * An altnerative could be to have multiple bloom texture outputs that are
255
- * additively combined. Normals as well could simply be overwritten for SSR.
256
- */
257
- private fquadBlendAO;
258
- private createAoblendQuad;
237
+ addCluster(cluster: Cluster): void;
238
+ addOverlayCamera(camera: Camera): void;
239
+ clearOverlayCameras(): void;
240
+ removeOverlayCamera(camera: Camera): void;
259
241
  setPaused(value: boolean): void;
260
242
  resolutionScale: number;
261
243
  maxPixelRatio: number;
@@ -263,19 +245,7 @@ export declare class RenderingView {
263
245
  private dynamicResolutionFrameTimeAverage;
264
246
  private dynamicResolutionFrameSamples;
265
247
  private dynamicResolutionLastAdjustmentAt;
266
- private upscaleOutputPass;
267
248
  setResolutionScale(scale: number | undefined): void;
268
- private readonly unjitteredProjectionMatrix;
269
- private readonly temporalJitter;
270
- private readonly temporalJitterUv;
271
- private readonly currentUnjitteredViewProjectionMatrix;
272
- private readonly currentViewProjectionMatrix;
273
- private readonly currentViewProjectionMatrixInverse;
274
- private readonly previousViewProjectionMatrix;
275
- private readonly temporalUpscalingFrameState;
276
- private temporalUpscalingFrameIndex;
277
- private hasPreviousTemporalViewProjection;
278
- private projectionJitterApplied;
279
249
  get currentResolutionScale(): number;
280
250
  get currentRenderPixelRatio(): number;
281
251
  get currentPresentationPixelRatio(): number;
@@ -283,10 +253,7 @@ export declare class RenderingView {
283
253
  /** CSS-pixel viewport size captured by resizeRender(). */
284
254
  getClientSize(target?: THREE.Vector2): THREE.Vector2;
285
255
  private isUpscalingEnabled;
286
- private isTemporalUpscalingEnabled;
287
256
  resetUpscalingHistory(): void;
288
- private prepareUpscalingFrame;
289
- private finishUpscalingFrame;
290
257
  private getBasePixelRatio;
291
258
  private getBaseResolutionScale;
292
259
  private getDynamicResolutionMinScale;
@@ -308,22 +275,10 @@ export declare class RenderingView {
308
275
  removePostProcessVolume(volume: PostProcessVolume): void;
309
276
  addPostProcessEffect(source: PostProcessMaterialSource, options?: PostProcessEffectOptions): PostProcessEffect;
310
277
  private syncExperimentalWebGpuPostProcessEffects;
311
- private getPostProcessEffectStageAnchorPass;
312
278
  private onVisiblityChane;
313
- private isDepthTextureExtensionSupported;
314
- private outlineEffect;
315
- private gRenderTarget;
316
- private phasedRenderPass;
317
- private webGlInitialized;
318
- private setupWebGlPipeline;
279
+ private get webGlInitialized();
319
280
  constructor(container: HTMLElement, options?: RenderingViewOptions);
320
- addCluster(cluster: Cluster): void;
321
- /**
322
- * This finds the most relevant occlusion clusters to query.
323
- * Optimizing this is a balance between minimizing the number of queries
324
- * and reducing pop in.
325
- */
326
- private updateRenderedOcclusionClusters;
281
+ private setupWebGlPipeline;
327
282
  private fixStatsStyle;
328
283
  setEnableOutlines(enabled: boolean): void;
329
284
  registerWebGpuPresentationExtension(extension: WebGpuPresentationExtension): () => void;
@@ -339,7 +294,17 @@ export declare class RenderingView {
339
294
  setDirectionalShadowUpdateOptions(options: DirectionalShadowUpdateOptions): void;
340
295
  invalidateDirectionalShadows(): void;
341
296
  setDirectionalShadowOptions(options: DirectionalShadowOptions): void;
297
+ setSSROptions(options: SSROptions): void;
342
298
  setGTAOOptions(options: GTAOOptions): void;
299
+ private sdfgiRuntimeOptions;
300
+ private sceneSDFGISettings;
301
+ /** Runtime/player quality overrides, combined with the scene's authored lighting. */
302
+ setSDFGIOptions(options: SDFGIOptions): void;
303
+ /** Null restores project defaults when a scene's World Environment is removed. */
304
+ setSceneSDFGISettings(settings: SceneSDFGISettings | null): void;
305
+ private syncSDFGISettings;
306
+ invalidateSDFGI(): void;
307
+ getSDFGIStats(): Readonly<SDFGIStats> | null;
343
308
  configureAmbientOcclusion(enabled: boolean, blendIntensity?: number, options?: Record<string, unknown>): void;
344
309
  invalidateShadows(): void;
345
310
  initTexture(texture: Texture): void;
@@ -363,12 +328,6 @@ export declare class RenderingView {
363
328
  object: Object3D;
364
329
  instanceIndex: number;
365
330
  }[]): void;
366
- private static createDepthRenderTarget;
367
- /** */
368
- private static createAOMaskDepthRenderTarget;
369
- private createSceneColorRenderTarget;
370
- private createSceneDepthRenderTarget;
371
- private createGRenderTarget;
372
331
  private setupEventListeners;
373
332
  stop(dispose?: boolean): void;
374
333
  /** Stops frame scheduling without releasing the renderer, GPU device, or presentation surface. */
@@ -405,53 +364,7 @@ export declare class RenderingView {
405
364
  private requireInitializedBackend;
406
365
  private activateExperimentalStaticDrawSets;
407
366
  private disposeExperimentalStaticDrawSets;
408
- private applyEnvMap;
409
367
  setWorldEnvironment(environment: WorldEnvironmentState | null): void;
410
- private applyWorldEnvironmentToWebGl;
411
- private hideOccluded;
412
- private setupCsm;
413
- private gbufferMaterialCache;
414
- private gbufferDepthPrepassMaterialCache;
415
- private tbufferMaterialCache;
416
- private depthPrepassMaterialCache;
417
- private depthPrepassCachedMaterials;
418
- private depthPrepassCachedVisibility;
419
- /**
420
- * If the material such as a standard material has updated properties, then we need to update
421
- * the corresponding g buffer material
422
- * @param source
423
- * @param target
424
- */
425
- private updateMaterialProperties;
426
- /**
427
- * Updates uniform values from source material to target material.
428
- * Optimized for hot path execution in rendering loop.
429
- */
430
- private updateUniformValues;
431
- /**
432
- * Creates target-local uniform wrapper objects for any source uniforms that the
433
- * derived material does not already declare. We keep the underlying value
434
- * references instead of deep-cloning them so render-target textures and other
435
- * runtime-owned resources are not duplicated or warned about.
436
- */
437
- private inheritCustomUniformBindings;
438
- private updateMaterialCommonProperties;
439
- /**
440
- * After rendering the opaque scene, we will also calculate lights which updates uniforms.
441
- * These need to be present on the gbuffer materials so we need to copy them afterward.
442
- */
443
- private updateLightUniformValues;
444
- private createGBufferMaterial;
445
- private isDepthPrepassEnabled;
446
- private usesSceneFeedbackUniforms;
447
- private usesShaderUniform;
448
- private isDepthPrepassEligibleMaterial;
449
- private isDepthPrepassEligibleMesh;
450
- private createDepthPrepassMaterial;
451
- private applyDepthPrepassMaterials;
452
- private unapplyDepthPrepassMaterials;
453
- private renderDepthPrepass;
454
- private updateCsm;
455
368
  /**
456
369
  * three.js CSM splits are normalized against CSM.maxFar. The shared WGSL
457
370
  * material graph measures linear depth against the camera clip range, so
@@ -459,23 +372,6 @@ export declare class RenderingView {
459
372
  */
460
373
  private syncExperimentalWebGpuCascades;
461
374
  loop(onFrame: (deltaTime: number) => any, showStats?: boolean, onInputFrame?: (inactive: boolean) => void): void;
462
- private frameGBufferMeshes;
463
- private frameGBufferPhaseMasks;
464
- private frameUnsupportedGBufferObjects;
465
- private frameGBufferExcludedObjects;
466
- private appliedGBufferMeshes;
467
- private originalGBufferMaterials;
468
- private originalGBufferOnBeforeRender;
469
- private hiddenGBufferObjects;
470
- private gBufferPhaseMaskCache;
471
- private gBufferMaterialArrayCache;
472
- private gBufferShadowUpdaterCache;
473
- private collectGBufferRenderables;
474
- private getGBufferPhaseMask;
475
- private getGBufferMaterialArray;
476
- private applyGBufferMaterials;
477
- private unapplyGBufferMaterials;
478
- private applyGBufferShadowUniformUpdater;
479
375
  initTextures(scene?: THREE.Scene): void;
480
376
  /**
481
377
  * Initializes scene textures without monopolizing the host event loop.
@@ -500,57 +396,9 @@ export declare class RenderingView {
500
396
  private releaseExperimentalWebGpuBackend;
501
397
  private applyExperimentalWebGpuViewState;
502
398
  private syncWebGpuOutlineState;
503
- private depthMaterialCachedMaterials;
504
- private applyDepthMaterial;
505
- private unapplyDepthMaterial;
506
- private renderScene;
507
399
  getEnvTexture(texture: Texture): Texture;
508
400
  private applyPostProcessSettings;
509
- private updatePostProcessEffectUniforms;
510
- private insetHeight;
511
- private insetWidth;
512
- private insetOffsetY;
513
- private insetMargin;
514
- private maxInsetCameras;
515
- private overlayCameras;
516
- private renderOverlay;
517
- addOverlayCamera(camera: Camera): void;
518
- clearOverlayCameras(): void;
519
- removeOverlayCamera(camera: Camera): void;
520
- private prevClearColor;
521
- private hadBloom;
522
401
  render(deltaTime?: number): void;
523
- private bloomStoredMaterials;
524
- private bloomHidden;
525
- private hasBloom;
526
- private usesSceneColorUniform;
527
- private initSceneColorUniform;
528
- private initDepthUniform;
529
- private initNormalUniform;
530
- private initShadowUniform;
531
- private initLightVolumeUniform;
532
- private initResolutionUniform;
533
- private initAoUniform;
534
- private initCustomDepthMaterial;
535
- private _customDepthMaterialCache;
536
402
  }
537
403
  export declare function setRenderingPaused(value: boolean): void;
538
- /**
539
- * Checks if a given 3D object is within the camera's frustum.
540
- *
541
- * @param object - The 3D object to check.
542
- * @param camera - The camera to check against.
543
- * @returns `true` if the object is in the camera's frustum, `false` otherwise.
544
- */
545
- export declare function isObjectInFrustum(object: THREE.Object3D, frustum: THREE.Frustum): boolean;
546
- export declare class FogNode extends RgbaNode {
547
- private readonly source;
548
- private readonly fogColor;
549
- constructor(source: RgbaNode, fogColor?: IRgbNode);
550
- compile(c: any): {
551
- pars: string;
552
- chunk: string;
553
- out: string;
554
- };
555
- }
556
404
  //# sourceMappingURL=rendering.d.ts.map