@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.
- package/dist/effects/sequence/sequence-player.d.ts +1 -0
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/gameplay/actors/builtin/components/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.d.ts +66 -0
- package/dist/gameplay/actors/builtin/components/primitive-mesh-component.js +4 -0
- package/dist/gameplay/actors/builtin/index.d.ts +6 -0
- package/dist/gameplay/actors/builtin/index.js +1 -1
- package/dist/gameplay/actors/builtin/light-actor.d.ts +54 -0
- package/dist/gameplay/actors/builtin/light-actor.js +4 -0
- package/dist/gameplay/actors/builtin/mesh-actor.d.ts +9 -0
- package/dist/gameplay/actors/builtin/mesh-actor.js +4 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +5 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/index.d.ts +1 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/rendering-host.d.ts +1 -0
- package/dist/gameplay/rendering-host.js +1 -1
- package/dist/gameplay/services/asset-loader.d.ts +3 -0
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/rendering/node-material-webgpu-resolver.d.ts +5 -1
- package/dist/rendering/node-material-webgpu-resolver.js +1 -1
- package/dist/rendering/post-process-color.d.ts +9 -0
- package/dist/rendering/post-process-color.js +4 -0
- package/dist/rendering/sdfgi-settings.d.ts +8 -0
- package/dist/rendering/sdfgi-settings.js +4 -0
- package/dist/rendering/sdfgi-surface-material.d.ts +8 -0
- package/dist/rendering/sdfgi-surface-material.js +4 -0
- package/dist/rendering/webgl-backend.d.ts +243 -9
- package/dist/rendering/webgl-backend.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +14 -3
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +56 -208
- package/dist/rendering.js +1 -1
- package/dist/scene/actor-material-parameters.d.ts +19 -0
- package/dist/scene/actor-material-parameters.js +4 -0
- package/dist/scene/actor-mesh-provider.d.ts +2 -0
- package/dist/scene/actor-mesh-provider.js +4 -0
- package/dist/scene/actor-mesh-renderer.d.ts +40 -0
- package/dist/scene/actor-mesh-renderer.js +4 -0
- package/dist/scene/asset-resource-loader.d.ts +2 -0
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/custom-param-deserialize.js +1 -1
- package/dist/scene/custom-param-runtime-types.js +1 -1
- package/dist/scene/material-ref.d.ts +7 -0
- package/dist/scene/material-ref.js +4 -0
- package/dist/scene/materializer.d.ts +18 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +4 -1
- package/dist/scene/model.js +1 -1
- package/dist/scene/runtime-bundled-backend-service.d.ts +1 -0
- package/dist/scene/runtime-bundled-backend-service.js +1 -1
- package/dist/scene/scene-data-service.js +1 -1
- package/dist/scene/scene-object-actor-conversion.d.ts +10 -0
- package/dist/scene/scene-object-actor-conversion.js +4 -0
- package/dist/shader/parameter.d.ts +5 -2
- package/dist/shader-nodes/particle.d.ts +2 -2
- package/dist/shader-nodes/surface-reflection.d.ts +1 -0
- package/dist/shader-nodes/surface-reflection.js +1 -1
- package/dist/test/actor-mesh-renderer.test.d.ts +2 -0
- package/dist/test/actor-mesh-renderer.test.js +4 -0
- package/dist/test/actor-persistence-runtime.test.js +1 -1
- package/dist/test/asset-resource-loader-converted-fbx.test.js +1 -1
- package/dist/test/asset-resource-loader-skinned-merge.test.js +1 -1
- package/dist/test/landscape-static-draw-sets.test.js +1 -1
- package/dist/test/node-material-webgpu-resolver.test.js +1 -1
- package/dist/test/physics-ray-object.test.js +1 -1
- package/dist/test/primitive-actors.test.d.ts +2 -0
- package/dist/test/primitive-actors.test.js +4 -0
- package/dist/test/rendering-host.test.js +1 -1
- package/dist/test/runtime-bundled-backend-service.test.d.ts +2 -0
- package/dist/test/runtime-bundled-backend-service.test.js +4 -0
- package/dist/test/scene-object-actor-conversion.test.d.ts +2 -0
- package/dist/test/scene-object-actor-conversion.test.js +4 -0
- package/dist/test/sdfgi-settings.test.d.ts +2 -0
- package/dist/test/sdfgi-settings.test.js +4 -0
- package/dist/test/shader-graph.test.js +1 -1
- package/dist/test/surface-reflection.test.js +1 -1
- package/dist/test/webgl-backend.test.d.ts +2 -0
- package/dist/test/webgl-backend.test.js +4 -0
- package/dist/utils/async.d.ts +2 -0
- package/dist/utils/async.js +1 -1
- package/dist/utils/mesh.js +1 -1
- package/package.json +3 -3
- 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
|
*/
|
package/dist/rendering.d.ts
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
|
+
import type { DetailCullingSettings, DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
1
2
|
import * as THREE from "three";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type {
|
|
6
|
-
|
|
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 {
|
|
13
|
-
import {
|
|
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
|
|
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,
|
|
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'):
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
|
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
|
-
|
|
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
|