@hology/core 0.0.267 → 0.0.268
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/gameplay/services/render.d.ts +2 -1
- package/dist/gameplay/services/render.js +1 -1
- package/dist/rendering/node-material-webgpu-resolver.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +2 -0
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +13 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/materializer.d.ts +2 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/shader/builtin/standard-shader.d.ts +23 -0
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader-nodes/scene-sample.d.ts +3 -0
- package/dist/shader-nodes/scene-sample.js +1 -1
- package/dist/test/frame-audio-listener.test.d.ts +2 -0
- package/dist/test/frame-audio-listener.test.js +4 -0
- package/dist/test/node-material-webgpu-resolver.test.js +1 -1
- package/dist/utils/three/frame-audio-listener.d.ts +19 -0
- package/dist/utils/three/frame-audio-listener.js +4 -0
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Camera } from "three";
|
|
2
|
+
import { FrameAudioListener } from '../../utils/three/frame-audio-listener.js';
|
|
2
3
|
import { RenderingView } from '../../rendering.js';
|
|
3
4
|
import { BehaviorSubject, Observable } from "rxjs";
|
|
4
5
|
import * as THREE from "three";
|
|
@@ -24,7 +25,7 @@ export declare class ViewController {
|
|
|
24
25
|
private view;
|
|
25
26
|
private readonly tick;
|
|
26
27
|
private readonly lateTick;
|
|
27
|
-
readonly audioListener:
|
|
28
|
+
readonly audioListener: FrameAudioListener;
|
|
28
29
|
readonly pausedChanged: BehaviorSubject<boolean>;
|
|
29
30
|
readonly mutedChanged: BehaviorSubject<boolean>;
|
|
30
31
|
private _muted;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{Service as a}from"typedi";import{Camera as i}from"three";import{RenderingView as r}from"../../rendering.js";import{BehaviorSubject as s,Subject as n,takeUntil as h}from"rxjs";import*as o from"three";import{GameTimeScheduler as m}from"./game-time-scheduler.js";import{createCameraShakeSample as u,resetCameraShakeSample as l,sampleCameraShake as c}from"./camera-shake.js";export{defaultPostProcessEffectStage,postProcessEffectStages}from"../../rendering/post-process-effect.js";let d=class{constructor(e){this.view=e,this.tick=new n,this.lateTick=new n,this.audioListener=new o.AudioListener,this.pausedChanged=new s(!1),this.mutedChanged=new s(!1),this._muted=!1,this._masterVolume=1,this._cameraShakeIntensity=1,this._timeScale=1,this._hitStopRemaining=0,this.scheduler=new m,this.cameraOverrideId=0,this.cameraOverrides=[],this.cameraShakeId=0,this.gameplayCameraShakes=[],this.cameraShakeContributions=new Map,this.presentationCamera=null,this.accumulatedCameraShakeSample=u(),this.scratchCameraShakeSample=u(),this._updateFrameIndex=0,this.outlined=[],this.baseCamera=e.camera,this.sourceCamera=e.camera,e.onLoop(e=>{this.handleFrame(e)}),e.camera.add(this.audioListener),window.hology_view=this}get activeBackend(){return this.view.activeBackend}get requestedBackend(){return this.view.requestedBackend}get vfxBackendPreference(){return this.view.vfxBackendPreference}get webgpuVfxInstancesPerTemplate(){return this.view.webgpuVfxInstancesPerTemplate}get webgpuVfxTemplateMemoryBudgetBytes(){return this.view.webgpuVfxTemplateMemoryBudgetBytes}get webgpuVfxWorldMemoryBudgetBytes(){return this.view.webgpuVfxWorldMemoryBudgetBytes}get webgpuVfxColdTemplateSeconds(){return this.view.webgpuVfxColdTemplateSeconds}get webGpuDevice(){return this.view.webGpuDevice}get experimentalWebGpuDevice(){return this.webGpuDevice}registerWebGpuRenderGraphExtension(e){return this.view.registerWebGpuRenderGraphExtension(e)}registerExperimentalWebGpuRenderGraphExtension(e){return this.registerWebGpuRenderGraphExtension(e)}get updateFrameIndex(){return this._updateFrameIndex}handleFrame(e){this._updateFrameIndex++;let t=this._timeScale,a=0;this._hitStopRemaining>0?(this._hitStopRemaining-=1e3*e,this._hitStopRemaining<=0&&(this._hitStopRemaining=0),t=0):a=e*this._timeScale,this.advanceGameplayCameraShakes(a),this.tick.next(a),this.scheduler.update(1e3*a),this.lateTick.next(a),this.view.simulationTimeScale=t,this.refreshCameraPresentation()}set timeScale(e){this._timeScale=Math.max(0,e)}get timeScale(){return this._timeScale}get time(){return performance.now()/1e3}applyHitStop(e){this._hitStopRemaining=Math.max(this._hitStopRemaining,e)}set fpsCap(e){this.view.fpsCap=e}get fpsCap(){return this.view.fpsCap}set showStats(e){this.view.showStats=e}get showStats(){return this.view.showStats}setProfilingEnabled(e){this.view.setProfilingEnabled(e)}getLastFrameProfile(){return this.view.getLastFrameProfile()}setLightVolume(e){this.view.lightVolume=e}getLightVolume(){return this.view.lightVolume}addPostProcessVolume(e){this.view.addPostProcessVolume(e)}removePostProcessVolume(e){this.view.removePostProcessVolume(e)}addPostProcessEffect(e,t){return this.view.addPostProcessEffect(e,t)}onUpdate(e){return null==e?this.tick:this.tick.pipe(h(e.disposed))}onLateUpdate(e){return null==e?this.lateTick:this.lateTick.pipe(h(e.disposed))}setCamera(e){const t=e instanceof i?e:e.camera.instance;this.baseCamera=t,0===this.cameraOverrides.length&&(this.sourceCamera=t,this.refreshCameraPresentation())}getCamera(){return this.view.camera}getSourceCamera(){return this.sourceCamera}getBaseCamera(){return this.baseCamera}applyCameraShake(e){const t=function(e){return{duration:Math.max(0,e.duration??0),attack:e.attack??0,decay:e.decay??0,frequency:e.frequency??24,positionAmplitude:e.positionAmplitude?[...e.positionAmplitude]:[0,0,0],rotationAmplitude:e.rotationAmplitude?[...e.rotationAmplitude]:[0,0,0],seed:e.seed}}(e);if(t.duration<=0)return{release:()=>{}};const a={id:++this.cameraShakeId,request:t,elapsedTime:0,seedOverride:t.seed};this.gameplayCameraShakes.push(a),this.refreshCameraPresentation();let i=!1;return{release:()=>{i||(i=!0,this.releaseGameplayCameraShake(a.id))}}}setCameraShakeContribution(e,t,a,i,r){if(a.duration<=0)return void this.removeCameraShakeContribution(e,t);let s=this.cameraShakeContributions.get(e);s||(s=new Map,this.cameraShakeContributions.set(e,s));const n=s.get(t);n?(n.request=a,n.elapsedTime=Math.max(0,i),n.seedOverride=r):s.set(t,{key:t,request:a,elapsedTime:Math.max(0,i),seedOverride:r}),this.refreshCameraPresentation()}removeCameraShakeContribution(e,t){const a=this.cameraShakeContributions.get(e);a?.delete(t)&&(0===a.size&&this.cameraShakeContributions.delete(e),this.refreshCameraPresentation())}clearCameraShakeContributionsForOwner(e){this.cameraShakeContributions.delete(e)&&this.refreshCameraPresentation()}pushCameraOverride(e,t,a=0){const i={id:++this.cameraOverrideId,camera:e,owner:t,priority:a};this.cameraOverrides.push(i),this.applyTopCameraOverride();let r=!1;return{release:()=>{r||(r=!0,this.releaseCameraOverrideEntry(i))}}}releaseCameraOverridesForOwner(e){const t=this.cameraOverrides.filter(t=>t.owner!==e);t.length!==this.cameraOverrides.length&&(this.cameraOverrides=t,this.applyTopCameraOverride())}releaseCameraOverrideEntry(e){const t=this.cameraOverrides.indexOf(e);-1!==t&&(this.cameraOverrides.splice(t,1),this.applyTopCameraOverride())}applyTopCameraOverride(){const e=this.getTopCameraOverride();this.sourceCamera=e?.camera??this.baseCamera,this.refreshCameraPresentation()}getTopCameraOverride(){let e;for(const t of this.cameraOverrides)(!e||t.priority>e.priority||t.priority===e.priority&&t.id>e.id)&&(e=t);return e}applyRenderedCamera(e){this.view.camera!==e&&this.view.setCamera(e),e.add(this.audioListener)}releaseGameplayCameraShake(e){const t=this.gameplayCameraShakes.findIndex(t=>t.id===e);-1!==t&&(this.gameplayCameraShakes.splice(t,1),this.refreshCameraPresentation())}advanceGameplayCameraShakes(e){if(!(e<=0||0===this.gameplayCameraShakes.length))for(let t=this.gameplayCameraShakes.length-1;t>=0;t--){const a=this.gameplayCameraShakes[t];a.elapsedTime+=e,a.elapsedTime>a.request.duration&&this.gameplayCameraShakes.splice(t,1)}}refreshCameraPresentation(){if(!this.hasActiveCameraShake())return void this.applyRenderedCamera(this.sourceCamera);const e=this.ensurePresentationCamera();this.copyCameraState(this.sourceCamera,e),this.accumulateCameraShakeSamples(),this.applyCameraShakeSample(e),this.applyRenderedCamera(e)}hasActiveCameraShake(){if(this.gameplayCameraShakes.length>0)return!0;for(const e of this.cameraShakeContributions.values())if(e.size>0)return!0;return!1}ensurePresentationCamera(){return this.presentationCamera||(this.presentationCamera=new o.PerspectiveCamera,this.presentationCamera.name="View Controller Presentation Camera"),this.presentationCamera}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(S)),t.quaternion.copy(e.getWorldQuaternion(w)),t.scale.copy(e.getWorldScale(f)),t.layers.mask=e.layers.mask,e instanceof o.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect,t.zoom=e.zoom,t.focus=e.focus,t.filmGauge=e.filmGauge,t.filmOffset=e.filmOffset,t.view=null==e.view?null:{enabled:e.view.enabled,fullWidth:e.view.fullWidth,fullHeight:e.view.fullHeight,offsetX:e.view.offsetX,offsetY:e.view.offsetY,width:e.view.width,height:e.view.height},t.updateProjectionMatrix()):(t.projectionMatrix.copy(e.projectionMatrix),t.projectionMatrixInverse.copy(e.projectionMatrixInverse))}accumulateCameraShakeSamples(){l(this.accumulatedCameraShakeSample);for(let e=0;e<this.gameplayCameraShakes.length;e++)this.accumulateCameraShakeEntry(this.gameplayCameraShakes[e]);for(const e of this.cameraShakeContributions.values())for(const t of e.values())this.accumulateCameraShakeEntry(t)}accumulateCameraShakeEntry(e){const t=c(e.request,e.elapsedTime,this.scratchCameraShakeSample,e.seedOverride);if(t)for(let e=0;e<3;e++)this.accumulatedCameraShakeSample.position[e]+=t.position[e],this.accumulatedCameraShakeSample.rotation[e]+=t.rotation[e]}applyCameraShakeSample(e){k.copy(e.quaternion),y.set(this.accumulatedCameraShakeSample.position[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[2]*this._cameraShakeIntensity),y.applyQuaternion(k),e.position.add(y),x.set(this.accumulatedCameraShakeSample.rotation[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[2]*this._cameraShakeIntensity),P.setFromEuler(x),e.quaternion.copy(k).multiply(P),e.updateMatrixWorld(!0)}setMuted(e){this._muted=e,this.applyAudioGain(),this.mutedChanged.next(e)}getMuted(){return this._muted}set masterVolume(e){this._masterVolume=Math.min(Math.max(e,0),1),this.applyAudioGain()}get masterVolume(){return this._masterVolume}set cameraShakeIntensity(e){this._cameraShakeIntensity=Math.min(Math.max(e,0),1),this.refreshCameraPresentation()}get cameraShakeIntensity(){return this._cameraShakeIntensity}applyAudioGain(){this.audioListener.gain.gain.setValueAtTime(this._muted?0:this._masterVolume,this.audioListener.context.currentTime)}setOutlined(e){this.outlined.length=0;const t=this.outlined;for(let a=0;a<e.length;a++)t[a]=e[a];this.view.setSelectedObjects(t),this.view.setEnableOutlines(e.length>0)}getOutlined(){return this.outlined}addOutlined(e){this.outlined.includes(e)||(this.outlined.push(e),this.view.setSelectedObjects(this.outlined),this.view.setEnableOutlines(!0))}removeOutlined(e){const t=this.outlined.indexOf(e);-1!==t&&(this.outlined.splice(t,1),this.view.setSelectedObjects(this.outlined))}setOutlineColor(e){this.view.outlinePass?.visibleEdgeColor.copy(e)}getOutlineColor(){return this.view.outlinePass?.visibleEdgeColor}setOutlineThickness(e){this.view.outlinePass.edgeThickness=e}getOutlineThickness(){return this.view.outlinePass.edgeThickness}get htmlElement(){return this.view.container}getViewportSize(e=g){return this.view.getClientSize(e)}get paused(){return this.view.paused}set paused(e){e!=this.paused&&(e?this.pauseRendering():this.unpauseRendering())}pauseRendering(){this.view.paused=!0,this.pausedChanged.next(this.view.paused),this.scheduler.pause()}unpauseRendering(){this.view.paused=!1,this.pausedChanged.next(this.view.paused),this.scheduler.resume()}setInterval(e,t,a){return this.scheduler.setInterval(e,t,a)}clearInterval(e){this.scheduler.clearInterval(e)}dispose(e=!0){e&&this.view.running&&this.view.stop(),this.scheduler.dispose(),this.cameraOverrides.length=0,this.gameplayCameraShakes.length=0,this.cameraShakeContributions.clear(),this.audioListener.removeFromParent(),this.tick.complete(),this.lateTick.complete(),this.paused=!0}createTimer(e){return this.scheduler.createTimer(e)}getScreenPosition(e,t=C,a=this.getViewportSize()){const i=this.getCamera();return p.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),i instanceof o.PerspectiveCamera&&(v.setFromProjectionMatrix(p),!v.containsPoint(e))?null:(t.copy(e),t.project(i),t.x=(t.x+1)/2*a.x,t.y=(1-t.y)/2*a.y,t)}};d=e([a(),t("design:paramtypes",[r])],d);export{d as ViewController};const p=new o.Matrix4,C=new o.Vector3,g=new o.Vector2,v=new o.Frustum,S=new o.Vector3,f=new o.Vector3,w=new o.Quaternion,k=new o.Quaternion,y=new o.Vector3,x=new o.Euler(0,0,0,"XYZ"),P=new o.Quaternion;/*
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{Service as a}from"typedi";import{Camera as i}from"three";import{FrameAudioListener as r}from"../../utils/three/frame-audio-listener.js";import{RenderingView as s}from"../../rendering.js";import{BehaviorSubject as n,Subject as h,takeUntil as o}from"rxjs";import*as m from"three";import{GameTimeScheduler as u}from"./game-time-scheduler.js";import{createCameraShakeSample as l,resetCameraShakeSample as c,sampleCameraShake as d}from"./camera-shake.js";export{defaultPostProcessEffectStage,postProcessEffectStages}from"../../rendering/post-process-effect.js";let p=class{constructor(e){this.view=e,this.tick=new h,this.lateTick=new h,this.audioListener=new r,this.pausedChanged=new n(!1),this.mutedChanged=new n(!1),this._muted=!1,this._masterVolume=1,this._cameraShakeIntensity=1,this._timeScale=1,this._hitStopRemaining=0,this.scheduler=new u,this.cameraOverrideId=0,this.cameraOverrides=[],this.cameraShakeId=0,this.gameplayCameraShakes=[],this.cameraShakeContributions=new Map,this.presentationCamera=null,this.accumulatedCameraShakeSample=l(),this.scratchCameraShakeSample=l(),this._updateFrameIndex=0,this.outlined=[],this.baseCamera=e.camera,this.sourceCamera=e.camera,e.onLoop(e=>{this.handleFrame(e)}),e.camera.add(this.audioListener),window.hology_view=this}get activeBackend(){return this.view.activeBackend}get requestedBackend(){return this.view.requestedBackend}get vfxBackendPreference(){return this.view.vfxBackendPreference}get webgpuVfxInstancesPerTemplate(){return this.view.webgpuVfxInstancesPerTemplate}get webgpuVfxTemplateMemoryBudgetBytes(){return this.view.webgpuVfxTemplateMemoryBudgetBytes}get webgpuVfxWorldMemoryBudgetBytes(){return this.view.webgpuVfxWorldMemoryBudgetBytes}get webgpuVfxColdTemplateSeconds(){return this.view.webgpuVfxColdTemplateSeconds}get webGpuDevice(){return this.view.webGpuDevice}get experimentalWebGpuDevice(){return this.webGpuDevice}registerWebGpuRenderGraphExtension(e){return this.view.registerWebGpuRenderGraphExtension(e)}registerExperimentalWebGpuRenderGraphExtension(e){return this.registerWebGpuRenderGraphExtension(e)}get updateFrameIndex(){return this._updateFrameIndex}handleFrame(e){this._updateFrameIndex++;let t=this._timeScale,a=0;this._hitStopRemaining>0?(this._hitStopRemaining-=1e3*e,this._hitStopRemaining<=0&&(this._hitStopRemaining=0),t=0):a=e*this._timeScale,this.advanceGameplayCameraShakes(a),this.tick.next(a),this.scheduler.update(1e3*a),this.lateTick.next(a),this.view.simulationTimeScale=t,this.refreshCameraPresentation()}set timeScale(e){this._timeScale=Math.max(0,e)}get timeScale(){return this._timeScale}get time(){return performance.now()/1e3}applyHitStop(e){this._hitStopRemaining=Math.max(this._hitStopRemaining,e)}set fpsCap(e){this.view.fpsCap=e}get fpsCap(){return this.view.fpsCap}set showStats(e){this.view.showStats=e}get showStats(){return this.view.showStats}setProfilingEnabled(e){this.view.setProfilingEnabled(e)}getLastFrameProfile(){return this.view.getLastFrameProfile()}setLightVolume(e){this.view.lightVolume=e}getLightVolume(){return this.view.lightVolume}addPostProcessVolume(e){this.view.addPostProcessVolume(e)}removePostProcessVolume(e){this.view.removePostProcessVolume(e)}addPostProcessEffect(e,t){return this.view.addPostProcessEffect(e,t)}onUpdate(e){return null==e?this.tick:this.tick.pipe(o(e.disposed))}onLateUpdate(e){return null==e?this.lateTick:this.lateTick.pipe(o(e.disposed))}setCamera(e){const t=e instanceof i?e:e.camera.instance;this.baseCamera=t,0===this.cameraOverrides.length&&(this.sourceCamera=t,this.refreshCameraPresentation())}getCamera(){return this.view.camera}getSourceCamera(){return this.sourceCamera}getBaseCamera(){return this.baseCamera}applyCameraShake(e){const t=function(e){return{duration:Math.max(0,e.duration??0),attack:e.attack??0,decay:e.decay??0,frequency:e.frequency??24,positionAmplitude:e.positionAmplitude?[...e.positionAmplitude]:[0,0,0],rotationAmplitude:e.rotationAmplitude?[...e.rotationAmplitude]:[0,0,0],seed:e.seed}}(e);if(t.duration<=0)return{release:()=>{}};const a={id:++this.cameraShakeId,request:t,elapsedTime:0,seedOverride:t.seed};this.gameplayCameraShakes.push(a),this.refreshCameraPresentation();let i=!1;return{release:()=>{i||(i=!0,this.releaseGameplayCameraShake(a.id))}}}setCameraShakeContribution(e,t,a,i,r){if(a.duration<=0)return void this.removeCameraShakeContribution(e,t);let s=this.cameraShakeContributions.get(e);s||(s=new Map,this.cameraShakeContributions.set(e,s));const n=s.get(t);n?(n.request=a,n.elapsedTime=Math.max(0,i),n.seedOverride=r):s.set(t,{key:t,request:a,elapsedTime:Math.max(0,i),seedOverride:r}),this.refreshCameraPresentation()}removeCameraShakeContribution(e,t){const a=this.cameraShakeContributions.get(e);a?.delete(t)&&(0===a.size&&this.cameraShakeContributions.delete(e),this.refreshCameraPresentation())}clearCameraShakeContributionsForOwner(e){this.cameraShakeContributions.delete(e)&&this.refreshCameraPresentation()}pushCameraOverride(e,t,a=0){const i={id:++this.cameraOverrideId,camera:e,owner:t,priority:a};this.cameraOverrides.push(i),this.applyTopCameraOverride();let r=!1;return{release:()=>{r||(r=!0,this.releaseCameraOverrideEntry(i))}}}releaseCameraOverridesForOwner(e){const t=this.cameraOverrides.filter(t=>t.owner!==e);t.length!==this.cameraOverrides.length&&(this.cameraOverrides=t,this.applyTopCameraOverride())}releaseCameraOverrideEntry(e){const t=this.cameraOverrides.indexOf(e);-1!==t&&(this.cameraOverrides.splice(t,1),this.applyTopCameraOverride())}applyTopCameraOverride(){const e=this.getTopCameraOverride();this.sourceCamera=e?.camera??this.baseCamera,this.refreshCameraPresentation()}getTopCameraOverride(){let e;for(const t of this.cameraOverrides)(!e||t.priority>e.priority||t.priority===e.priority&&t.id>e.id)&&(e=t);return e}applyRenderedCamera(e){this.view.camera!==e&&this.view.setCamera(e),e.add(this.audioListener)}releaseGameplayCameraShake(e){const t=this.gameplayCameraShakes.findIndex(t=>t.id===e);-1!==t&&(this.gameplayCameraShakes.splice(t,1),this.refreshCameraPresentation())}advanceGameplayCameraShakes(e){if(!(e<=0||0===this.gameplayCameraShakes.length))for(let t=this.gameplayCameraShakes.length-1;t>=0;t--){const a=this.gameplayCameraShakes[t];a.elapsedTime+=e,a.elapsedTime>a.request.duration&&this.gameplayCameraShakes.splice(t,1)}}refreshCameraPresentation(){if(!this.hasActiveCameraShake())return void this.applyRenderedCamera(this.sourceCamera);const e=this.ensurePresentationCamera();this.copyCameraState(this.sourceCamera,e),this.accumulateCameraShakeSamples(),this.applyCameraShakeSample(e),this.applyRenderedCamera(e)}hasActiveCameraShake(){if(this.gameplayCameraShakes.length>0)return!0;for(const e of this.cameraShakeContributions.values())if(e.size>0)return!0;return!1}ensurePresentationCamera(){return this.presentationCamera||(this.presentationCamera=new m.PerspectiveCamera,this.presentationCamera.name="View Controller Presentation Camera"),this.presentationCamera}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(f)),t.quaternion.copy(e.getWorldQuaternion(k)),t.scale.copy(e.getWorldScale(w)),t.layers.mask=e.layers.mask,e instanceof m.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect,t.zoom=e.zoom,t.focus=e.focus,t.filmGauge=e.filmGauge,t.filmOffset=e.filmOffset,t.view=null==e.view?null:{enabled:e.view.enabled,fullWidth:e.view.fullWidth,fullHeight:e.view.fullHeight,offsetX:e.view.offsetX,offsetY:e.view.offsetY,width:e.view.width,height:e.view.height},t.updateProjectionMatrix()):(t.projectionMatrix.copy(e.projectionMatrix),t.projectionMatrixInverse.copy(e.projectionMatrixInverse))}accumulateCameraShakeSamples(){c(this.accumulatedCameraShakeSample);for(let e=0;e<this.gameplayCameraShakes.length;e++)this.accumulateCameraShakeEntry(this.gameplayCameraShakes[e]);for(const e of this.cameraShakeContributions.values())for(const t of e.values())this.accumulateCameraShakeEntry(t)}accumulateCameraShakeEntry(e){const t=d(e.request,e.elapsedTime,this.scratchCameraShakeSample,e.seedOverride);if(t)for(let e=0;e<3;e++)this.accumulatedCameraShakeSample.position[e]+=t.position[e],this.accumulatedCameraShakeSample.rotation[e]+=t.rotation[e]}applyCameraShakeSample(e){y.copy(e.quaternion),x.set(this.accumulatedCameraShakeSample.position[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.position[2]*this._cameraShakeIntensity),x.applyQuaternion(y),e.position.add(x),P.set(this.accumulatedCameraShakeSample.rotation[0]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[1]*this._cameraShakeIntensity,this.accumulatedCameraShakeSample.rotation[2]*this._cameraShakeIntensity),b.setFromEuler(P),e.quaternion.copy(y).multiply(b),e.updateMatrixWorld(!0)}setMuted(e){this._muted=e,this.applyAudioGain(),this.mutedChanged.next(e)}getMuted(){return this._muted}set masterVolume(e){this._masterVolume=Math.min(Math.max(e,0),1),this.applyAudioGain()}get masterVolume(){return this._masterVolume}set cameraShakeIntensity(e){this._cameraShakeIntensity=Math.min(Math.max(e,0),1),this.refreshCameraPresentation()}get cameraShakeIntensity(){return this._cameraShakeIntensity}applyAudioGain(){this.audioListener.gain.gain.setValueAtTime(this._muted?0:this._masterVolume,this.audioListener.context.currentTime)}setOutlined(e){this.outlined.length=0;const t=this.outlined;for(let a=0;a<e.length;a++)t[a]=e[a];this.view.setSelectedObjects(t),this.view.setEnableOutlines(e.length>0)}getOutlined(){return this.outlined}addOutlined(e){this.outlined.includes(e)||(this.outlined.push(e),this.view.setSelectedObjects(this.outlined),this.view.setEnableOutlines(!0))}removeOutlined(e){const t=this.outlined.indexOf(e);-1!==t&&(this.outlined.splice(t,1),this.view.setSelectedObjects(this.outlined))}setOutlineColor(e){this.view.outlinePass?.visibleEdgeColor.copy(e)}getOutlineColor(){return this.view.outlinePass?.visibleEdgeColor}setOutlineThickness(e){this.view.outlinePass.edgeThickness=e}getOutlineThickness(){return this.view.outlinePass.edgeThickness}get htmlElement(){return this.view.container}getViewportSize(e=v){return this.view.getClientSize(e)}get paused(){return this.view.paused}set paused(e){e!=this.paused&&(e?this.pauseRendering():this.unpauseRendering())}pauseRendering(){this.view.paused=!0,this.pausedChanged.next(this.view.paused),this.scheduler.pause()}unpauseRendering(){this.view.paused=!1,this.pausedChanged.next(this.view.paused),this.scheduler.resume()}setInterval(e,t,a){return this.scheduler.setInterval(e,t,a)}clearInterval(e){this.scheduler.clearInterval(e)}dispose(e=!0){e&&this.view.running&&this.view.stop(),this.scheduler.dispose(),this.cameraOverrides.length=0,this.gameplayCameraShakes.length=0,this.cameraShakeContributions.clear(),this.audioListener.disposePoseUpdates(),this.audioListener.removeFromParent(),this.tick.complete(),this.lateTick.complete(),this.paused=!0}createTimer(e){return this.scheduler.createTimer(e)}getScreenPosition(e,t=g,a=this.getViewportSize()){const i=this.getCamera();return C.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse),i instanceof m.PerspectiveCamera&&(S.setFromProjectionMatrix(C),!S.containsPoint(e))?null:(t.copy(e),t.project(i),t.x=(t.x+1)/2*a.x,t.y=(1-t.y)/2*a.y,t)}};p=e([a(),t("design:paramtypes",[s])],p);export{p as ViewController};const C=new m.Matrix4,g=new m.Vector3,v=new m.Vector2,S=new m.Frustum,f=new m.Vector3,w=new m.Vector3,k=new m.Quaternion,y=new m.Quaternion,x=new m.Vector3,P=new m.Euler(0,0,0,"XYZ"),b=new m.Quaternion;/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as e from"three";import{compileNodeWebGpuFullscreen as t,compileNodeShaderMaterialForWebGpu as a,NodeShaderMaterial as i,webGpuRendererBindings as n,webGpuTiledRendererBindings as s,textureSampler2d as o,float as r,length as l,max as u,rgba as p,isWgslCompiler as m,isWgslFragmentCompiler as c,sqrt as f,normalize as d,transformed as h,uniformFloat as M,uniforms as v,vec4 as y,Vec3Node as g,toonMaterial as V}from"three-shader-graph";import{StandardShader as w}from"../shader/builtin/standard-shader.js";import{LambertShader as I}from"../shader/builtin/lambert-shader.js";import{ToonShader as S}from"../shader/builtin/toon-shader.js";import{UnlitShader as x}from"../shader/builtin/unlit-shader.js";import{SpriteShader as T}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as E}from"../shader-nodes/time.js";import{depthUniformName as b,farUniformName as U,nearUniformName as A,resolutionUniformName as C,sceneNormalUniformName as W}from"../shader-nodes/depth.js";import{sceneMapUniformName as N}from"../shader-nodes/scene-sample.js";const k={...n,uniformExpressions:{...n.uniformExpressions,ambientLightColor:{type:"vec3",expression:"rendererAmbientLight()"},[E]:{type:"float",expression:"rendererElapsedTime()"},[A]:{type:"float",expression:"rendererCameraNear()"},[U]:{type:"float",expression:"rendererCameraFar()"},[C]:{type:"vec2",expression:"rendererViewportSize()"}},sceneTextures:{[N]:{semantic:"sceneColor",sampleType:"float"},[b]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};class L extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalPositionNode can only be used in the vertex stage");const t=`outline_local_position_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight).xyz;\n#else\n let ${t} = input.position;\n#endif`,out:t}}}class R extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalNormalNode can only be used in the vertex stage");const t=`outline_local_normal_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${t} = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let ${t} = input.normal;\n#endif`,out:t}}}export function setMaterialUniformValuesAutoUpdate(e,t){e.uniformValuesAutoUpdate=t}export function markMaterialUniformValuesNeedUpdate(e){const t=e;"uniformValuesNeedsUpdate"in t?t.uniformValuesNeedsUpdate=!0:t.uniformValuesAutoVersion=(t.uniformValuesAutoVersion??0)+1}function D(e){return!1!==e.uniformValuesAutoUpdate}function F(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const O=new WeakMap,j=new WeakMap;export function createNodeMaterialSignature(e){const t=j.get(e);if(null!=t)return t;const a=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return j.set(e,a),a}export class NodeMaterialWebGpuResolver{constructor(e,t,a){this.webGpu=e,this.mrtResolver=t,this.environmentTextureResolver=a,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.outlineMaterials=new WeakMap,this.outlineUniformVersions=new WeakMap,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const t=e?.texture??null,a=e?.intensity??0;if(this.worldEnvironmentTexture!==t||this.worldEnvironmentIntensity!==a){if(this.worldEnvironmentTexture!==t)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=a,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=t,this.worldEnvironmentIntensity=a}}resolve(e,t=void 0){let n,o=!1;if(e instanceof i)n=e,this.observeNodeMaterial(n);else{const t=this.getOrCreateMappedNodeMaterial(e);if(null==t)return;n=t,o=!0}if("outline"===t){if(null==n.outputAlbedo)return;o&&G(e,n),n.userData.outlineParameters=e.userData?.outlineParameters,n=this.getOrCreateOutlineMaterial(n),o=!1}n.visible=e.visible,o&&(n.userData.receiveDecals=e.userData.receiveDecals);const r=t??"default",l=this.cache.get(n),u=l?.get(r);if(o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision){const t=D(e),a=F(e);return u.material.uniformValuesAutoUpdate=t,this.syncInheritedWorldEnvironmentSource(n,u),t||u.sourceUniformValuesAutoVersion!==a?(G(e,n),u.compiled.syncLiveUniforms(u.material.uniforms),$(n,u.material.uniforms),z(n,u.material),u.sourceUniformValuesAutoVersion=a,t||(u.material.uniformValuesNeedsUpdate=!0),u.material):u.material}if(!o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision&&B(n,u.compiled))return this.syncInheritedWorldEnvironmentSource(n,u),P(n,u),u.material;o&&G(e,n);const p=this.prepareWorldEnvironment(n),m=this.getNodeMaterialSignature(n,p);if(u?.signature===m&&B(n,u.compiled))return o?(u.material.uniformValuesAutoUpdate=D(e),u.compiled.syncLiveUniforms(u.material.uniforms),$(n,u.material.uniforms),z(n,u.material),u.sourceUniformValuesAutoVersion=F(e),u.material.uniformValuesAutoUpdate||(u.material.uniformValuesNeedsUpdate=!0)):P(n,u,!0),u.sourceVersion=e.version,u.worldEnvironmentRevision=this.worldEnvironmentRevision,u.material;try{const i=this.mrtResolver?.(n,t),c=a(n,"opaque"===t?{...k,arrays:s.arrays}:k,i),f=new this.webGpu.WGSLShaderMaterial({vertexShader:c.vertexShader,fragmentShader:c.fragmentShader,depthVertexShader:c.depthVertexShader,depthFragmentShader:c.depthFragmentShader,pointShadowVertexShader:c.pointShadowVertexShader,pointShadowFragmentShader:c.pointShadowFragmentShader,uniforms:c.uniforms,textures:c.textures,sceneTextures:c.sceneTextures,graphTextures:c.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(c.vertexAttributes),uniformValuesAutoUpdate:o?D(e):n.uniformValuesAutoUpdate,transparent:c.renderState?.transparent,alphaTest:c.renderState?.alphaTest,depthTest:c.renderState?.depthTest,depthWrite:c.renderState?.depthWrite,side:c.renderState?.side,wireframe:n.wireframe});f.name=e.name||n.name||e.uuid,f.userData.pipelineOrigin={assetId:e.userData.assetId??n.userData.assetId,assetName:e.userData.assetName??n.userData.assetName,sourceUuid:e.uuid,sourceName:e.name,sourceType:e.type,sourceVersion:e.version},f.uniformValuesAutoUpdate=o?D(e):n.uniformValuesAutoUpdate,function(e,t){if(null==e)return;Object.assign(t,e)}(c.renderState,f),null!=u&&(u.material.dispose(),this.cacheValues.delete(u));const d={signature:m,compiled:c,material:f,inheritsWorldEnvironment:p,sourceVersion:e.version,sourceUniformValuesAutoVersion:o?F(e):n.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},h=l??new Map;return h.set(r,d),this.cache.set(n,h),this.cacheValues.add(d),$(n,f.uniforms),z(n,f),f}catch(e){let t=this.failedSignatures.get(n);if(null==t&&(t=new Map,this.failedSignatures.set(n,t)),t.get(r)!==m){t.set(r,m);const a=e instanceof Error?e.message:String(e),i=n.name||n.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${i}": ${a}`,{material:n,error:e})}return}}getOrCreateOutlineMaterial(t){let a=this.outlineMaterials.get(t);if(null==a){const n=t.nodeMaterialDefinition,s=t.outputAlbedo;if(null==s)throw new Error("Cannot derive an outline material without an albedo output");const o=M("outlineThickness",.003),m=M("outlineDarkening",.65),c=M("outlineAlpha",1),g=new L(h.position.xyz),w=new R(h.normal),I=n.transform?.multiplyVec(y(g,1))??y(g,1),S=v.modelViewMatrix.multiplyVec(I),x=d(v.normalMatrix.multiplyVec(w)),T=f(u(l(S.xyz),r(1e-4))).multiply(.5),E=S.xyz.add(x.multiplyScalar(o.multiply(T))),b=v.projectionMatrix.multiplyVec(S),U=v.projectionMatrix.multiplyVec(y(E,1)),A=(n.position??b).add(U.subtract(b)),C=p(V({color:s.rgb.multiplyScalar(r(1).subtract(m))}),t.outputOpacity.multiply(c));a=new i({color:C,position:A,opacity:t.outputOpacity,discard:n.discard,alphaTest:t.alphaTest,transparent:!0,fog:!1,outputEncoding:n.outputEncoding,uniforms:n.uniforms,uniformNodes:n.uniformNodes}),a.side=e.BackSide,a.depthTest=!0,a.depthWrite=!0,this.outlineMaterials.set(t,a),this.outlineUniformVersions.delete(t)}const n=t.userData?.outlineParameters,s=n?.thickness??.003,o=e.MathUtils.clamp(n?.darkening??.65,0,1),m=e.MathUtils.clamp(n?.alpha??t.opacity,0,1),c=a.uniforms.outlineThickness.value!==s||a.uniforms.outlineDarkening.value!==o||a.uniforms.outlineAlpha.value!==m;a.uniforms.outlineThickness.value=s,a.uniforms.outlineDarkening.value=o,a.uniforms.outlineAlpha.value=m,a.userData.outlineSource=t,a.uniformValuesAutoUpdate=t.uniformValuesAutoUpdate;let g=this.outlineUniformVersions.get(t);const w=t.uniformValuesAutoUpdate||null==g||g.version!==t.uniformValuesAutoVersion||g.uniforms!==t.uniforms;if(w){for(const e in t.uniforms)null!=a.uniforms[e]&&(a.uniforms[e].value=t.uniforms[e].value);g?(g.version=t.uniformValuesAutoVersion,g.uniforms=t.uniforms):(g={version:t.uniformValuesAutoVersion,uniforms:t.uniforms},this.outlineUniformVersions.set(t,g))}return t.uniformValuesAutoUpdate||!c&&!w||(a.uniformValuesNeedsUpdate=!0),a}compileFullscreen(e){const a=t({color:e.outputColor,wgslBindings:{...k,uniformExpressions:{},graphTextures:{...k.graphTextures,[W]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),i=a.syncLiveUniforms;return{...a,syncLiveUniforms(t){i(t),$(e,t)}}}getOrCreateMappedNodeMaterial(t){const a=function(t){const a=[t.vertexColors,t.transparent,t.alphaTest,t.side,t.depthTest,t.depthWrite,t.wireframe??!1];t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.roughnessMap?t.roughnessMap.uuid:null,t.metalnessMap?t.metalnessMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshLambertMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshToonMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.gradientMap?t.gradientMap.uuid:null):t instanceof e.MeshBasicMaterial?a.push(t.map?t.map.uuid:null,t.aoMap?t.aoMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.MeshPhongMaterial?a.push(t.map?t.map.uuid:null,t.normalMap?t.normalMap.uuid:null,t.aoMap?t.aoMap.uuid:null,t.emissiveMap?t.emissiveMap.uuid:null,t.lightMap?t.lightMap.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.envMap?t.envMap.uuid:null):t instanceof e.SpriteMaterial&&a.push(t.map?t.map.uuid:null,t.alphaMap?t.alphaMap.uuid:null,t.sizeAttenuation);return a.join(",")}(t),i=this.mappedMaterialsCache.get(t),n=this.mappedMaterialsSignatures.get(t);if(null!=i&&n===a)return i;if(null!=i){i.dispose();const e=this.cache.get(i);if(null!=e){for(const t of e.values())t.material.dispose(),this.cacheValues.delete(t);this.cache.delete(i)}}const s=function(t){if(t instanceof e.SpriteMaterial){const e=new T;e.color=t.color,e.opacity=t.opacity,e.rotation=t.rotation,e.screenSpaceSize=t.sizeAttenuation?0:1,e.alphaTest=t.alphaTest,t.map&&(e.map=t.map),t.alphaMap&&(e.alphaMap=t.alphaMap);const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a}if(t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=t.roughness,e.metalness=t.metalness,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.roughnessMap&&(e.roughnessMap=o(t.roughnessMap)),t.metalnessMap&&(e.metalnessMap=o(t.metalnessMap)),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.envMapIntensity=t.envMapIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshLambertMaterial){const e=new I;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshToonMaterial){const e=new S;e.color=t.color,e.opacity=t.opacity,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}if(t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial){const a=new x;a.color=t.color,a.opacity=t.opacity,a.vertexColor=t.vertexColors,t instanceof e.MeshBasicMaterial&&(t.map&&(a.map=o(t.map)),t.aoMap&&(a.aoMap=o(t.aoMap),a.aoMapIntensity=t.aoMapIntensity),t.lightMap&&(a.lightMap=o(t.lightMap),a.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(a.alphaMap=o(t.alphaMap)),a.envMap=t.envMap),a.alphaTest=t.alphaTest;const i=a.build();return i.transparent=t.transparent,i.side=t.side,i.depthTest=t.depthTest,i.depthWrite=t.depthWrite,i.wireframe=t instanceof e.MeshBasicMaterial&&t.wireframe,i}if(t instanceof e.MeshPhongMaterial){const e=new w;e.color=t.color,e.opacity=t.opacity,e.roughness=Math.max(0,1-t.shininess/100),e.metalness=0,e.vertexColor=t.vertexColors,t.map&&(e.map=o(t.map)),t.normalMap&&(e.normalMap=o(t.normalMap),e.normalScale=t.normalScale),t.aoMap&&(e.aoMap=o(t.aoMap),e.aoMapIntensity=t.aoMapIntensity),t.emissiveMap&&(e.emissiveMap=o(t.emissiveMap)),t.lightMap&&(e.lightMap=o(t.lightMap),e.lightMapIntensity=t.lightMapIntensity),t.alphaMap&&(e.alphaMap=o(t.alphaMap)),e.emissive=t.emissive,e.emissiveIntensity=t.emissiveIntensity,e.envMap=t.envMap,e.alphaTest=t.alphaTest;const a=e.build();return a.transparent=t.transparent,a.side=t.side,a.depthTest=t.depthTest,a.depthWrite=t.depthWrite,a.wireframe=t.wireframe,a}return null}(t);return null==s?null:(s.wireframe=t.wireframe??!1,this.mappedMaterialsCache.set(t,s),this.mappedMaterialsSignatures.set(t,a),t.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(t);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(t),this.mappedMaterialsSignatures.delete(t);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),s)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,t]of this.observedNodeMaterials)e.removeEventListener("dispose",t);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,t){t.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,t){const a=`${createNodeMaterialSignature(e)}|receiveDecals:${!1!==e.userData.receiveDecals}`;return t?`${a}|worldEnvironment:${this.worldEnvironmentRevision}`:a}prepareWorldEnvironment(t){var a,i,n,s,o,r;if(null!=t.envMap){const s=this.environmentTextureResolver?.(t.envMap)??t.envMap;return(a=t.uniforms).envMap??(a.envMap={value:s}),t.uniforms.envMap.value=s,(i=t.uniforms).envMapIntensity??(i.envMapIntensity={value:1}),(n=t.uniforms).envMapRotation??(n.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.delete(t),!1}return null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(t)&&(delete t.uniforms.envMap,delete t.uniforms.envMapIntensity,delete t.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(t)),!1):((s=t.uniforms).envMap??(s.envMap={value:this.worldEnvironment.texture}),t.uniforms.envMap.value=this.worldEnvironment.texture,(o=t.uniforms).envMapIntensity??(o.envMapIntensity={value:this.worldEnvironment.intensity}),t.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(r=t.uniforms).envMapRotation??(r.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(t),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const t=()=>{e.removeEventListener("dispose",t),this.observedNodeMaterials.delete(e);const a=this.cache.get(e);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}const i=this.outlineMaterials.get(e);if(null!=i){const t=this.cache.get(i);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(i)}this.failedSignatures.delete(i),j.delete(i),i.dispose(),this.outlineMaterials.delete(e),this.outlineUniformVersions.delete(e)}this.failedSignatures.delete(e),j.delete(e)};this.observedNodeMaterials.set(e,t),e.addEventListener("dispose",t)}}function P(e,t,a=!1){const i=t.material;i.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(a||e.uniformValuesAutoUpdate||t.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(t.compiled.syncLiveUniforms(i.uniforms),$(e,i.uniforms),z(e,i),t.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,i.uniformValuesAutoUpdate||(i.uniformValuesNeedsUpdate=!0))}function $(e,t){let a=O.get(t);if(null==a){a=[];for(const e in t){const i=t[e],n=i.value,s=!0===n?.isVector2?2:!0===n?.isVector3?3:!0===n?.isVector4?4:!0===n?.isColor?5:0;a.push({name:e,target:i,copyKind:s})}O.set(t,a)}const i=e.uniforms;for(let e=0;e<a.length;e++){const t=a[e],n=i[t.name];if(null==n)continue;const s=n.value,o=t.target.value;if(s!==o){if(0!==t.copyKind){const e=s,a=o;if((2===t.copyKind?!0===e?.isVector2:3===t.copyKind?!0===e?.isVector3:4===t.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof a?.copy){a.copy(s);continue}}t.target.value=s}}}function z(t,a){const i=t.uniforms.envMapIntensity,n=a.uniforms.envMapIntensity;null!=i&&null!=n&&(n.value=i.value);const s=t.uniforms.envMapRotation?.value,o=a.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function B(e,t){for(const a in t.textures){const i=t.textures[a],n=e.uniforms[a]?.value;if(_(n)&&n!==i)return!1}return!0}function _(e){return!0===e?.isTexture}function G(t,a){if(t instanceof e.SpriteMaterial){const i=a;a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),i.rotation=t.rotation,i.screenSpaceSize=t.sizeAttenuation?0:1}else t instanceof e.MeshStandardMaterial||t instanceof e.MeshPhysicalMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=t.roughness),a.uniforms.metalness&&(a.uniforms.metalness.value=t.metalness),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity),a.uniforms.envMapIntensity&&(a.uniforms.envMapIntensity.value=t.envMapIntensity)):t instanceof e.MeshLambertMaterial||t instanceof e.MeshToonMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity)):t instanceof e.MeshBasicMaterial||t instanceof e.LineBasicMaterial?(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),t instanceof e.MeshBasicMaterial&&(a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))):t instanceof e.MeshPhongMaterial&&(a.uniforms.color&&(a.uniforms.color.value instanceof e.Vector3?a.uniforms.color.value.setFromColor(t.color):a.uniforms.color.value instanceof e.Color&&a.uniforms.color.value.copy(t.color)),a.uniforms.opacity&&(a.uniforms.opacity.value=t.opacity),a.uniforms.roughness&&(a.uniforms.roughness.value=Math.max(0,1-t.shininess/100)),a.uniforms.emissive&&(a.uniforms.emissive.value instanceof e.Vector3?a.uniforms.emissive.value.setFromColor(t.emissive):a.uniforms.emissive.value instanceof e.Color&&a.uniforms.emissive.value.copy(t.emissive)),a.uniforms.emissiveIntensity&&(a.uniforms.emissiveIntensity.value=t.emissiveIntensity),a.uniforms.normalScale&&t.normalScale&&(a.uniforms.normalScale.value=t.normalScale.x),a.uniforms.aoMapIntensity&&(a.uniforms.aoMapIntensity.value=t.aoMapIntensity),a.uniforms.lightMapIntensity&&(a.uniforms.lightMapIntensity.value=t.lightMapIntensity))}/*
|
|
1
|
+
import*as e from"three";import{compileNodeWebGpuFullscreen as a,compileNodeShaderMaterialForWebGpu as t,NodeShaderMaterial as n,webGpuRendererBindings as i,webGpuTiledRendererBindings as s,textureSampler2d as o,float as r,length as l,max as u,rgba as p,isWgslCompiler as m,isWgslFragmentCompiler as c,sqrt as f,normalize as h,transformed as d,uniformFloat as M,uniforms as v,vec4 as y,Vec3Node as g,toonMaterial as V}from"three-shader-graph";import{StandardShader as w}from"../shader/builtin/standard-shader.js";import{LambertShader as I}from"../shader/builtin/lambert-shader.js";import{ToonShader as S}from"../shader/builtin/toon-shader.js";import{UnlitShader as x}from"../shader/builtin/unlit-shader.js";import{SpriteShader as T}from"../shader/sprite-shader.js";import{elapsedTimeUniformName as E}from"../shader-nodes/time.js";import{depthUniformName as C,farUniformName as b,nearUniformName as U,resolutionUniformName as A,sceneNormalUniformName as N}from"../shader-nodes/depth.js";import{sceneMapUniformName as W,transmissionMapUniformName as k}from"../shader-nodes/scene-sample.js";const R={...i,uniformExpressions:{...i.uniformExpressions,ambientLightColor:{type:"vec3",expression:"rendererAmbientLight()"},[E]:{type:"float",expression:"rendererElapsedTime()"},[U]:{type:"float",expression:"rendererCameraNear()"},[b]:{type:"float",expression:"rendererCameraFar()"},[A]:{type:"vec2",expression:"rendererViewportSize()"}},graphTextures:{[k]:{resource:"physicalTransmissionSnapshot",dimension:"2d",sampleType:"float",sampler:"filtering",requiresLatePass:!0}},sceneTextures:{[W]:{semantic:"sceneColor",sampleType:"float"},[C]:{semantic:"sceneDepth",sampleType:"depth"}},attributes:{material:{shaderLocation:6,format:"float32x4",defaultValue:[0,0,0,0]},material2:{shaderLocation:7,format:"float32x4",defaultValue:[0,0,0,0]},hole:{shaderLocation:8,format:"float32",defaultValue:[0]},offset:{shaderLocation:9,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},velocity:{shaderLocation:10,format:"float32x4",stepMode:"instance",defaultValue:[0,0,0,0]},size:{shaderLocation:11,format:"float32x3",stepMode:"instance",defaultValue:[0,0,0]},rotation:{shaderLocation:12,format:"float32",stepMode:"instance",defaultValue:[0]},particleData:{shaderLocation:13,format:"float32x3",stepMode:"instance",defaultValue:[1,1,0]},particleColor:{shaderLocation:14,format:"float32x4",stepMode:"instance",defaultValue:[1,1,1,1]}}};class L extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalPositionNode can only be used in the vertex stage");const a=`outline_local_position_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${a} = rendererSkinPosition(input.position, input.skinIndex, input.skinWeight).xyz;\n#else\n let ${a} = input.position;\n#endif`,out:a}}}class D extends g{constructor(e){super(),this.fallback=e}compile(e){if(!m(e))return{out:e.get(this.fallback)};if(c(e))throw new Error("OutlineLocalNormalNode can only be used in the vertex stage");const a=`outline_local_normal_${e.variable()}`;return{chunk:`\n#ifdef USE_SKINNING\n let ${a} = rendererSkinNormal(input.normal, input.skinIndex, input.skinWeight);\n#else\n let ${a} = input.normal;\n#endif`,out:a}}}export function setMaterialUniformValuesAutoUpdate(e,a){e.uniformValuesAutoUpdate=a}export function markMaterialUniformValuesNeedUpdate(e){const a=e;"uniformValuesNeedsUpdate"in a?a.uniformValuesNeedsUpdate=!0:a.uniformValuesAutoVersion=(a.uniformValuesAutoVersion??0)+1}function F(e){return!1!==e.uniformValuesAutoUpdate}function O(e){return e.uniformValuesAutoVersion??0}export function withThreeDefaultVertexAttributeValues(e){return e.map(e=>"uv1"===e.name&&null==e.defaultValue?{...e,defaultValue:[0,0]}:e)}const P=new WeakMap,j=new WeakMap;export function createNodeMaterialSignature(e){const a=j.get(e);if(null!=a)return a;const t=JSON.stringify({version:e.version,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,alphaTest:e.alphaTest,alphaToCoverage:e.alphaToCoverage,blending:e.blending,colorWrite:e.colorWrite,depthFunc:e.depthFunc,depthTest:e.depthTest,depthWrite:e.depthWrite,polygonOffset:e.polygonOffset,polygonOffsetFactor:e.polygonOffsetFactor,polygonOffsetUnits:e.polygonOffsetUnits,premultipliedAlpha:e.premultipliedAlpha,side:e.side,stencilWrite:e.stencilWrite,transparent:e.transparent,wireframe:e.wireframe});return j.set(e,t),t}export class NodeMaterialWebGpuResolver{constructor(e,a,t){this.webGpu=e,this.mrtResolver=a,this.environmentTextureResolver=t,this.cache=new WeakMap,this.failedSignatures=new WeakMap,this.mappedMaterialsCache=new WeakMap,this.mappedMaterialsSignatures=new WeakMap,this.observedNodeMaterials=new Map,this.outlineMaterials=new WeakMap,this.outlineUniformVersions=new WeakMap,this.worldEnvironmentMaterials=new WeakSet,this.worldEnvironment=null,this.worldEnvironmentTexture=null,this.worldEnvironmentIntensity=0,this.worldEnvironmentRevision=0,this.cacheValues=new Set}setWorldEnvironment(e){const a=e?.texture??null,t=e?.intensity??0;if(this.worldEnvironmentTexture!==a||this.worldEnvironmentIntensity!==t){if(this.worldEnvironmentTexture!==a)this.worldEnvironmentRevision++;else if(null!=e)for(const e of this.cacheValues)e.inheritsWorldEnvironment&&null!=e.material.uniforms.envMapIntensity&&(e.material.uniforms.envMapIntensity.value=t,e.material.uniformValuesNeedsUpdate=!0);this.worldEnvironment=e,this.worldEnvironmentTexture=a,this.worldEnvironmentIntensity=t}}resolve(e,a=void 0){let i,o=!1;if(e instanceof n)i=e,this.observeNodeMaterial(i);else{const a=this.getOrCreateMappedNodeMaterial(e);if(null==a)return;i=a,o=!0}if("outline"===a){if(null==i.outputAlbedo)return;o&&J(e,i),i.userData.outlineParameters=e.userData?.outlineParameters,i=this.getOrCreateOutlineMaterial(i),o=!1}i.visible=e.visible,o&&(i.userData.receiveDecals=e.userData.receiveDecals);const r=a??"default",l=this.cache.get(i),u=l?.get(r);if(o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision){const a=F(e),t=O(e);return u.material.uniformValuesAutoUpdate=a,this.syncInheritedWorldEnvironmentSource(i,u),a||u.sourceUniformValuesAutoVersion!==t?(J(e,i),u.compiled.syncLiveUniforms(u.material.uniforms),z(i,u.material.uniforms),B(i,u.material),u.sourceUniformValuesAutoVersion=t,a||(u.material.uniformValuesNeedsUpdate=!0),u.material):u.material}if(!o&&null!=u&&u.sourceVersion===e.version&&u.worldEnvironmentRevision===this.worldEnvironmentRevision&&_(i,u.compiled))return this.syncInheritedWorldEnvironmentSource(i,u),$(i,u),u.material;o&&J(e,i);const p=this.prepareWorldEnvironment(i),m=this.getNodeMaterialSignature(i,p);if(u?.signature===m&&_(i,u.compiled))return o?(u.material.uniformValuesAutoUpdate=F(e),u.compiled.syncLiveUniforms(u.material.uniforms),z(i,u.material.uniforms),B(i,u.material),u.sourceUniformValuesAutoVersion=O(e),u.material.uniformValuesAutoUpdate||(u.material.uniformValuesNeedsUpdate=!0)):$(i,u,!0),u.sourceVersion=e.version,u.worldEnvironmentRevision=this.worldEnvironmentRevision,u.material;try{const n=this.mrtResolver?.(i,a),c=t(i,"opaque"===a?{...R,arrays:s.arrays}:R,n),f=new this.webGpu.WGSLShaderMaterial({vertexShader:c.vertexShader,fragmentShader:c.fragmentShader,depthVertexShader:c.depthVertexShader,depthFragmentShader:c.depthFragmentShader,pointShadowVertexShader:c.pointShadowVertexShader,pointShadowFragmentShader:c.pointShadowFragmentShader,uniforms:c.uniforms,textures:c.textures,sceneTextures:c.sceneTextures,graphTextures:c.graphTextures,vertexAttributes:withThreeDefaultVertexAttributeValues(c.vertexAttributes),uniformValuesAutoUpdate:o?F(e):i.uniformValuesAutoUpdate,transparent:c.renderState?.transparent,alphaTest:c.renderState?.alphaTest,depthTest:c.renderState?.depthTest,depthWrite:c.renderState?.depthWrite,side:c.renderState?.side,wireframe:i.wireframe});f.name=e.name||i.name||e.uuid,f.userData.pipelineOrigin={assetId:e.userData.assetId??i.userData.assetId,assetName:e.userData.assetName??i.userData.assetName,sourceUuid:e.uuid,sourceName:e.name,sourceType:e.type,sourceVersion:e.version},f.uniformValuesAutoUpdate=o?F(e):i.uniformValuesAutoUpdate,function(e,a){if(null==e)return;Object.assign(a,e)}(c.renderState,f),null!=u&&(u.material.dispose(),this.cacheValues.delete(u));const h={signature:m,compiled:c,material:f,inheritsWorldEnvironment:p,sourceVersion:e.version,sourceUniformValuesAutoVersion:o?O(e):i.uniformValuesAutoVersion,worldEnvironmentRevision:this.worldEnvironmentRevision},d=l??new Map;return d.set(r,h),this.cache.set(i,d),this.cacheValues.add(h),z(i,f.uniforms),B(i,f),f}catch(e){let a=this.failedSignatures.get(i);if(null==a&&(a=new Map,this.failedSignatures.set(i,a)),a.get(r)!==m){a.set(r,m);const t=e instanceof Error?e.message:String(e),n=i.name||i.uuid;console.warn(`[Hology WebGPU experiment] Falling back for NodeShaderMaterial "${n}": ${t}`,{material:i,error:e})}return}}getOrCreateOutlineMaterial(a){let t=this.outlineMaterials.get(a);if(null==t){const i=a.nodeMaterialDefinition,s=a.outputAlbedo;if(null==s)throw new Error("Cannot derive an outline material without an albedo output");const o=M("outlineThickness",.003),m=M("outlineDarkening",.65),c=M("outlineAlpha",1),g=new L(d.position.xyz),w=new D(d.normal),I=i.transform?.multiplyVec(y(g,1))??y(g,1),S=v.modelViewMatrix.multiplyVec(I),x=h(v.normalMatrix.multiplyVec(w)),T=f(u(l(S.xyz),r(1e-4))).multiply(.5),E=S.xyz.add(x.multiplyScalar(o.multiply(T))),C=v.projectionMatrix.multiplyVec(S),b=v.projectionMatrix.multiplyVec(y(E,1)),U=(i.position??C).add(b.subtract(C)),A=p(V({color:s.rgb.multiplyScalar(r(1).subtract(m))}),a.outputOpacity.multiply(c));t=new n({color:A,position:U,opacity:a.outputOpacity,discard:i.discard,alphaTest:a.alphaTest,transparent:!0,fog:!1,outputEncoding:i.outputEncoding,uniforms:i.uniforms,uniformNodes:i.uniformNodes}),t.side=e.BackSide,t.depthTest=!0,t.depthWrite=!0,this.outlineMaterials.set(a,t),this.outlineUniformVersions.delete(a)}const i=a.userData?.outlineParameters,s=i?.thickness??.003,o=e.MathUtils.clamp(i?.darkening??.65,0,1),m=e.MathUtils.clamp(i?.alpha??a.opacity,0,1),c=t.uniforms.outlineThickness.value!==s||t.uniforms.outlineDarkening.value!==o||t.uniforms.outlineAlpha.value!==m;t.uniforms.outlineThickness.value=s,t.uniforms.outlineDarkening.value=o,t.uniforms.outlineAlpha.value=m,t.userData.outlineSource=a,t.uniformValuesAutoUpdate=a.uniformValuesAutoUpdate;let g=this.outlineUniformVersions.get(a);const w=a.uniformValuesAutoUpdate||null==g||g.version!==a.uniformValuesAutoVersion||g.uniforms!==a.uniforms;if(w){for(const e in a.uniforms)null!=t.uniforms[e]&&(t.uniforms[e].value=a.uniforms[e].value);g?(g.version=a.uniformValuesAutoVersion,g.uniforms=a.uniforms):(g={version:a.uniformValuesAutoVersion,uniforms:a.uniforms},this.outlineUniformVersions.set(a,g))}return a.uniformValuesAutoUpdate||!c&&!w||(t.uniformValuesNeedsUpdate=!0),t}compileFullscreen(e){const t=a({color:e.outputColor,wgslBindings:{...R,uniformExpressions:{},graphTextures:{...R.graphTextures,[N]:{resource:"hologyNormalRoughness",dimension:"2d",sampleType:"float",sampler:"filtering"}}}}),n=t.syncLiveUniforms;return{...t,syncLiveUniforms(a){n(a),z(e,a)}}}getOrCreateMappedNodeMaterial(a){const t=function(a){const t=[a.vertexColors,a.transparent,a.alphaTest,a.side,a.depthTest,a.depthWrite,a.wireframe??!1];if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){if(t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.roughnessMap?a.roughnessMap.uuid:null,a.metalnessMap?a.metalnessMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null),a instanceof e.MeshPhysicalMaterial){t.push(a.clearcoat>0,a.iridescence>0,a.transmission>0,a.sheen>0,a.anisotropy>0,1.5!==a.ior,1!==a.specularIntensity,1!==a.specularColor.r||1!==a.specularColor.g||1!==a.specularColor.b);for(const e of H)t.push(a[e]?.uuid??null)}}else a instanceof e.MeshLambertMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshToonMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.gradientMap?a.gradientMap.uuid:null):a instanceof e.MeshBasicMaterial?t.push(a.map?a.map.uuid:null,a.aoMap?a.aoMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.MeshPhongMaterial?t.push(a.map?a.map.uuid:null,a.normalMap?a.normalMap.uuid:null,a.aoMap?a.aoMap.uuid:null,a.emissiveMap?a.emissiveMap.uuid:null,a.lightMap?a.lightMap.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.envMap?a.envMap.uuid:null):a instanceof e.SpriteMaterial&&t.push(a.map?a.map.uuid:null,a.alphaMap?a.alphaMap.uuid:null,a.sizeAttenuation);return t.join(",")}(a),n=this.mappedMaterialsCache.get(a),i=this.mappedMaterialsSignatures.get(a);if(null!=n&&i===t)return n;if(null!=n){n.dispose();const e=this.cache.get(n);if(null!=e){for(const a of e.values())a.material.dispose(),this.cacheValues.delete(a);this.cache.delete(n)}}const s=function(a){if(a instanceof e.SpriteMaterial){const e=new T;e.color=a.color,e.opacity=a.opacity,e.rotation=a.rotation,e.screenSpaceSize=a.sizeAttenuation?0:1,e.alphaTest=a.alphaTest,a.map&&(e.map=a.map),a.alphaMap&&(e.alphaMap=a.alphaMap);const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t}if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){const t=new w;if(t.color=a.color,t.opacity=a.opacity,t.roughness=a.roughness,t.metalness=a.metalness,t.vertexColor=a.vertexColors,a.map&&(t.map=o(a.map)),a.normalMap&&(t.normalMap=o(a.normalMap),t.normalScale=a.normalScale),a.roughnessMap&&(t.roughnessMap=o(a.roughnessMap)),a.metalnessMap&&(t.metalnessMap=o(a.metalnessMap)),a.aoMap&&(t.aoMap=o(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(t.emissiveMap=o(a.emissiveMap)),a.lightMap&&(t.lightMap=o(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=o(a.alphaMap)),t.emissive=a.emissive,t.emissiveIntensity=a.emissiveIntensity,t.envMap=a.envMap,t.envMapIntensity=a.envMapIntensity,t.alphaTest=a.alphaTest,a instanceof e.MeshPhysicalMaterial){for(const e of K)t[e]=a[e];for(const e of q)t[e]=a[e];for(const e of H)a[e]&&(t[e]=o(a[e]));t.clearcoatNormalScale=a.clearcoatNormalScale,t.iridescenceThicknessRange=new e.Vector2(...a.iridescenceThicknessRange),t.anisotropyRotation=a.anisotropyRotation}const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a.wireframe,n}if(a instanceof e.MeshLambertMaterial){const e=new I;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=o(a.map)),a.normalMap&&(e.normalMap=o(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=o(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=o(a.emissiveMap)),a.lightMap&&(e.lightMap=o(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=o(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshToonMaterial){const e=new S;e.color=a.color,e.opacity=a.opacity,e.vertexColor=a.vertexColors,a.map&&(e.map=o(a.map)),a.normalMap&&(e.normalMap=o(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=o(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=o(a.emissiveMap)),a.lightMap&&(e.lightMap=o(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=o(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}if(a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial){const t=new x;t.color=a.color,t.opacity=a.opacity,t.vertexColor=a.vertexColors,a instanceof e.MeshBasicMaterial&&(a.map&&(t.map=o(a.map)),a.aoMap&&(t.aoMap=o(a.aoMap),t.aoMapIntensity=a.aoMapIntensity),a.lightMap&&(t.lightMap=o(a.lightMap),t.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(t.alphaMap=o(a.alphaMap)),t.envMap=a.envMap),t.alphaTest=a.alphaTest;const n=t.build();return n.transparent=a.transparent,n.side=a.side,n.depthTest=a.depthTest,n.depthWrite=a.depthWrite,n.wireframe=a instanceof e.MeshBasicMaterial&&a.wireframe,n}if(a instanceof e.MeshPhongMaterial){const e=new w;e.color=a.color,e.opacity=a.opacity,e.roughness=Math.max(0,1-a.shininess/100),e.metalness=0,e.vertexColor=a.vertexColors,a.map&&(e.map=o(a.map)),a.normalMap&&(e.normalMap=o(a.normalMap),e.normalScale=a.normalScale),a.aoMap&&(e.aoMap=o(a.aoMap),e.aoMapIntensity=a.aoMapIntensity),a.emissiveMap&&(e.emissiveMap=o(a.emissiveMap)),a.lightMap&&(e.lightMap=o(a.lightMap),e.lightMapIntensity=a.lightMapIntensity),a.alphaMap&&(e.alphaMap=o(a.alphaMap)),e.emissive=a.emissive,e.emissiveIntensity=a.emissiveIntensity,e.envMap=a.envMap,e.alphaTest=a.alphaTest;const t=e.build();return t.transparent=a.transparent,t.side=a.side,t.depthTest=a.depthTest,t.depthWrite=a.depthWrite,t.wireframe=a.wireframe,t}return null}(a);return null==s?null:(s.wireframe=a.wireframe??!1,this.mappedMaterialsCache.set(a,s),this.mappedMaterialsSignatures.set(a,t),a.addEventListener("dispose",()=>{const e=this.mappedMaterialsCache.get(a);if(null!=e){e.dispose(),this.mappedMaterialsCache.delete(a),this.mappedMaterialsSignatures.delete(a);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}}}),s)}canResolve(e){return null!=this.resolve(e)}dispose(){for(const[e,a]of this.observedNodeMaterials)e.removeEventListener("dispose",a);this.observedNodeMaterials.clear();for(const e of this.cacheValues)e.material.dispose();this.cacheValues.clear()}syncInheritedWorldEnvironmentSource(e,a){a.inheritsWorldEnvironment&&null!=this.worldEnvironment&&(e.uniforms.envMap.value=this.worldEnvironment.texture,e.uniforms.envMapIntensity.value=this.worldEnvironment.intensity)}getNodeMaterialSignature(e,a){const t=`${createNodeMaterialSignature(e)}|receiveDecals:${!1!==e.userData.receiveDecals}`;return a?`${t}|worldEnvironment:${this.worldEnvironmentRevision}`:t}prepareWorldEnvironment(a){var t,n,i,s,o,r;if(null!=a.envMap){const s=this.environmentTextureResolver?.(a.envMap)??a.envMap;return(t=a.uniforms).envMap??(t.envMap={value:s}),a.uniforms.envMap.value=s,(n=a.uniforms).envMapIntensity??(n.envMapIntensity={value:1}),(i=a.uniforms).envMapRotation??(i.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.delete(a),!1}return null==this.worldEnvironment?(this.worldEnvironmentMaterials.has(a)&&(delete a.uniforms.envMap,delete a.uniforms.envMapIntensity,delete a.uniforms.envMapRotation,this.worldEnvironmentMaterials.delete(a)),!1):((s=a.uniforms).envMap??(s.envMap={value:this.worldEnvironment.texture}),a.uniforms.envMap.value=this.worldEnvironment.texture,(o=a.uniforms).envMapIntensity??(o.envMapIntensity={value:this.worldEnvironment.intensity}),a.uniforms.envMapIntensity.value=this.worldEnvironment.intensity,(r=a.uniforms).envMapRotation??(r.envMapRotation={value:new e.Matrix3}),this.worldEnvironmentMaterials.add(a),!0)}observeNodeMaterial(e){if(this.observedNodeMaterials.has(e))return;const a=()=>{e.removeEventListener("dispose",a),this.observedNodeMaterials.delete(e);const t=this.cache.get(e);if(null!=t){for(const e of t.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(e)}const n=this.outlineMaterials.get(e);if(null!=n){const a=this.cache.get(n);if(null!=a){for(const e of a.values())e.material.dispose(),this.cacheValues.delete(e);this.cache.delete(n)}this.failedSignatures.delete(n),j.delete(n),n.dispose(),this.outlineMaterials.delete(e),this.outlineUniformVersions.delete(e)}this.failedSignatures.delete(e),j.delete(e)};this.observedNodeMaterials.set(e,a),e.addEventListener("dispose",a)}}function $(e,a,t=!1){const n=a.material;n.uniformValuesAutoUpdate=e.uniformValuesAutoUpdate,(t||e.uniformValuesAutoUpdate||a.sourceUniformValuesAutoVersion!==e.uniformValuesAutoVersion)&&(a.compiled.syncLiveUniforms(n.uniforms),z(e,n.uniforms),B(e,n),a.sourceUniformValuesAutoVersion=e.uniformValuesAutoVersion,n.uniformValuesAutoUpdate||(n.uniformValuesNeedsUpdate=!0))}function z(e,a){let t=P.get(a);if(null==t){t=[];for(const e in a){const n=a[e],i=n.value,s=!0===i?.isVector2?2:!0===i?.isVector3?3:!0===i?.isVector4?4:!0===i?.isColor?5:0;t.push({name:e,target:n,copyKind:s})}P.set(a,t)}const n=e.uniforms;for(let e=0;e<t.length;e++){const a=t[e],i=n[a.name];if(null==i)continue;const s=i.value,o=a.target.value;if(s!==o){if(0!==a.copyKind){const e=s,t=o;if((2===a.copyKind?!0===e?.isVector2:3===a.copyKind?!0===e?.isVector3:4===a.copyKind?!0===e?.isVector4:!0===e?.isColor)&&"function"==typeof t?.copy){t.copy(s);continue}}a.target.value=s}}}function B(a,t){const n=a.uniforms.envMapIntensity,i=t.uniforms.envMapIntensity;null!=n&&null!=i&&(i.value=n.value);const s=a.uniforms.envMapRotation?.value,o=t.uniforms.envMapRotation?.value;s instanceof e.Matrix3&&o instanceof e.Matrix3&&o.copy(s)}function _(e,a){for(const t in a.textures){const n=a.textures[t],i=e.uniforms[t]?.value;if(G(i)&&i!==n)return!1}return!0}function G(e){return!0===e?.isTexture}const K=["ior","specularIntensity","clearcoat","clearcoatRoughness","iridescence","iridescenceIOR","transmission","thickness","attenuationDistance","dispersion","sheen","sheenRoughness","anisotropy"],q=["specularColor","attenuationColor","sheenColor"],H=["specularIntensityMap","specularColorMap","clearcoatMap","clearcoatRoughnessMap","clearcoatNormalMap","iridescenceMap","iridescenceThicknessMap","transmissionMap","thicknessMap","sheenColorMap","sheenRoughnessMap","anisotropyMap"];function J(a,t){if(a instanceof e.SpriteMaterial){const n=t;t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),n.rotation=a.rotation,n.screenSpaceSize=a.sizeAttenuation?0:1}else if(a instanceof e.MeshStandardMaterial||a instanceof e.MeshPhysicalMaterial){if(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=a.roughness),t.uniforms.metalness&&(t.uniforms.metalness.value=a.metalness),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity),t.uniforms.envMapIntensity&&(t.uniforms.envMapIntensity.value=a.envMapIntensity),a instanceof e.MeshPhysicalMaterial){for(const e of K)t.uniforms[e]&&(t.uniforms[e].value=a[e]);for(const n of q){const i=t.uniforms[n]?.value;i instanceof e.Vector3&&i.setFromColor(a[n])}const n=t.uniforms.clearcoatNormalScale?.value;n instanceof e.Vector2&&n.copy(a.clearcoatNormalScale),t.uniforms.iridescenceThicknessMin&&(t.uniforms.iridescenceThicknessMin.value=a.iridescenceThicknessRange[0]),t.uniforms.iridescenceThicknessMax&&(t.uniforms.iridescenceThicknessMax.value=a.iridescenceThicknessRange[1]);const i=t.uniforms.anisotropyDirection?.value;i instanceof e.Vector2&&i.set(Math.cos(a.anisotropyRotation),Math.sin(a.anisotropyRotation))}}else a instanceof e.MeshLambertMaterial||a instanceof e.MeshToonMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity)):a instanceof e.MeshBasicMaterial||a instanceof e.LineBasicMaterial?(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),a instanceof e.MeshBasicMaterial&&(t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))):a instanceof e.MeshPhongMaterial&&(t.uniforms.color&&(t.uniforms.color.value instanceof e.Vector3?t.uniforms.color.value.setFromColor(a.color):t.uniforms.color.value instanceof e.Color&&t.uniforms.color.value.copy(a.color)),t.uniforms.opacity&&(t.uniforms.opacity.value=a.opacity),t.uniforms.roughness&&(t.uniforms.roughness.value=Math.max(0,1-a.shininess/100)),t.uniforms.emissive&&(t.uniforms.emissive.value instanceof e.Vector3?t.uniforms.emissive.value.setFromColor(a.emissive):t.uniforms.emissive.value instanceof e.Color&&t.uniforms.emissive.value.copy(a.emissive)),t.uniforms.emissiveIntensity&&(t.uniforms.emissiveIntensity.value=a.emissiveIntensity),t.uniforms.normalScale&&a.normalScale&&(t.uniforms.normalScale.value=a.normalScale.x),t.uniforms.aoMapIntensity&&(t.uniforms.aoMapIntensity.value=a.aoMapIntensity),t.uniforms.lightMapIntensity&&(t.uniforms.lightMapIntensity.value=a.lightMapIntensity))}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -144,6 +144,8 @@ export declare class ExperimentalWebGpuBackend implements RenderingBackendDriver
|
|
|
144
144
|
readonly x: number;
|
|
145
145
|
readonly y: number;
|
|
146
146
|
}[], lights?: readonly THREE.DirectionalLight[]): void;
|
|
147
|
+
setDirectionalShadowUpdateOptions(options: import("@hology/webgpu-renderer").DirectionalShadowUpdateOptions): void;
|
|
148
|
+
invalidateDirectionalShadows(): void;
|
|
147
149
|
setDirectionalShadowOptions(enabled: boolean, mapSize: number): void;
|
|
148
150
|
setWorldEnvironment(environment: WorldEnvironmentState | null): void;
|
|
149
151
|
getEnvironmentTexture(texture: THREE.Texture): THREE.Texture;
|
|
@@ -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,M=!1!==m.gtao&&(null==m.gtao||!1!==m.gtao.temporal),D=!1!==m.volumetricFog&&(null==m.volumetricFog||!1!==m.volumetricFog.temporal),E=x?"off":b?"taa":null!=(F=m).antiAliasing?F.antiAliasing:null!=F.taa&&!1!==F.taa?"taa":null!=F.smaa&&!1!==F.smaa?"smaa":null!=F.fxaa&&!1!==F.fxaa?"fxaa":!1===F.taa?"off":"taa";var F;const O=null!=m.antiAliasing,L=y||M||D||(O||"taa"===E)||x;let C=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)),...L?[h(e)]:[]]:void 0,e=>C?.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??{}}),W=O||!1!==m.fxaa&&"fxaa"===E?new f.FXAAEffect(!1===m.fxaa?{}:m.fxaa):null,k=O||!1!==m.smaa&&"smaa"===E?new f.SMAAEffect(!1===m.smaa?{}:m.smaa):null,V=x||O||!1!==m.taa&&"taa"===E?new f.TemporalAAEffect({renderScale:1,...!1===m.taa?{}:m.taa}):null,I={mode:E},U=!1===m.motionBlur||null==m.motionBlur?null:new f.MotionBlurEffect(m.motionBlur),N=m.volumetricFog||void 0,j=!1===m.volumetricFog?null:new f.VolumetricFogEffect(void 0,{...f.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...N,temporal:!1!==N?.temporal&&{...f.VOLUMETRIC_FOG_PRESETS.high.temporal,...N?.temporal},blur:!1!==N?.blur&&{...!1===f.VOLUMETRIC_FOG_PRESETS.high.blur?{}:f.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...N?.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"===E?V?.renderScale??1:1),Y.setRenderGraphBuilder((e,t)=>{const i=new f.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=L?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])}),a=Q(i,"beforeFog",a),i.addLatePass(a);for(const e of K)null!=e.stage&&"afterScene"!==e.stage||e(i,a);null!=j&&(a=j.addPasses(i,{sceneColor:a,depth:i.mainDepth,velocity:r??void 0,volumeObjects:t.fogVolumeObjects,lights:t.extractedLights})),null!=U&&null!=r&&(a=U.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"===I.mode&&null!=V?V.addPass(i,a,i.mainDepth,r??void 0):a;"smaa"===I.mode&&null!=k?s=k.addPass(i,s):"fxaa"===I.mode&&null!=W&&(s=W.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),C=new ExperimentalWebGpuBackend(Y,S,G,R,B,W,k,T,A,V,U,j,H,$,_,q,K,Z,I,X,P,v),C}catch(e){throw Y.destroy(),S.dispose(),G.dispose(),R.dispose(),T?.dispose(),k?.dispose(),U?.dispose(),j?.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()}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)}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}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 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),E=x?"off":b?"taa":null!=(O=m).antiAliasing?O.antiAliasing:null!=O.taa&&!1!==O.taa?"taa":null!=O.smaa&&!1!==O.smaa?"smaa":null!=O.fxaa&&!1!==O.fxaa?"fxaa":!1===O.taa?"off":"taa";var O;const F=null!=m.antiAliasing,L=y||D||M||(F||"taa"===E)||x;let C=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)),...L?[h(e)]:[]]:void 0,e=>C?.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"===E?new f.FXAAEffect(!1===m.fxaa?{}:m.fxaa):null,W=F||!1!==m.smaa&&"smaa"===E?new f.SMAAEffect(!1===m.smaa?{}:m.smaa):null,k=x||F||!1!==m.taa&&"taa"===E?new f.TemporalAAEffect({renderScale:1,...!1===m.taa?{}:m.taa}):null,V={mode:E},I=!1===m.motionBlur||null==m.motionBlur?null:new f.MotionBlurEffect(m.motionBlur),N=m.volumetricFog||void 0,j=!1===m.volumetricFog?null:new f.VolumetricFogEffect(void 0,{...f.VOLUMETRIC_FOG_PRESETS.high,maxDistance:64,spatialJitter:!0,scatteringIntensity:Math.PI,...N,temporal:!1!==N?.temporal&&{...f.VOLUMETRIC_FOG_PRESETS.high.temporal,...N?.temporal},blur:!1!==N?.blur&&{...!1===f.VOLUMETRIC_FOG_PRESETS.high.blur?{}:f.VOLUMETRIC_FOG_PRESETS.high.blur,depthAwareUpsample:!0,...N?.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"===E?k?.renderScale??1:1),Y.setRenderGraphBuilder((e,t)=>{const i=new f.FrameGraphBuilder(t),n=i.createColorTarget("hologyNormalRoughness",{format:"rgba8unorm"}),r=L?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])}),a=Q(i,"beforeFog",a),i.addLatePass(a);for(const e of K)null!=e.stage&&"afterScene"!==e.stage||e(i,a);null!=j&&(a=j.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),C=new ExperimentalWebGpuBackend(Y,S,G,R,B,U,W,T,A,k,I,j,H,$,_,q,K,Z,V,X,P,v),C}catch(e){throw Y.destroy(),S.dispose(),G.dispose(),R.dispose(),T?.dispose(),W?.dispose(),I?.dispose(),j?.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()}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}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";/*
|
|
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,4 +1,8 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
|
+
import type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
3
|
+
export type { DirectionalShadowUpdateOptions } from "@hology/webgpu-renderer";
|
|
4
|
+
import type { DetailCullingSettings } from "@hology/webgpu-renderer";
|
|
5
|
+
export type { DetailCullingSettings } from "@hology/webgpu-renderer";
|
|
2
6
|
import { Camera, Object3D, WebGLRenderer, WebGLRenderTarget, Texture } from 'three';
|
|
3
7
|
import { ShaderPass } from "three-stdlib";
|
|
4
8
|
import { IRgbNode, RgbaNode } from 'three-shader-graph';
|
|
@@ -210,6 +214,7 @@ export declare class RenderingView {
|
|
|
210
214
|
/** Tracks last update time (ms) for each CSM cascade. */
|
|
211
215
|
private csmCascadeLastUpdate?;
|
|
212
216
|
private csmUpdateInvervals;
|
|
217
|
+
private webgpuDirectionalShadowUpdateOptions;
|
|
213
218
|
private webgpuDirectionalShadowOptions;
|
|
214
219
|
aoPass: GTAOPass;
|
|
215
220
|
private bloomPass;
|
|
@@ -223,6 +228,8 @@ export declare class RenderingView {
|
|
|
223
228
|
private postProcessEffects;
|
|
224
229
|
private postProcessEffectResolution;
|
|
225
230
|
private postProcessEffectUniformState;
|
|
231
|
+
private transmissionColorRenderTarget?;
|
|
232
|
+
private transmissionCopyQuad?;
|
|
226
233
|
private fquadCopySceneColor;
|
|
227
234
|
private fquadCopySceneDepth;
|
|
228
235
|
private occlusionClusters;
|
|
@@ -318,6 +325,9 @@ export declare class RenderingView {
|
|
|
318
325
|
setExperimentalWebGpuTiledLightingEnabled(enabled: boolean): void;
|
|
319
326
|
setExperimentalWebGpuDynamicBatchingEnabled(enabled: boolean): void;
|
|
320
327
|
setMotionBlurOptions(options: MotionBlurOptions): void;
|
|
328
|
+
/** Opt-in cached WebGPU cascade refresh rates, independent of render FPS. */
|
|
329
|
+
setDirectionalShadowUpdateOptions(options: DirectionalShadowUpdateOptions): void;
|
|
330
|
+
invalidateDirectionalShadows(): void;
|
|
321
331
|
setDirectionalShadowOptions(options: DirectionalShadowOptions): void;
|
|
322
332
|
setGTAOOptions(options: GTAOOptions): void;
|
|
323
333
|
configureAmbientOcclusion(enabled: boolean, blendIntensity?: number, options?: Record<string, unknown>): void;
|
|
@@ -330,6 +340,8 @@ export declare class RenderingView {
|
|
|
330
340
|
setVolumetricFogOptions(options: VolumetricFogOptions): void;
|
|
331
341
|
setVolumetricFogQuality(quality: VolumetricFogQuality): void;
|
|
332
342
|
pushMotionBlurOverride(override: MotionBlurOverride): MotionBlurOverrideHandle | null;
|
|
343
|
+
/** WebGPU detail rejection. Inherited by descendants; set before static registration. */
|
|
344
|
+
setObjectDetailCulling(object: Object3D, settings: DetailCullingSettings): void;
|
|
333
345
|
setObjectMotionBlur(object: Object3D, mode: MotionBlurObjectMode, scale?: number): void;
|
|
334
346
|
/** Call after a teleport or discontinuous animation reset. */
|
|
335
347
|
invalidateObjectMotion(object: Object3D): void;
|
|
@@ -496,6 +508,7 @@ export declare class RenderingView {
|
|
|
496
508
|
private bloomStoredMaterials;
|
|
497
509
|
private bloomHidden;
|
|
498
510
|
private hasBloom;
|
|
511
|
+
private usesSceneColorUniform;
|
|
499
512
|
private initSceneColorUniform;
|
|
500
513
|
private initDepthUniform;
|
|
501
514
|
private initNormalUniform;
|