@hology/core 0.0.267 → 0.0.269
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/actors/builtin/components/character/character-movement.d.ts +2 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +1 -0
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- 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/asset-resource-loader.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/frame-stats.test.d.ts +2 -0
- package/dist/test/frame-stats.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/dist/utils/three/frame-stats.d.ts +22 -0
- package/dist/utils/three/frame-stats.js +4 -0
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -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;
|