@hology/core 0.0.275 → 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 +1 -0
- 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/webgl-backend.d.ts +243 -9
- package/dist/rendering/webgl-backend.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +4 -1
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +45 -209
- 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 +16 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +2 -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-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/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/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 +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -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 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,v,S,b,w,P,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=v,this.antiAliasingState=S,this.directionalShadowState=b,this.nativeDlss=w,this.sdfgi=P,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 v=await import("@hology/webgpu-renderer");i({registerPipelineDiagnosticOrigin:v.registerPipelineDiagnosticOrigin,createComputeKernel:(e,t)=>new v.ComputeKernel(e,t),buildParticleLightingShaderHeader:v.buildParticleLightingShaderHeader});const S=document.createElement("canvas");S.dataset.hologyRenderer="webgpu-experimental";const b=new v.WGSLShaderMaterial({vertexShader:p,fragmentShader:m}),w=!1!==g.nativeUpscaling&&"dlss"===g.nativeUpscaling?.method,P=w?(await import("./native-dlss-upscaler.js")).createNativeDlssUpscaler(g.nativeUpscaling?.mode??"quality"):null,x=null!=P;b.side=v.DoubleSide;const y=v,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":w?"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 v.GTAOEffect({normalSpace:"view",...v.GTAO_PRESETS.high,...g.gtao??{}}),I=new v.SSREffect({normalSpace:"view",enabled:null!=g.ssr&&!1!==g.ssr,...g.ssr||{}}),B=!1===g.bloom?null:new v.BloomEffect({threshold:1,strength:.9,radius:.2,...g.bloom??{}}),U=E||!1!==g.fxaa&&"fxaa"===M?new v.FXAAEffect(!1===g.fxaa?{}:g.fxaa):null,k=E||!1!==g.smaa&&"smaa"===M?new v.SMAAEffect(!1===g.smaa?{}:g.smaa):null,V=x||E||!1!==g.taa&&"taa"===M?new v.TemporalAAEffect({renderScale:1,...!1===g.taa?{}:g.taa}):null,W={mode:M},j=!1===g.motionBlur||null==g.motionBlur?null:new v.MotionBlurEffect(g.motionBlur),N=g.volumetricFog||void 0,H=!1===g.volumetricFog?null:new v.VolumetricFogEffect(void 0,{...v.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...N,temporal:!1!==N?.temporal&&{...v.VOLUMETRIC_FOG_PRESETS.high.temporal,...N?.temporal},blur:!1!==N?.blur&&{...!1===v.VOLUMETRIC_FOG_PRESETS.high.blur?{}:v.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...N?.blur}}),$=!1===g.colorGrading?null:new v.ColorGradingEffect({enabled:!1,...g.colorGrading??{}}),_=!1===g.depthOfField?null:new v.DepthOfFieldEffect({enabled:!1,...g.depthOfField??{}}),q=!1===g.outline?null:new v.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 v.SDFGI(ie.getDevice(),{...t,...e});try{i.setSurfaceCaptureFactory(e=>new v.SDFGISurfaceCapture(ie,e,e=>R.resolveSDFGISurface(e)??null,e!==i))}catch(e){throw i.dispose(),e}return ee=i,i},ie=new v.WebGpuRenderer({canvas:S,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:P?.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 v.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);ee?.addPasses(i),Y.enabled&&i.addDirectionalShadowPass(),i.addPointShadowPass(),i.addSpotShadowPass(),i.addDepthPrepass(),i.addHiZPasses(),i.addVisibilityPass(),i.addMaterialPass({name:"OpaqueGBufferPass",dependsOn:null==ee?void 0:["SDFGIUpdate"],outputs:null==r?[i.sceneColor,n]:[i.sceneColor,n,r],drawStage:"opaque",loadDepth:!0}),i.addHiZHistoryPass("OpaqueGBufferPass");let s=i.sceneColor;if(A?.enabled){const e=A.addPasses(i,{depth:i.mainDepth,normal:n,velocity:r??void 0});s=A.addCompositePass(i,s,e)}I.enabled&&(s=I.addPasses(i,{sceneColor:s,depth:i.mainDepth,normalRoughness:n}));const a=new Set(Z.flatMap(e=>e.getSceneTextureReads?.()??[]));i.addSceneTextureCopyPass(s,{sceneColor:a.has("sceneColorSnapshot"),sceneDepth:a.has("sceneDepthSnapshot")||z.some(e=>e.enabled&&null!=e.material.uniforms[d])}),i.addLatePass(s);for(const e of Z)null!=e.stage&&"afterScene"!==e.stage||e(i,s);s=X(i,"beforeFog",s),null!=H&&(s=H.addPasses(i,{sceneColor:s,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=j&&null!=r&&(s=j.addPass(i,s,r,i.mainDepth)),null!=B&&(s=B.addPass(i,s)),s=X(i,"beforeOutline",s),null!=q&&(s=q.addPass(i,s)),s=X(i,"beforeDepthOfField",s),null!=_&&(s=_.addPass(i,s,i.mainDepth)),s=X(i,"beforeColorAdjustment",s),null!=$&&(s=$.addPass(i,s)),s=X(i,"beforeAntiAliasing",s);let o="taa"===W.mode&&null!=V?V.addPass(i,s,i.mainDepth,r??void 0):s;"smaa"===W.mode&&null!=k?o=k.addPass(i,o):"fxaa"===W.mode&&null!=U&&(o=U.addPass(i,o)),o=X(i,"beforeOutput",o);for(const e of Z)"beforePresent"===e.stage&&e(i,o);!0===P?.enabled&&null!=r?P.addInputPass(i,o,r):i.present(o)});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,P,ee,te,S),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"){this.renderer.setHiZOcclusionCullingEnabled(!0);const r=this.renderer.createStaticDrawSet(e,{label:t,onUnsupported:n,allowUnsortedLateDraws:i});if(0===r.drawCount)return r.dispose(),null;if(null==this.sdfgi)return r;const s=this.sdfgi.registerStaticDrawRoot(e);return{label:r.label,drawCount:r.drawCount,instanceCount:r.instanceCount,dispose:()=>{s(),r.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)}}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";/*
|
|
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,33 +1,28 @@
|
|
|
1
|
+
import type { DetailCullingSettings, DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
import { Camera, Object3D, Texture, WebGLRenderer } from 'three';
|
|
1
4
|
import { type SceneSDFGISettings } from './rendering/sdfgi-settings.js';
|
|
5
|
+
export type { DetailCullingSettings, DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
2
6
|
export type { SceneSDFGISettings } from './rendering/sdfgi-settings.js';
|
|
3
|
-
|
|
4
|
-
import type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
5
|
-
export type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
6
|
-
import type { DetailCullingSettings } from "@hology/webgpu-renderer";
|
|
7
|
-
export type { DetailCullingSettings } from "@hology/webgpu-renderer";
|
|
8
|
-
import { Camera, Object3D, WebGLRenderer, WebGLRenderTarget, Texture } from 'three';
|
|
9
|
-
import { ShaderPass } from "three-stdlib";
|
|
10
|
-
import { IRgbNode, RgbaNode } from 'three-shader-graph';
|
|
11
|
-
import { CSM } from "three/examples/jsm/csm/CSM.js";
|
|
12
|
-
import { type RenderingStatsStyle } from './utils/three/frame-stats.js';
|
|
7
|
+
export { FogNode, isObjectInFrustum } from './rendering/webgl-backend.js';
|
|
13
8
|
export type { RenderingStatsStyle } from './utils/three/frame-stats.js';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
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';
|
|
17
11
|
import type { WaterPostProcessVolume } from './gameplay/actors/builtin/components/water-post-process-settings.js';
|
|
18
|
-
import { type
|
|
12
|
+
import { type PostProcessSettings, type PostProcessVolume } from "./gameplay/actors/builtin/post-process-volume-actor.js";
|
|
19
13
|
import { Cluster } from "./rendering/cluster-generator.js";
|
|
20
|
-
import { LightVolume } from "./rendering/light-probes/light-volume-capture.js";
|
|
21
|
-
import { type PostProcessMaterialSource } from "./shader/post-process-shader.js";
|
|
22
|
-
import { type UpscalingOptions } from "./rendering/upscaling-pass.js";
|
|
23
|
-
import { type AntiAliasingMode, type ExperimentalWebGpuPostProcessingOptions, type SSROptions, type GTAOOptions, type GTAOQuality, type SDFGIOptions, type SDFGIStats, type MotionBlurOptions, type MotionBlurOverride, type MotionBlurOverrideHandle, type RendererFrameProfile, type ExperimentalWebGpuRenderGraphExtension, type WebGpuPresentationExtension, type RendererSceneCapture, type VolumetricFogOptions, type VolumetricFogQuality } from './rendering/webgpu-experimental-backend.js';
|
|
24
14
|
import type { WorldEnvironmentState } from './rendering/environment.js';
|
|
25
|
-
import type { VfxBackendPreference } from './effects/vfx/gpu-sprite-compiler.js';
|
|
26
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';
|
|
27
23
|
export { GraphicsRuntime } from './rendering/graphics-runtime.js';
|
|
28
24
|
export type { UpscalingOptions } from "./rendering/upscaling-pass.js";
|
|
29
|
-
export type { AntiAliasingMode, ExperimentalWebGpuPostProcessingOptions, ExperimentalWebGpuRenderGraphExtension,
|
|
30
|
-
export type { SSROptions, GTAOOptions, GTAOQuality, SDFGICascadeOptions, SDFGIOptions, SDFGIStats, 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';
|
|
31
26
|
/** Renderer requested by a view. `webgpu-experimental` is a deprecated alias. */
|
|
32
27
|
export type RenderingBackend = 'webgl' | 'webgpu' | 'webgpu-experimental';
|
|
33
28
|
export type ActiveRenderingBackend = 'webgl' | 'webgpu';
|
|
@@ -38,6 +33,10 @@ export interface DirectionalShadowOptions {
|
|
|
38
33
|
maxDistance: number;
|
|
39
34
|
}
|
|
40
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
|
+
};
|
|
41
40
|
export type DynamicResolutionOptions = {
|
|
42
41
|
enabled?: boolean;
|
|
43
42
|
/**
|
|
@@ -178,7 +177,7 @@ export declare class RenderingView {
|
|
|
178
177
|
* initialized. The source remains visible until its static draw set exists,
|
|
179
178
|
* so WebGL fallback continues to render the normal Three.js objects.
|
|
180
179
|
*/
|
|
181
|
-
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;
|
|
182
181
|
/** @deprecated Use registerWebGpuRenderGraphExtension. */
|
|
183
182
|
registerExperimentalWebGpuRenderGraphExtension(extension: ExperimentalWebGpuRenderGraphExtension): () => void;
|
|
184
183
|
private isIntersecting;
|
|
@@ -189,25 +188,30 @@ export declare class RenderingView {
|
|
|
189
188
|
camera: THREE.Camera;
|
|
190
189
|
windowVisible: boolean;
|
|
191
190
|
/** @deprecated WebGL-specific escape hatch. Use webGlRenderer and backend-neutral RenderingView APIs. */
|
|
192
|
-
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']);
|
|
193
209
|
/** Returns the WebGL renderer only when the active backend is WebGL. */
|
|
194
210
|
get webGlRenderer(): WebGLRenderer | null;
|
|
195
211
|
registerWebGpuRenderGraphExtension(extension: ExperimentalWebGpuRenderGraphExtension): () => void;
|
|
196
|
-
rendererDepth: WebGLRenderer;
|
|
197
|
-
private composer;
|
|
198
|
-
private bloomComposer;
|
|
199
|
-
outlinePass: OutlinePass;
|
|
200
|
-
fxaaPass: ShaderPass;
|
|
201
|
-
/** Copy pass is to copy the forward rendered result into the effect composer */
|
|
202
|
-
private copyPass;
|
|
203
212
|
scene: THREE.Scene;
|
|
204
|
-
private queryScene;
|
|
205
213
|
running: boolean;
|
|
206
214
|
paused: boolean;
|
|
207
|
-
aoMaskDepthRenderTarget: WebGLRenderTarget;
|
|
208
|
-
depthRenderTarget: WebGLRenderTarget;
|
|
209
|
-
sceneColorRenderTarget: WebGLRenderTarget;
|
|
210
|
-
sceneDepthRenderTarget: WebGLRenderTarget;
|
|
211
215
|
csm: CSM | null;
|
|
212
216
|
private _fpsCap;
|
|
213
217
|
private fpsCapRevision;
|
|
@@ -222,42 +226,18 @@ export declare class RenderingView {
|
|
|
222
226
|
baseToneMapping: THREE.ToneMapping;
|
|
223
227
|
baseToneMappingExposure: number;
|
|
224
228
|
/** Tracks last update time (ms) for each CSM cascade. */
|
|
225
|
-
private csmCascadeLastUpdate?;
|
|
226
|
-
private csmUpdateInvervals;
|
|
227
229
|
private webgpuDirectionalShadowUpdateOptions;
|
|
228
230
|
private webgpuDirectionalShadowOptions;
|
|
229
|
-
aoPass: GTAOPass;
|
|
230
|
-
private bloomPass;
|
|
231
|
-
private colorPass;
|
|
232
|
-
private dofPass;
|
|
233
|
-
private lutPass;
|
|
234
|
-
private outputPass;
|
|
235
|
-
private ssrPass;
|
|
236
|
-
private volumetricFogPass;
|
|
237
231
|
private postProcessEffectId;
|
|
238
232
|
private postProcessEffects;
|
|
239
|
-
private postProcessEffectResolution;
|
|
240
|
-
private postProcessEffectUniformState;
|
|
241
|
-
private transmissionColorRenderTarget?;
|
|
242
|
-
private transmissionCopyQuad?;
|
|
243
|
-
private fquadCopySceneColor;
|
|
244
|
-
private fquadCopySceneDepth;
|
|
245
|
-
private occlusionClusters;
|
|
246
233
|
simulationTime: number;
|
|
247
234
|
simulationTimeScale: number;
|
|
248
235
|
lightVolume: LightVolume;
|
|
249
236
|
lightProbeIntensity: number;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
* pass and add to the samt MRT for bloom and other effects.
|
|
255
|
-
*
|
|
256
|
-
* An altnerative could be to have multiple bloom texture outputs that are
|
|
257
|
-
* additively combined. Normals as well could simply be overwritten for SSR.
|
|
258
|
-
*/
|
|
259
|
-
private fquadBlendAO;
|
|
260
|
-
private createAoblendQuad;
|
|
237
|
+
addCluster(cluster: Cluster): void;
|
|
238
|
+
addOverlayCamera(camera: Camera): void;
|
|
239
|
+
clearOverlayCameras(): void;
|
|
240
|
+
removeOverlayCamera(camera: Camera): void;
|
|
261
241
|
setPaused(value: boolean): void;
|
|
262
242
|
resolutionScale: number;
|
|
263
243
|
maxPixelRatio: number;
|
|
@@ -265,19 +245,7 @@ export declare class RenderingView {
|
|
|
265
245
|
private dynamicResolutionFrameTimeAverage;
|
|
266
246
|
private dynamicResolutionFrameSamples;
|
|
267
247
|
private dynamicResolutionLastAdjustmentAt;
|
|
268
|
-
private upscaleOutputPass;
|
|
269
248
|
setResolutionScale(scale: number | undefined): void;
|
|
270
|
-
private readonly unjitteredProjectionMatrix;
|
|
271
|
-
private readonly temporalJitter;
|
|
272
|
-
private readonly temporalJitterUv;
|
|
273
|
-
private readonly currentUnjitteredViewProjectionMatrix;
|
|
274
|
-
private readonly currentViewProjectionMatrix;
|
|
275
|
-
private readonly currentViewProjectionMatrixInverse;
|
|
276
|
-
private readonly previousViewProjectionMatrix;
|
|
277
|
-
private readonly temporalUpscalingFrameState;
|
|
278
|
-
private temporalUpscalingFrameIndex;
|
|
279
|
-
private hasPreviousTemporalViewProjection;
|
|
280
|
-
private projectionJitterApplied;
|
|
281
249
|
get currentResolutionScale(): number;
|
|
282
250
|
get currentRenderPixelRatio(): number;
|
|
283
251
|
get currentPresentationPixelRatio(): number;
|
|
@@ -285,10 +253,7 @@ export declare class RenderingView {
|
|
|
285
253
|
/** CSS-pixel viewport size captured by resizeRender(). */
|
|
286
254
|
getClientSize(target?: THREE.Vector2): THREE.Vector2;
|
|
287
255
|
private isUpscalingEnabled;
|
|
288
|
-
private isTemporalUpscalingEnabled;
|
|
289
256
|
resetUpscalingHistory(): void;
|
|
290
|
-
private prepareUpscalingFrame;
|
|
291
|
-
private finishUpscalingFrame;
|
|
292
257
|
private getBasePixelRatio;
|
|
293
258
|
private getBaseResolutionScale;
|
|
294
259
|
private getDynamicResolutionMinScale;
|
|
@@ -310,22 +275,10 @@ export declare class RenderingView {
|
|
|
310
275
|
removePostProcessVolume(volume: PostProcessVolume): void;
|
|
311
276
|
addPostProcessEffect(source: PostProcessMaterialSource, options?: PostProcessEffectOptions): PostProcessEffect;
|
|
312
277
|
private syncExperimentalWebGpuPostProcessEffects;
|
|
313
|
-
private getPostProcessEffectStageAnchorPass;
|
|
314
278
|
private onVisiblityChane;
|
|
315
|
-
private
|
|
316
|
-
private outlineEffect;
|
|
317
|
-
private gRenderTarget;
|
|
318
|
-
private phasedRenderPass;
|
|
319
|
-
private webGlInitialized;
|
|
320
|
-
private setupWebGlPipeline;
|
|
279
|
+
private get webGlInitialized();
|
|
321
280
|
constructor(container: HTMLElement, options?: RenderingViewOptions);
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* This finds the most relevant occlusion clusters to query.
|
|
325
|
-
* Optimizing this is a balance between minimizing the number of queries
|
|
326
|
-
* and reducing pop in.
|
|
327
|
-
*/
|
|
328
|
-
private updateRenderedOcclusionClusters;
|
|
281
|
+
private setupWebGlPipeline;
|
|
329
282
|
private fixStatsStyle;
|
|
330
283
|
setEnableOutlines(enabled: boolean): void;
|
|
331
284
|
registerWebGpuPresentationExtension(extension: WebGpuPresentationExtension): () => void;
|
|
@@ -375,12 +328,6 @@ export declare class RenderingView {
|
|
|
375
328
|
object: Object3D;
|
|
376
329
|
instanceIndex: number;
|
|
377
330
|
}[]): void;
|
|
378
|
-
private static createDepthRenderTarget;
|
|
379
|
-
/** */
|
|
380
|
-
private static createAOMaskDepthRenderTarget;
|
|
381
|
-
private createSceneColorRenderTarget;
|
|
382
|
-
private createSceneDepthRenderTarget;
|
|
383
|
-
private createGRenderTarget;
|
|
384
331
|
private setupEventListeners;
|
|
385
332
|
stop(dispose?: boolean): void;
|
|
386
333
|
/** Stops frame scheduling without releasing the renderer, GPU device, or presentation surface. */
|
|
@@ -417,53 +364,7 @@ export declare class RenderingView {
|
|
|
417
364
|
private requireInitializedBackend;
|
|
418
365
|
private activateExperimentalStaticDrawSets;
|
|
419
366
|
private disposeExperimentalStaticDrawSets;
|
|
420
|
-
private applyEnvMap;
|
|
421
367
|
setWorldEnvironment(environment: WorldEnvironmentState | null): void;
|
|
422
|
-
private applyWorldEnvironmentToWebGl;
|
|
423
|
-
private hideOccluded;
|
|
424
|
-
private setupCsm;
|
|
425
|
-
private gbufferMaterialCache;
|
|
426
|
-
private gbufferDepthPrepassMaterialCache;
|
|
427
|
-
private tbufferMaterialCache;
|
|
428
|
-
private depthPrepassMaterialCache;
|
|
429
|
-
private depthPrepassCachedMaterials;
|
|
430
|
-
private depthPrepassCachedVisibility;
|
|
431
|
-
/**
|
|
432
|
-
* If the material such as a standard material has updated properties, then we need to update
|
|
433
|
-
* the corresponding g buffer material
|
|
434
|
-
* @param source
|
|
435
|
-
* @param target
|
|
436
|
-
*/
|
|
437
|
-
private updateMaterialProperties;
|
|
438
|
-
/**
|
|
439
|
-
* Updates uniform values from source material to target material.
|
|
440
|
-
* Optimized for hot path execution in rendering loop.
|
|
441
|
-
*/
|
|
442
|
-
private updateUniformValues;
|
|
443
|
-
/**
|
|
444
|
-
* Creates target-local uniform wrapper objects for any source uniforms that the
|
|
445
|
-
* derived material does not already declare. We keep the underlying value
|
|
446
|
-
* references instead of deep-cloning them so render-target textures and other
|
|
447
|
-
* runtime-owned resources are not duplicated or warned about.
|
|
448
|
-
*/
|
|
449
|
-
private inheritCustomUniformBindings;
|
|
450
|
-
private updateMaterialCommonProperties;
|
|
451
|
-
/**
|
|
452
|
-
* After rendering the opaque scene, we will also calculate lights which updates uniforms.
|
|
453
|
-
* These need to be present on the gbuffer materials so we need to copy them afterward.
|
|
454
|
-
*/
|
|
455
|
-
private updateLightUniformValues;
|
|
456
|
-
private createGBufferMaterial;
|
|
457
|
-
private isDepthPrepassEnabled;
|
|
458
|
-
private usesSceneFeedbackUniforms;
|
|
459
|
-
private usesShaderUniform;
|
|
460
|
-
private isDepthPrepassEligibleMaterial;
|
|
461
|
-
private isDepthPrepassEligibleMesh;
|
|
462
|
-
private createDepthPrepassMaterial;
|
|
463
|
-
private applyDepthPrepassMaterials;
|
|
464
|
-
private unapplyDepthPrepassMaterials;
|
|
465
|
-
private renderDepthPrepass;
|
|
466
|
-
private updateCsm;
|
|
467
368
|
/**
|
|
468
369
|
* three.js CSM splits are normalized against CSM.maxFar. The shared WGSL
|
|
469
370
|
* material graph measures linear depth against the camera clip range, so
|
|
@@ -471,23 +372,6 @@ export declare class RenderingView {
|
|
|
471
372
|
*/
|
|
472
373
|
private syncExperimentalWebGpuCascades;
|
|
473
374
|
loop(onFrame: (deltaTime: number) => any, showStats?: boolean, onInputFrame?: (inactive: boolean) => void): void;
|
|
474
|
-
private frameGBufferMeshes;
|
|
475
|
-
private frameGBufferPhaseMasks;
|
|
476
|
-
private frameUnsupportedGBufferObjects;
|
|
477
|
-
private frameGBufferExcludedObjects;
|
|
478
|
-
private appliedGBufferMeshes;
|
|
479
|
-
private originalGBufferMaterials;
|
|
480
|
-
private originalGBufferOnBeforeRender;
|
|
481
|
-
private hiddenGBufferObjects;
|
|
482
|
-
private gBufferPhaseMaskCache;
|
|
483
|
-
private gBufferMaterialArrayCache;
|
|
484
|
-
private gBufferShadowUpdaterCache;
|
|
485
|
-
private collectGBufferRenderables;
|
|
486
|
-
private getGBufferPhaseMask;
|
|
487
|
-
private getGBufferMaterialArray;
|
|
488
|
-
private applyGBufferMaterials;
|
|
489
|
-
private unapplyGBufferMaterials;
|
|
490
|
-
private applyGBufferShadowUniformUpdater;
|
|
491
375
|
initTextures(scene?: THREE.Scene): void;
|
|
492
376
|
/**
|
|
493
377
|
* Initializes scene textures without monopolizing the host event loop.
|
|
@@ -512,57 +396,9 @@ export declare class RenderingView {
|
|
|
512
396
|
private releaseExperimentalWebGpuBackend;
|
|
513
397
|
private applyExperimentalWebGpuViewState;
|
|
514
398
|
private syncWebGpuOutlineState;
|
|
515
|
-
private depthMaterialCachedMaterials;
|
|
516
|
-
private applyDepthMaterial;
|
|
517
|
-
private unapplyDepthMaterial;
|
|
518
|
-
private renderScene;
|
|
519
399
|
getEnvTexture(texture: Texture): Texture;
|
|
520
400
|
private applyPostProcessSettings;
|
|
521
|
-
private updatePostProcessEffectUniforms;
|
|
522
|
-
private insetHeight;
|
|
523
|
-
private insetWidth;
|
|
524
|
-
private insetOffsetY;
|
|
525
|
-
private insetMargin;
|
|
526
|
-
private maxInsetCameras;
|
|
527
|
-
private overlayCameras;
|
|
528
|
-
private renderOverlay;
|
|
529
|
-
addOverlayCamera(camera: Camera): void;
|
|
530
|
-
clearOverlayCameras(): void;
|
|
531
|
-
removeOverlayCamera(camera: Camera): void;
|
|
532
|
-
private prevClearColor;
|
|
533
|
-
private hadBloom;
|
|
534
401
|
render(deltaTime?: number): void;
|
|
535
|
-
private bloomStoredMaterials;
|
|
536
|
-
private bloomHidden;
|
|
537
|
-
private hasBloom;
|
|
538
|
-
private usesSceneColorUniform;
|
|
539
|
-
private initSceneColorUniform;
|
|
540
|
-
private initDepthUniform;
|
|
541
|
-
private initNormalUniform;
|
|
542
|
-
private initShadowUniform;
|
|
543
|
-
private initLightVolumeUniform;
|
|
544
|
-
private initResolutionUniform;
|
|
545
|
-
private initAoUniform;
|
|
546
|
-
private initCustomDepthMaterial;
|
|
547
|
-
private _customDepthMaterialCache;
|
|
548
402
|
}
|
|
549
403
|
export declare function setRenderingPaused(value: boolean): void;
|
|
550
|
-
/**
|
|
551
|
-
* Checks if a given 3D object is within the camera's frustum.
|
|
552
|
-
*
|
|
553
|
-
* @param object - The 3D object to check.
|
|
554
|
-
* @param camera - The camera to check against.
|
|
555
|
-
* @returns `true` if the object is in the camera's frustum, `false` otherwise.
|
|
556
|
-
*/
|
|
557
|
-
export declare function isObjectInFrustum(object: THREE.Object3D, frustum: THREE.Frustum): boolean;
|
|
558
|
-
export declare class FogNode extends RgbaNode {
|
|
559
|
-
private readonly source;
|
|
560
|
-
private readonly fogColor;
|
|
561
|
-
constructor(source: RgbaNode, fogColor?: IRgbNode);
|
|
562
|
-
compile(c: any): {
|
|
563
|
-
pars: string;
|
|
564
|
-
chunk: string;
|
|
565
|
-
out: string;
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
404
|
//# sourceMappingURL=rendering.d.ts.map
|