@hology/core 0.0.206 → 0.0.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effects/sequence/sequence-data.d.ts +8 -3
- package/dist/effects/sequence/sequence-data.js +1 -1
- package/dist/effects/sequence/sequence-definitions.js +1 -1
- package/dist/effects/sequence/sequence-player.d.ts +4 -0
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/sequence/sequence-value-lane.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/factory.d.ts +1 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/internal/component-init.d.ts +1 -0
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/animation/anim-sm.d.ts +2 -0
- package/dist/gameplay/animation/anim-sm.js +1 -1
- package/dist/gameplay/initiate.d.ts +3 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/services/world.js +1 -1
- package/dist/rendering/upscaling-pass.d.ts +95 -0
- package/dist/rendering/upscaling-pass.js +4 -0
- package/dist/rendering.d.ts +77 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +2 -0
- 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/scene/materials/water.js +1 -1
- package/dist/scene/runtime-asset-service.d.ts +2 -0
- package/dist/scene/runtime-asset-service.js +1 -1
- package/dist/scene/storage/storage.d.ts +3 -0
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/landscape-composite-shader.d.ts +0 -1
- package/dist/shader/builtin/landscape-composite-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.d.ts +13 -12
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.d.ts +9 -7
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.d.ts +5 -4
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/graph/compiler.js +1 -1
- package/dist/shader/parameter.js +1 -1
- package/dist/shader-nodes/pom.js +1 -1
- package/dist/test/data-asset-definition.test.js +1 -1
- package/dist/test/parameter-definition.test.js +1 -1
- package/dist/test/runtime-asset-service.test.d.ts +2 -0
- package/dist/test/runtime-asset-service.test.js +4 -0
- package/dist/test/runtime-param-type-inference.test.js +1 -1
- package/dist/test/sequence-post-process.test.js +1 -1
- package/dist/test/sequence-property-parameters.test.js +1 -1
- package/dist/test/sequence-vfx.test.d.ts +2 -0
- package/dist/test/sequence-vfx.test.js +4 -0
- package/dist/test/shader-graph.test.js +1 -1
- package/dist/test/storage-case-collision.test.js +1 -1
- package/dist/test/world-lifecycle.test.d.ts +2 -0
- package/dist/test/world-lifecycle.test.js +4 -0
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as s}from"tslib";import{Material as t,MathUtils as a,MeshBasicMaterial as o,MeshLambertMaterial as l,MeshStandardMaterial as i}from"three";import{cos as
|
|
1
|
+
import{__decorate as e,__metadata as s}from"tslib";import{Material as t,MathUtils as a,MeshBasicMaterial as o,MeshLambertMaterial as l,MeshStandardMaterial as i}from"three";import{cos as n,float as r,mix as p,rgb as h,standardMaterial as u,step as m,varyingAttributes as c,SimplexNoiseNode as d,varying as y,uniforms as M,vec4 as f,attributes as g,smoothstep as S,textureSampler2d as b,rgba as v,NodeShaderMaterial as A,varyingTransformed as w,colorToNormal as C}from"three-shader-graph";import{LayerMixMode as L,mixColorsByLayer as N}from"../../shader-nodes/layers.js";import{Parameter as j}from"../parameter.js";import{NodeShader as x}from"../shader.js";import{ParallaxStandardMaterial as R}from"./standard-shader.js";import{parallaxOcclusionMapping as T}from"../../shader-nodes/pom.js";import{applyUvTiling as O}from"./../../shader/uv-nodes.js";const P=y(M.modelMatrix.multiplyVec(f(g.position,1)).xz),k=new i({color:"gray"});export class LandscapeCompositeShader extends x{constructor(){super(...arguments),this.layers=[],this.transition=L.soft,this.noiseScale=1,this.noiseAmount=.2,this.softness=.3,this.enableSlope=!1,this.slopeAngle=35}output(){if(0===this.layers.length)return{color:u({color:h("gray")}),landscape:!0};for(let e=0;e<this.layers.length;e++){null==this.layers[e]&&(console.warn("One of the layers in the landscape composite shader is null or undefined. This layer will be rendered as gray. Please make sure to assign a material to all layers.",this.layers),this.layers[e]=k);this.layers[e]instanceof i||this.layers[e]instanceof l||this.layers[e]instanceof o||this.layers[e]instanceof A||(console.warn("One of the layers in the landscape composite shader is not a supported material. This layer will be rendered as gray. Please use a supported material.",this.layers[e]),this.layers[e]=k)}const e=new Map,s=new z,t=c.uv;function y(s,t){let a=t;if(s instanceof R&&null!=s.heightMap){let o=e.get(s);null==o&&(o=T(t,b(s.heightMap),r(s.heightScale??1)),e.set(s,o)),a=o}return a}const M=this.layers.map(e=>{if(e instanceof i||e instanceof l||e instanceof o){let s=v(e.color,1);return null!=e.map&&(s=s.multiply(b(e.map).sample(y(e,O(t,e.map))))),s}return e instanceof A&&null!=e.outputAlbedo?e.outputAlbedo.rgba(1):v("white")}),f=this.layers.map(e=>{if(e instanceof i||e instanceof l){if(null!=e.normalMap)return C(b(e.normalMap).sample(y(e,O(t,e.normalMap))),e.normalScale?.x??1)}else if(e instanceof A&&null!=e.outputNormal)return e.outputNormal;return w.normal}),g=this.layers.map(e=>{let a=r(1);return e instanceof i?(a=r(e.roughness??1),null!=e.roughnessMap&&(a=a.multiply(s.get(e.roughnessMap,y(e,O(t,e.roughnessMap))).g))):e instanceof A&&null!=e.outputRoughness&&(a=e.outputRoughness),a}),j=this.layers.map(e=>{let a=r(0);return e instanceof i?(a=r(e.metalness??0),null!=e.metalnessMap&&(a=a.multiply(s.get(e.metalnessMap,y(e,O(t,e.metalnessMap))).b))):e instanceof A&&null!=e.outputMetalness&&(a=e.outputMetalness),a});let x,B,H,V;if(this.enableSlope&&null!=this.slopeMaterial)if(this.slopeMaterial instanceof i){const e=y(this.slopeMaterial,t);x=v(this.slopeMaterial.color,1),null!=this.slopeMaterial.map&&(x=x.multiply(s.get(this.slopeMaterial.map,O(e,this.slopeMaterial.map)))),B=w.normal,null!=this.slopeMaterial.normalMap&&(B=C(s.get(this.slopeMaterial.normalMap,O(e,this.slopeMaterial.normalMap)),this.slopeMaterial.normalScale?.x??1)),H=r(this.slopeMaterial.roughness??1),null!=this.slopeMaterial.roughnessMap&&(H=H.multiply(s.get(this.slopeMaterial.roughnessMap,O(e,this.slopeMaterial.roughnessMap)).g)),V=r(this.slopeMaterial.metalness??0),null!=this.slopeMaterial.metalnessMap&&(V=V.multiply(s.get(this.slopeMaterial.metalnessMap,O(e,this.slopeMaterial.metalnessMap)).b))}else this.slopeMaterial instanceof A&&(x=this.slopeMaterial.outputAlbedo.rgba(1)??v("white"),B=this.slopeMaterial.outputNormal??w.normal,H=this.slopeMaterial.outputRoughness??r(1),V=this.slopeMaterial.outputMetalness??r(0));const q=(e,s)=>{const t=N({layerColors:e.slice(0,8),noiseScale:this.noiseScale,noiseAmount:this.noiseAmount,mode:this.transition,decay:this.softness}),o=r(this.noiseAmount).multiply(r(.1)),l=r(this.noiseScale),i=new d(P.multiplyScalar(l)).multiply(r(2)).subtract(r(1)).multiply(o),h=r(a.degToRad(this.slopeAngle)).add(i.multiply(r(.1)));let u=p(t,s,m(h,n(c.normal.y)));if(this.transition==L.soft){const e=h,a=r(this.softness).divide(r(2)),o=e.subtract(a),l=e.add(a);u=p(t,s,S(o,l,n(c.normal.y)))}return this.enableSlope&&null!=s?u:t},D=q(M,x),E=q(f,B),F=q(g,H),G=q(j,V);return{color:u({color:D,normal:E,roughness:F,metalness:G}),landscape:!0}}}e([j({type:t}),s("design:type",Array)],LandscapeCompositeShader.prototype,"layers",void 0),e([j({options:[{value:L.hard,name:"Hard"},{value:L.soft,name:"Soft"}]}),s("design:type",Number)],LandscapeCompositeShader.prototype,"transition",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseScale",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"noiseAmount",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"softness",void 0),e([j(),s("design:type",Boolean)],LandscapeCompositeShader.prototype,"enableSlope",void 0),e([j(),s("design:type",t)],LandscapeCompositeShader.prototype,"slopeMaterial",void 0),e([j(),s("design:type",Number)],LandscapeCompositeShader.prototype,"slopeAngle",void 0);class z{constructor(){this.cache=new Map}get(e,s){return this.cache.has(e)||this.cache.set(e,b(e).sample(s)),this.cache.get(e)}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
import { Color, Material, MeshStandardMaterial, MeshStandardMaterialParameters, Texture, Vector2 } from 'three';
|
|
2
2
|
import { Shader } from '../shader.js';
|
|
3
|
+
import { Sampler2DNode } from 'three-shader-graph';
|
|
3
4
|
export declare class StandardShader extends Shader {
|
|
4
5
|
color: Color;
|
|
5
|
-
map?:
|
|
6
|
+
map?: Sampler2DNode;
|
|
6
7
|
opacity: number;
|
|
7
|
-
alphaMap?:
|
|
8
|
+
alphaMap?: Sampler2DNode;
|
|
8
9
|
roughness?: number;
|
|
9
|
-
roughnessMap?:
|
|
10
|
+
roughnessMap?: Sampler2DNode;
|
|
10
11
|
metalness?: number;
|
|
11
|
-
metalnessMap?:
|
|
12
|
-
lightMap?:
|
|
12
|
+
metalnessMap?: Sampler2DNode;
|
|
13
|
+
lightMap?: Sampler2DNode;
|
|
13
14
|
lightMapIntensity?: number;
|
|
14
|
-
aoMap?:
|
|
15
|
+
aoMap?: Sampler2DNode;
|
|
15
16
|
aoMapIntensity?: number;
|
|
16
17
|
emissive?: Color;
|
|
17
18
|
emissiveIntensity?: number;
|
|
18
|
-
emissiveMap?:
|
|
19
|
-
normalMap?:
|
|
19
|
+
emissiveMap?: Sampler2DNode;
|
|
20
|
+
normalMap?: Sampler2DNode;
|
|
20
21
|
normalScale?: Vector2;
|
|
21
22
|
sheen: number;
|
|
22
23
|
sheenColor?: Color;
|
|
23
|
-
sheenColorMap
|
|
24
|
+
sheenColorMap?: Sampler2DNode;
|
|
24
25
|
sheenRoughness: number;
|
|
25
|
-
sheenRoughnessMap
|
|
26
|
+
sheenRoughnessMap?: Sampler2DNode;
|
|
26
27
|
anisotropyRotation?: number;
|
|
27
|
-
anisotropyMap?:
|
|
28
|
+
anisotropyMap?: Sampler2DNode;
|
|
28
29
|
anisotropy?: number;
|
|
29
30
|
envMap?: Texture;
|
|
30
31
|
envMapIntensity?: number;
|
|
31
|
-
heightMap?:
|
|
32
|
+
heightMap?: Sampler2DNode;
|
|
32
33
|
heightScale?: number;
|
|
33
34
|
vertexColor?: boolean;
|
|
34
35
|
uvScale: Vector2;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as o}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as p}from"../../utils/collections.js";import*as l from"three";const d=new r;export class StandardShader extends o{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.opacity=1,this.roughness=1,this.metalness=0,this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenRoughness=.5,this.anisotropy=0,this.heightMap=d,this.vertexColor=!1,this.uvScale=new i(1,1)}build(){const e=this.sheen>0,a=this.anisotropy>0,t=a||e,r=(null!=this.map||null!=this.normalMap)&&null!=this.heightMap&&this.heightMap!=d&&0!==this.heightScale,i=r?ParallaxStandardMaterial:t?l.MeshPhysicalMaterial:n;null!=this.map&&(this.map.colorSpace=l.SRGBColorSpace),null!=this.normalMap&&(this.normalMap.colorSpace=l.LinearSRGBColorSpace),null!=this.metalnessMap&&(this.metalnessMap.colorSpace=l.LinearSRGBColorSpace),null!=this.roughnessMap&&(this.roughnessMap.colorSpace=l.LinearSRGBColorSpace),null!=this.aoMap&&(this.aoMap.colorSpace=l.LinearSRGBColorSpace),null!=this.heightMap&&(this.heightMap.colorSpace=l.NoColorSpace),null!=this.emissiveMap&&(this.emissiveMap.colorSpace=l.SRGBColorSpace),null!=this.alphaMap&&(this.alphaMap.colorSpace=l.LinearSRGBColorSpace),null!=this.lightMap&&(this.lightMap.colorSpace=l.LinearSRGBColorSpace);return new i(p({color:this.color,vertexColors:this.vertexColor,opacity:this.opacity,roughness:this.roughness,metalness:this.metalness,map:applyTiling(this.map,this.uvScale),lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:applyTiling(this.aoMap,this.uvScale),aoMapIntensity:this.aoMapIntensity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:applyTiling(this.emissiveMap,this.uvScale),normalMap:applyTiling(this.normalMap,this.uvScale),normalScale:this.normalScale,sheen:e?this.sheen:void 0,sheenColor:e?this.sheenColor:void 0,sheenColorMap:e?this.sheenColorMap:void 0,sheenRoughness:e?this.sheenRoughness:void 0,sheenRoughnessMap:e?this.sheenRoughnessMap:void 0,anisotropy:a?this.anisotropy:void 0,anisotropyMap:a?this.anisotropyMap:void 0,anisotropyRotation:a?this.anisotropyRotation:void 0,roughnessMap:applyTiling(this.roughnessMap,this.uvScale),metalnessMap:applyTiling(this.metalnessMap,this.uvScale),alphaMap:applyTiling(this.alphaMap,this.uvScale),envMap:this.envMap,envMapIntensity:this.envMapIntensity,...r?{heightMap:this.heightMap,heightScale:this.heightScale}:{}}))}}e([s(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([s({label:"Color Map"}),a("design:type",r)],StandardShader.prototype,"map",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"alphaMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"roughnessMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"metalnessMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"lightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"aoMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([s({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"emissiveMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"normalMap",void 0),e([s(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenColorMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"anisotropyMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"heightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([s(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0),e([s(),a("design:type",i)],StandardShader.prototype,"uvScale",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 viewDirTS = -viewDir * tbn;\n\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float factor = pow(1.0 - abs(vv.z), 2.0);\n float nNumSamples = mix(float(minLayers), float(maxLayers), factor);\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 128; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec3 pomViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv, pomViewDir, vNormal);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv, pomViewDir, vNormal);\n }\n\n vec4 texelColor = texture2D(map, uvPOM);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n // RE-COMPUTE TBN for normal mapping consistency\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uvPOM);\n vec2 duv2 = dFdy(uvPOM);\n vec3 dp2perp = cross(dp2, vNormal);\n vec3 dp1perp = cross(vNormal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 localTBN = mat3(T * invmax, B * invmax, vNormal);\n\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( localTBN * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}export function applyTiling(e,a){if(null==e||null==a)return e;if(1===a.x&&1===a.y)return e;const t=e.clone();return t.repeat.copy(a),t.needsUpdate=!0,t}/*
|
|
1
|
+
import{__decorate as e,__metadata as a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as s}from"../shader.js";import{Parameter as o}from"../parameter.js";import*as p from"three";import{attributes as l,colorToNormal as d,NodeShaderMaterial as h,normalize as m,Sampler2DNode as v,standardMaterial as u,UniformSampler2d as c,uniformFloat as y,uniformVec2 as g,uniformVec3 as f,varying as S,varyingAttributes as M,varyingTransformed as x,vec2 as b}from"three-shader-graph";import{parallaxOcclusionMapping as C}from"../../shader-nodes/pom.js";const w=new r,O=new i(1,1);export class StandardShader extends s{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.map=new c("map",w),this.opacity=1,this.alphaMap=new c("alphaMap",w),this.roughness=1,this.roughnessMap=new c("roughnessMap",w),this.metalness=0,this.metalnessMap=new c("metalnessMap",w),this.lightMap=new c("lightMap",w),this.aoMap=new c("aoMap",w),this.emissiveMap=new c("emissiveMap",w),this.normalMap=new c("normalMap",w),this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenColorMap=new c("sheenColorMap",w),this.sheenRoughness=.5,this.sheenRoughnessMap=new c("sheenRoughnessMap",w),this.anisotropyMap=new c("anisotropyMap",w),this.anisotropy=0,this.heightMap=new c("heightMap",w),this.vertexColor=!1,this.uvScale=O}build(){let e=!1;const a=g("uvScale",this.uvScale??O);let n=M.uv.multiply(a);T(this.heightMap)&&0!==(this.heightScale??.05)&&(n=C(n,this.heightMap,y("heightScale",this.heightScale??.05)));let r=y("opacity",this.opacity),s=f("color",(new p.Vector3).setFromColor(this.color)).rgb;if(T(this.map)){const e=this.map.sample(n);s=s.multiply(e.rgb),r=r.multiply(e.a)}T(this.alphaMap)&&(r=r.multiply(this.alphaMap.sample(n).r)),!0===this.vertexColor&&(s=s.multiply(S(l.color.rgb)));let o=null,v=null;T(this.aoMap)&&(v=y("aoMapIntensity",this.aoMapIntensity??1),o=this.aoMap.sample(n).r);let c=y("roughness",this.roughness??1);T(this.roughnessMap)&&(c=c.multiply(this.roughnessMap.sample(n).g),e=!0);let w=y("metalness",this.metalness??0);T(this.metalnessMap)&&(w=w.multiply(this.metalnessMap.sample(n).b),e=!0);let N=null;T(this.lightMap)&&(N=this.lightMap.sample(n).rgb.multiplyScalar(y("lightMapIntensity",this.lightMapIntensity??1)));let F=f("emissive",(new p.Vector3).setFromColor(this.emissive??new t(0))).rgb;T(this.emissiveMap)&&(F=F.multiply(this.emissiveMap.sample(n).rgb));const L=y("emissiveIntensity",this.emissiveIntensity??1);let R=x.normal;if(T(this.normalMap)){const e=y("normalScale",this.normalScale?.x??1);R=d(this.normalMap.sample(n),e)}let P=null,D=null;if((this.sheen??0)>0){const e=y("sheen",this.sheen??0);P=f("sheenColor",(new p.Vector3).setFromColor(this.sheenColor??new t(16777215))).rgb.multiplyScalar(e),T(this.sheenColorMap)&&(P=P.multiply(this.sheenColorMap.sample(n).rgb)),D=y("sheenRoughness",this.sheenRoughness??.5),T(this.sheenRoughnessMap)&&(D=D.multiply(this.sheenRoughnessMap.sample(n).a))}(this.roughness<1||this.metalness>0)&&(e=!0);let B=null,_=null;if((this.anisotropy??0)>0&&(B=y("anisotropy",this.anisotropy??0),_=g("anisotropyDirection",(I=this.anisotropyRotation??0,new i(Math.cos(I),Math.sin(I)))),T(this.anisotropyMap))){const e=this.anisotropyMap.sample(n),a=m(b(e.r,e.g).multiplyScalar(2).subtract(b(1,1)));_=b(_.x.multiply(a.x).subtract(_.y.multiply(a.y)),_.y.multiply(a.x).add(_.x.multiply(a.y))),B=B.multiply(e.b)}var I;const V=new h({color:u({color:s.rgba(r),roughness:c,metalness:w,ambientOcclusion:o,ambientOcclusionIntensity:v,emissive:F,emissiveIntensity:L,normal:R,bakedLight:N,sheenColor:P,sheenRoughness:D,anisotropy:B,anisotropyDirection:_,specular:e}),opacity:r,roughness:c,normal:R,emissive:F.multiplyScalar(L),envMap:this.envMap});return null!=this.envMap&&(V.uniforms.envMapIntensity={value:this.envMapIntensity??1}),V.vertexColors=!0===this.vertexColor,V}}function T(e){return null!=e&&(!(e instanceof c)||null!=e.value&&e.value!==w)}e([o(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([o({label:"Color Map"}),a("design:type",v)],StandardShader.prototype,"map",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"alphaMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"roughnessMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"metalnessMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"lightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"aoMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([o({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"emissiveMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"normalMap",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenColorMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"anisotropyMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"heightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([o(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"uvScale",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 viewDirTS = -viewDir * tbn;\n\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float factor = pow(1.0 - abs(vv.z), 2.0);\n float nNumSamples = mix(float(minLayers), float(maxLayers), factor);\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 128; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec3 pomViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv, pomViewDir, vNormal);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv, pomViewDir, vNormal);\n }\n\n vec4 texelColor = texture2D(map, uvPOM);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n // RE-COMPUTE TBN for normal mapping consistency\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uvPOM);\n vec2 duv2 = dFdy(uvPOM);\n vec3 dp2perp = cross(dp2, vNormal);\n vec3 dp1perp = cross(vNormal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 localTBN = mat3(T * invmax, B * invmax, vNormal);\n\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( localTBN * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}export function applyTiling(e,a){if(null==e||null==a)return e;if(1===a.x&&1===a.y)return e;const t=e.clone();return t.repeat.copy(a),t.needsUpdate=!0,t}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { Color, Material,
|
|
1
|
+
import { Color, Material, Vector2 } from 'three';
|
|
2
2
|
import { Shader } from '../shader.js';
|
|
3
|
+
import { Sampler2DNode } from 'three-shader-graph';
|
|
3
4
|
export declare class ToonShader extends Shader {
|
|
4
5
|
color: Color;
|
|
5
6
|
opacity: number;
|
|
6
7
|
intensity: number;
|
|
7
|
-
map?:
|
|
8
|
+
map?: Sampler2DNode;
|
|
8
9
|
lightSteps: number[];
|
|
9
|
-
lightMap?:
|
|
10
|
+
lightMap?: Sampler2DNode;
|
|
10
11
|
lightMapIntensity?: number;
|
|
11
|
-
normalMap?:
|
|
12
|
+
normalMap?: Sampler2DNode;
|
|
12
13
|
normalScale?: Vector2;
|
|
13
|
-
aoMap?:
|
|
14
|
+
aoMap?: Sampler2DNode;
|
|
14
15
|
aoMapIntensity?: number;
|
|
15
|
-
alphaMap?:
|
|
16
|
+
alphaMap?: Sampler2DNode;
|
|
16
17
|
emissive?: Color;
|
|
17
18
|
emissiveIntensity?: number;
|
|
18
|
-
emissiveMap?:
|
|
19
|
+
emissiveMap?: Sampler2DNode;
|
|
19
20
|
vertexColor?: boolean;
|
|
21
|
+
uvScale: Vector2;
|
|
20
22
|
build(): Material;
|
|
21
23
|
}
|
|
22
24
|
//# sourceMappingURL=toon-shader.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{Color as o,DataTexture as i,
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{Color as o,DataTexture as i,RedFormat as s,Texture as a,Vector2 as n}from"three";import{Parameter as r}from"../parameter.js";import{Shader as p}from"../shader.js";import*as l from"three";import{attributes as h,colorToNormal as m,NodeShaderMaterial as y,Sampler2DNode as d,toonMaterial as g,UniformSampler2d as v,uniformFloat as c,uniformVec3 as u,varying as S,varyingAttributes as M,varyingTransformed as b,vec2 as T}from"three-shader-graph";const w=new a;export class ToonShader extends p{constructor(){super(...arguments),this.color=new o("#FFFFFF"),this.opacity=1,this.intensity=1,this.map=new v("map",w),this.lightSteps=[],this.lightMap=new v("lightMap",w),this.normalMap=new v("normalMap",w),this.normalScale=new n(1,1),this.aoMap=new v("aoMap",w),this.alphaMap=new v("alphaMap",w),this.emissiveMap=new v("emissiveMap",w),this.vertexColor=!1,this.uvScale=new n(1,1)}build(){let e;if(null!=this.lightSteps&&this.lightSteps.length>0){const t=new Uint8Array(this.lightSteps.length);for(let e=0;e<t.length;e++)t[e]=255*this.lightSteps[e];e=new i(t,t.length,1,s),e.needsUpdate=!0}const t=function(e,t){if(null==t||1===t.x&&1===t.y)return e;return e.multiply(T(t))}(M.uv,this.uvScale);let a=c("opacity",this.opacity),n=u("color",(new l.Vector3).setFromColor(this.color)).rgb.multiplyScalar(c("intensity",this.intensity));if(f(this.map)){const e=this.map.sample(t);n=n.multiply(e.rgb),a=a.multiply(e.a)}f(this.alphaMap)&&(a=a.multiply(this.alphaMap.sample(t).r)),!0===this.vertexColor&&(n=n.multiply(S(h.color.rgb)));let r=null;f(this.lightMap)&&(r=this.lightMap.sample(t).rgb.multiplyScalar(c("lightMapIntensity",this.lightMapIntensity??1)));let p=b.normal;f(this.normalMap)&&(p=m(this.normalMap.sample(t),c("normalScale",this.normalScale?.x??1)));let d=null;f(this.aoMap)&&(d=this.aoMap.sample(t).r);const v=c("aoMapIntensity",this.aoMapIntensity??1);let w=u("emissive",(new l.Vector3).setFromColor(this.emissive??new o(0))).rgb;f(this.emissiveMap)&&(w=w.multiply(this.emissiveMap.sample(t).rgb));const I=c("emissiveIntensity",this.emissiveIntensity??1),x=new y({color:g({color:n.rgba(a),gradientMap:e,bakedLight:r,normal:p,ambientOcclusion:d,ambientOcclusionIntensity:v,emissive:w,emissiveIntensity:I}),opacity:a,normal:p,emissive:w.multiplyScalar(I)});return x.vertexColors=!0===this.vertexColor,x}}function f(e){return null!=e&&(!(e instanceof v)||null!=e.value&&e.value!==w)}e([r(),t("design:type",o)],ToonShader.prototype,"color",void 0),e([r({range:[0,1]}),t("design:type",Number)],ToonShader.prototype,"opacity",void 0),e([r({range:[0,10]}),t("design:type",Number)],ToonShader.prototype,"intensity",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"map",void 0),e([r({type:Number,array:!0,range:[0,1]}),t("design:type",Array)],ToonShader.prototype,"lightSteps",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"lightMap",void 0),e([r(),t("design:type",Number)],ToonShader.prototype,"lightMapIntensity",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"normalMap",void 0),e([r(),t("design:type",n)],ToonShader.prototype,"normalScale",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"aoMap",void 0),e([r(),t("design:type",Number)],ToonShader.prototype,"aoMapIntensity",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"alphaMap",void 0),e([r(),t("design:type",o)],ToonShader.prototype,"emissive",void 0),e([r({range:[0,10]}),t("design:type",Number)],ToonShader.prototype,"emissiveIntensity",void 0),e([r(),t("design:type",d)],ToonShader.prototype,"emissiveMap",void 0),e([r(),t("design:type",Boolean)],ToonShader.prototype,"vertexColor",void 0),e([r(),t("design:type",n)],ToonShader.prototype,"uvScale",void 0);/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Color, Material, Texture, Vector2 } from 'three';
|
|
2
2
|
import { Shader } from '../shader.js';
|
|
3
|
+
import { Sampler2DNode } from 'three-shader-graph';
|
|
3
4
|
export declare class UnlitShader extends Shader {
|
|
4
5
|
color: Color;
|
|
5
6
|
opacity: number;
|
|
6
7
|
intensity: number;
|
|
7
|
-
map?:
|
|
8
|
-
lightMap?:
|
|
8
|
+
map?: Sampler2DNode;
|
|
9
|
+
lightMap?: Sampler2DNode;
|
|
9
10
|
lightMapIntensity?: number;
|
|
10
|
-
aoMap?:
|
|
11
|
+
aoMap?: Sampler2DNode;
|
|
11
12
|
aoMapIntensity?: number;
|
|
12
|
-
alphaMap?:
|
|
13
|
+
alphaMap?: Sampler2DNode;
|
|
13
14
|
envMap?: Texture;
|
|
14
15
|
vertexColor?: boolean;
|
|
15
16
|
uvScale: Vector2;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import{Color as i,
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{Color as i,Texture as o,Vector2 as p}from"three";import{Shader as a}from"../shader.js";import{Parameter as r}from"../parameter.js";import{attributes as n,NodeShaderMaterial as l,rgba as s,Sampler2DNode as h,UniformSampler2d as y,uniformFloat as d,uniformVec3 as m,varying as u,varyingAttributes as c,vec2 as g}from"three-shader-graph";import*as v from"three";const M=new o;export class UnlitShader extends a{constructor(){super(...arguments),this.color=new i("#FFFFFF"),this.opacity=1,this.intensity=1,this.map=new y("map",M),this.lightMap=new y("lightMap",M),this.aoMap=new y("aoMap",M),this.alphaMap=new y("alphaMap",M),this.vertexColor=!1,this.uvScale=new p(1,1)}build(){const t=function(t,e){if(null==e||1===e.x&&1===e.y)return t;return t.multiply(g(e))}(c.uv,this.uvScale);let e=d("opacity",this.opacity),i=m("color",(new v.Vector3).setFromColor(this.color)).rgb.multiplyScalar(d("intensity",this.intensity));if(S(this.map)){const o=this.map.sample(t);i=i.multiply(o.rgb),e=e.multiply(o.a)}if(S(this.alphaMap)&&(e=e.multiply(this.alphaMap.sample(t).r)),!0===this.vertexColor&&(i=i.multiply(u(n.color.rgb))),S(this.lightMap)&&(i=i.add(this.lightMap.sample(t).rgb.multiplyScalar(d("lightMapIntensity",this.lightMapIntensity??1)))),S(this.aoMap)){const e=this.aoMap.sample(t).r,o=d("aoMapIntensity",this.aoMapIntensity??1);i=i.multiplyScalar(e.subtract(1).multiply(o).add(1))}const o=new l({color:s(i,e),opacity:e,emissive:i,envMap:this.envMap});return o.vertexColors=!0===this.vertexColor,o}}function S(t){return null!=t&&(!(t instanceof y)||null!=t.value&&t.value!==M)}t([r(),e("design:type",i)],UnlitShader.prototype,"color",void 0),t([r({range:[0,1]}),e("design:type",Number)],UnlitShader.prototype,"opacity",void 0),t([r({range:[0,10]}),e("design:type",Number)],UnlitShader.prototype,"intensity",void 0),t([r(),e("design:type",h)],UnlitShader.prototype,"map",void 0),t([r(),e("design:type",h)],UnlitShader.prototype,"lightMap",void 0),t([r(),e("design:type",Number)],UnlitShader.prototype,"lightMapIntensity",void 0),t([r(),e("design:type",h)],UnlitShader.prototype,"aoMap",void 0),t([r(),e("design:type",Number)],UnlitShader.prototype,"aoMapIntensity",void 0),t([r(),e("design:type",h)],UnlitShader.prototype,"alphaMap",void 0),t([r(),e("design:type",o)],UnlitShader.prototype,"envMap",void 0),t([r(),e("design:type",Boolean)],UnlitShader.prototype,"vertexColor",void 0),t([r(),e("design:type",p)],UnlitShader.prototype,"uvScale",void 0);/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{BackSide as t,Color as e,DoubleSide as a,FrontSide as r,Matrix4 as u,Texture as i,Vector2 as o,Vector3 as n,Vector4 as s}from"three";import{BooleanNode as l,FloatNode as p,Mat4Node as c,NodeShaderMaterial as h,RgbNode as v,RgbaNode as y,Sampler2DNode as m,Texture2dLookupNode as d,UniformFloatNode as f,Vec2Node as g,Vec3Node as b,Vec4Node as x,abs as w,acos as T,asin as I,attributes as S,atan as O,atan2 as M,autoVarying as C,bulge as N,bool as E,ceil as G,clamp as U,colorToNormal as B,cos as $,cross as z,degrees as V,distance as k,dot as P,exp as A,exp2 as j,float as D,floor as L,fract as q,inversesqrt as F,batchingMatrix as R,colorGradientSampler as _,curveSampler as W,ifDefApply as H,sampleNamedEasingCurve as Y,length as J,LayerMixMode as K,log as Q,log2 as X,mat4 as Z,max as tt,min as et,mix as at,mixColorsByLayer as rt,particleUniforms as ut,mod as it,normalize as ot,pow as nt,radians as st,rgba as lt,rgb as pt,saturate as ct,select as ht,sign as vt,sin as yt,smoothstep as mt,sqrt as dt,standardMaterial as ft,scaleTransform as gt,step as bt,tan as xt,textureSampler2d as wt,timeUniforms as Tt,toonMaterial as It,translate as St,transformed as Ot,triplanarMapping as Mt,twirl as Ct,uniformFloat as Nt,uniforms as Et,varyingAttributes as Gt,vec2 as Ut,vec3 as Bt,vec4 as $t,getPaintedMaterialLayerWeight as zt}from"../../shader-nodes/index.js";import{SpriteNodeShaderMaterial as Vt,getSpritePosition as kt}from"../sprite-shader.js";import{oneMinus as Pt}from"../../shader-nodes/index.js";import{vectorToRadial as At,remap as jt,hueShift as Dt,blendColor as Lt,desaturateColor as qt}from"../../shader-nodes/math.js";import{rectangleFloat as Ft,roundedRectangleFloat as Rt}from"../../shader-nodes/shapes.js";import{edgeDepthEffect as _t,fresnelEffect as Wt,depthFadeEffect as Ht}from"../../shader-nodes/effects.js";import{fragmentLinearEyeDepth as Yt,sampleSceneDepth as Jt,sampleSceneLinearEyeDepth as Kt,screenUV as Qt,nearUniformName as Xt,farUniformName as Zt}from"../../shader-nodes/depth.js";import{sampleSceneColor as te}from"../../shader-nodes/scene-sample.js";import{decalDiscard as ee,decalUV as ae}from"../../shader-nodes/decal.js";import{Trail as re,trailUV as ue}from"../../effects/vfx/trail-renderer.js";import{SimplexNoiseNode as ie,Voronoi2d as oe,rotateAxis as ne}from"../../shader-nodes/index.js";import{flipbookUv as se}from"../../shader-nodes/texture-sequence.js";import{parallaxOcclusionMapping as le}from"../../shader-nodes/pom.js";import{defaultInlineLiteralValueForPort as pe,inlineLiteralTypeForPort as ce,SHADER_GRAPH_NODE_DEFINITIONS as he}from"./registry.js";import{shaderGraphParameterTypeToValueType as ve}from"./parameters.js";import{varying as ye,reflect as me,refract as de,dFdx as fe,dFdy as ge,fwidth as be}from"three-shader-graph";import{decalNormal as xe}from"../../shader-nodes/decal.js";import{Curve2 as we}from"../../utils/curve.js";export class ShaderGraphCompileError extends Error{constructor(t,e,a){super(t),this.nodeId=e,this.port=a,this.name="ShaderGraphCompileError"}}export const shaderGraphPostProcessWeightUniformName="hology_post_process_weight";export class ShaderGraphCompiler{constructor(t,e={}){this.graph=t,this.options=e,this.compiled=new Map,this.nodesById=new Map((t.nodes??[]).map(t=>[t.id,t]))}validate(){this.compile()}compile(){if(1!==this.graph.version)throw new ShaderGraphCompileError(`Unsupported shader graph version ${this.graph.version}`);return this.validateEdges(),{output:this.compileOutput(),nodes:this.compiled}}validateEdges(){for(const t of this.graph.edges??[]){if(!this.nodesById.has(t.from.nodeId))throw new ShaderGraphCompileError(`Edge references missing source node "${t.from.nodeId}"`,t.from.nodeId,t.from.port);if(!this.nodesById.has(t.to.nodeId))throw new ShaderGraphCompileError(`Edge references missing target node "${t.to.nodeId}"`,t.to.nodeId,t.to.port)}}compileOutput(){if("postProcess"===this.graph.target)return this.compilePostProcessOutput();const t=this.graph.outputs?.color,e={color:null!=t?this.toColorOutput(this.resolveOutputBinding(t,"color")):lt("#ffffff",1),transparent:Ie(this.graph)},a=this.graph.outputs?.opacity;null!=a&&(e.opacity=this.expectType(this.resolveOutputBinding(a,"opacity"),["float"],"opacity").value);const r=this.graph.outputs?.roughness;null!=r&&(e.roughness=this.expectType(this.resolveOutputBinding(r,"roughness"),["float"],"roughness").value);const u=this.graph.outputs?.metalness;null!=u&&(e.metalness=this.floatOutput(u,"metalness"));const i=this.graph.outputs?.normal;null!=i&&(e.normal=this.toVec3Output(this.resolveOutputBinding(i,"normal"),"normal"));const o=this.graph.outputs?.emissive;null!=o&&(e.emissive=this.toVec3Output(this.resolveOutputBinding(o,"emissive"),"emissive"));const n=this.graph.outputs?.ambientOcclusion;null!=n&&(e.ambientOcclusion=this.floatOutput(n,"ambientOcclusion"));const s=this.graph.outputs?.ambientOcclusionIntensity;null!=s&&(e.ambientOcclusionIntensity=this.floatOutput(s,"ambientOcclusionIntensity"));const l=this.graph.outputs?.sheenColor;null!=l&&(e.sheenColor=this.toVec3Output(this.resolveOutputBinding(l,"sheenColor"),"sheenColor"));const p=this.graph.outputs?.sheenRoughness;null!=p&&(e.sheenRoughness=this.floatOutput(p,"sheenRoughness"));const c=this.graph.outputs?.anisotropy;null!=c&&(e.anisotropy=this.floatOutput(c,"anisotropy"));const h=this.graph.outputs?.anisotropyDirection;null!=h&&(e.anisotropyDirection=this.expectType(this.resolveOutputBinding(h,"anisotropyDirection"),["vec2"],"anisotropyDirection").value);const v=this.graph.outputs?.bakedLight;null!=v&&(e.bakedLight=this.toVec3Output(this.resolveOutputBinding(v,"bakedLight"),"bakedLight"));const y=this.graph.outputs?.transform;null!=y&&"decal"!==this.graph.target&&(e.transform=this.toMat4Output(this.resolveOutputBinding(y,"transform"),"transform"));const m=this.graph.outputs?.discard;null!=m&&(e.discard=this.expectType(this.resolveOutputBinding(m,"discard"),["boolean"],"discard").value);const d=this.graph.outputs?.transparent;null!=d&&null!=d.value&&(e.transparent=Boolean(d.value));const f=this.graph.outputs?.alphaTest;return null!=f&&null!=f.value&&(e.alphaTest=Number(f.value)),this.applyShadingModel(e)}compilePostProcessOutput(){const t=this.graph.outputs?.color,e=null!=t?this.toColorOutput(this.resolveOutputBinding(t,"color")):te(Qt),a=this.graph.outputs?.opacity;return Te(e,null!=a?this.expectType(this.resolveOutputBinding(a,"opacity"),["float"],"opacity").value:void 0)}applyShadingModel(t){const e=null!=t.opacity?function(t,e){if(t instanceof p)return lt(Bt(t,t,t),e);if(t instanceof g)return lt(Bt(t.x,t.y,0),e);if(t instanceof x)return lt(t.rgb,t.w.multiply(e));return lt(t,e)}(t.color,t.opacity):t.color;switch(this.graph.shadingModel??"standard"){case"standard":{const a={color:Ce(e),roughness:t.roughness??D(.5),...null!=t.metalness?{metalness:t.metalness}:{},..."decal"===this.graph.target?{normal:ot(ye(Et.normalMatrix).multiplyVec(xe))}:{},...null!=t.normal?{normal:t.normal}:{},...null!=t.emissive?{emissive:Ne(t.emissive)}:{},...null!=t.ambientOcclusion?{ambientOcclusion:t.ambientOcclusion}:{},...null!=t.ambientOcclusionIntensity?{ambientOcclusionIntensity:t.ambientOcclusionIntensity}:{},...null!=t.sheenColor?{sheenColor:t.sheenColor.rgb}:{},...null!=t.sheenRoughness?{sheenRoughness:t.sheenRoughness}:{},...null!=t.anisotropy?{anisotropy:t.anisotropy}:{},...null!=t.anisotropyDirection?{anisotropyDirection:t.anisotropyDirection}:{},...null!=t.bakedLight?{bakedLight:t.bakedLight}:{}};return{...t,color:ft(a)}}case"toon":{const a={color:Ce(e),...null!=t.normal?{normal:t.normal}:{},...null!=t.emissive?{emissive:Ne(t.emissive)}:{},...null!=t.ambientOcclusion?{ambientOcclusion:t.ambientOcclusion}:{},...null!=t.ambientOcclusionIntensity?{ambientOcclusionIntensity:t.ambientOcclusionIntensity}:{},...null!=t.bakedLight?{bakedLight:t.bakedLight}:{}};return{...t,color:It(a)}}case"unlit":return{...t,color:e}}}compileNode(t){const e=this.compiled.get(t);if(null!=e)return e;const a=this.nodesById.get(t);if(null==a)throw new ShaderGraphCompileError(`Missing shader graph node "${t}"`,t);if(null==he[a.kind])throw new ShaderGraphCompileError(`Unsupported shader graph node "${a.kind}"`,a.id);const r=this.compileNodeInternal(a);return this.compiled.set(t,r),r}compileNodeInternal(t){switch(t.kind){case"input.parameter":return this.output(t,this.compileParameterNode(t));case"input.slider":return this.output(t,{value:{type:"float",value:D(Ae(Ge(t,"value",.5)))}});case"constant.boolean":return this.output(t,{value:{type:"boolean",value:E(Boolean(Ee(t,"value",!1)))}});case"constant.float":return this.output(t,{value:{type:"float",value:D(Ge(t,"value",0))}});case"constant.vec2":return this.output(t,{value:{type:"vec2",value:Le(Ee(t,"value",[0,0]))}});case"constant.vec3":return this.output(t,{value:{type:"vec3",value:qe(Ee(t,"value",[0,0,0]))}});case"constant.rgba":return this.output(t,{value:{type:"rgba",value:Fe(Ee(t,"value","#ffffff"),Ge(t,"alpha",1))}});case"builtin.uv":{const e=this.defaultUV();return this.output(t,{value:{type:"vec2",value:!0===Ee(t,"flipY",!1)?Ut(e.x,Pt(e.y)):e},u:{type:"float",value:e.x},v:{type:"float",value:e.y}})}case"builtin.screenUv":return this.output(t,{value:{type:"vec2",value:Qt}});case"builtin.color":{const e=C(S.color);return this.output(t,{value:{type:"rgba",value:e},rgb:{type:"rgb",value:e.rgb},r:{type:"float",value:e.r},g:{type:"float",value:e.g},b:{type:"float",value:e.b},a:{type:"float",value:e.a}})}case"builtin.position":{const e=C(S.position);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.worldPosition":{const e=C(Ot.worldPosition);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.objectPosition":{let e=Et.instanceMatrix.multiplyVec($t(0,0,0,1));e=H("USE_BATCHING",e,t=>R.multiplyVec(t));const a=C(Et.modelMatrix.multiplyVec(e).xyz);return this.output(t,{value:{type:"vec3",value:a},x:{type:"float",value:a.x},y:{type:"float",value:a.y},z:{type:"float",value:a.z}})}case"builtin.viewDir":{const e=C(Ot.viewDir);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.normal":{const e=C(S.normal);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.time":return this.output(t,{value:{type:"float",value:Tt.elapsed}});case"builtin.camera":{const e=Nt(Xt),a=Nt(Zt),r=Et.cameraPosition;return this.output(t,{position:{type:"vec3",value:r},x:{type:"float",value:r.x},y:{type:"float",value:r.y},z:{type:"float",value:r.z},near:{type:"float",value:e},far:{type:"float",value:a}})}case"builtin.viewMatrix":return this.output(t,{value:{type:"mat4",value:Et.viewMatrix}});case"builtin.projectionMatrix":return this.output(t,{value:{type:"mat4",value:Et.projectionMatrix}});case"builtin.modelViewMatrix":return this.output(t,{value:{type:"mat4",value:Et.modelViewMatrix}});case"builtin.particle":return this.output(t,{energy:{type:"float",value:ut.energy},color:{type:"rgb",value:ut.color},opacity:{type:"float",value:ut.opacity},time:{type:"float",value:ut.time}});case"math.add":case"math.subtract":case"math.multiply":case"math.divide":return this.output(t,{value:this.compileBinaryMath(t)});case"math.oneMinus":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:e.type,value:Pt(e.value)}})}case"math.abs":return this.output(t,{value:this.compileUnaryMath(t,w)});case"math.sign":return this.output(t,{value:this.compileUnaryMath(t,vt)});case"math.floor":return this.output(t,{value:this.compileUnaryMath(t,L)});case"math.ceil":return this.output(t,{value:this.compileUnaryMath(t,G)});case"math.fract":return this.output(t,{value:this.compileUnaryMath(t,q)});case"math.sin":return this.output(t,{value:this.compileUnaryMath(t,yt)});case"math.cos":return this.output(t,{value:this.compileUnaryMath(t,$)});case"math.tan":return this.output(t,{value:this.compileUnaryMath(t,xt)});case"math.asin":return this.output(t,{value:this.compileUnaryMath(t,I)});case"math.acos":return this.output(t,{value:this.compileUnaryMath(t,T)});case"math.atan":return this.output(t,{value:this.compileUnaryMath(t,O)});case"math.atan2":return this.output(t,{value:this.compileAtan2(t)});case"math.radians":return this.output(t,{value:this.compileUnaryMath(t,st)});case"math.degrees":return this.output(t,{value:this.compileUnaryMath(t,V)});case"math.sqrt":return this.output(t,{value:this.compileUnaryMath(t,dt)});case"math.inverseSqrt":return this.output(t,{value:this.compileUnaryMath(t,F)});case"math.exp":return this.output(t,{value:this.compileUnaryMath(t,A)});case"math.exp2":return this.output(t,{value:this.compileUnaryMath(t,j)});case"math.log":return this.output(t,{value:this.compileUnaryMath(t,Q)});case"math.log2":return this.output(t,{value:this.compileUnaryMath(t,X)});case"math.saturate":return this.output(t,{value:this.compileUnaryMath(t,ct)});case"math.length":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:"float",value:J(e.value)}})}case"math.normalize":return this.output(t,{value:this.compileUnaryMath(t,ot)});case"math.clamp":{const e=this.expectNumeric(this.input(t,"value")),a=this.expectNumeric(this.input(t,"min",{type:"float",value:D(0)})),r=this.expectNumeric(this.input(t,"max",{type:"float",value:D(1)}));return this.output(t,{value:{type:e.type,value:U(e.value,a.value,r.value)}})}case"math.min":return this.output(t,{value:this.compileBinaryFunction(t,et)});case"math.max":return this.output(t,{value:this.compileBinaryFunction(t,tt)});case"math.pow":return this.output(t,{value:this.compileBinaryFunction(t,nt)});case"math.mod":return this.output(t,{value:this.compileBinaryFunction(t,it)});case"math.step":return this.output(t,{value:this.compileBinaryFunction(t,bt,!0)});case"math.smoothstep":{const e=this.expectNumeric(this.input(t,"edge0",{type:"float",value:D(0)})),a=this.expectNumeric(this.input(t,"edge1",{type:"float",value:D(1)})),r=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:r.type,value:mt(e.value,a.value,r.value)}})}case"math.mix":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b")),r=this.expectNumeric(this.input(t,"t",{type:"float",value:D(.5)})),u=ze(e.type,a.type,t.id);return this.output(t,{value:{type:u,value:at(e.value,a.value,r.value)}})}case"math.remap":{const e=this.expectType(this.input(t,"value"),["float"],t.id,"value").value,a=this.floatInput(t,"inMin",-1),r=this.floatInput(t,"inMax",1),u=this.floatInput(t,"outMin",0),i=this.floatInput(t,"outMax",1);return this.output(t,{value:{type:"float",value:jt(e,a,r,u,i)}})}case"math.select":{const e=this.boolInput(t,"condition",!1),a=this.expectNumeric(this.input(t,"a")),r=this.expectNumeric(this.input(t,"b")),u=ze(a.type,r.type,t.id);return this.output(t,{value:{type:u,value:ht(e,a.value,r.value)}})}case"math.reflect":{const e=this.expectType(this.input(t,"incident"),["vec2","vec3","vec4","rgb","rgba"],t.id,"incident"),a=this.expectType(this.input(t,"normal"),["vec2","vec3","vec4","rgb","rgba"],t.id,"normal");return this.output(t,{value:{type:e.type,value:me(e.value,a.value)}})}case"math.refract":{const e=this.expectType(this.input(t,"incident"),["vec2","vec3","vec4","rgb","rgba"],t.id,"incident"),a=this.expectType(this.input(t,"normal"),["vec2","vec3","vec4","rgb","rgba"],t.id,"normal"),r=this.floatInput(t,"ior",1.5);return this.output(t,{value:{type:e.type,value:de(e.value,a.value,r)}})}case"math.derivative":{const e=this.expectNumeric(this.input(t,"value")),a=String(Ee(t,"mode","fwidth"));let r;return r="dFdx"===a?fe(e.value):"dFdy"===a?ge(e.value):be(e.value),this.output(t,{value:{type:e.type,value:r}})}case"layer.mixPainted":return this.output(t,{value:this.compilePaintedLayerMix(t)});case"math.dot":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b"));return ze(e.type,a.type,t.id),this.output(t,{value:{type:"float",value:P(e.value,a.value)}})}case"math.distance":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b"));return ze(e.type,a.type,t.id),this.output(t,{value:{type:"float",value:k(e.value,a.value)}})}case"math.cross":{const e=this.expectType(this.input(t,"a"),["vec3","rgb"],t.id,"a"),a=this.expectType(this.input(t,"b"),["vec3","rgb"],t.id,"b");return this.output(t,{value:{type:"vec3",value:z(e.value,a.value)}})}case"compare.greaterThan":case"compare.greaterThanOrEqual":case"compare.lessThan":case"compare.lessThanOrEqual":case"compare.equal":case"compare.notEqual":return this.output(t,{value:{type:"boolean",value:this.compileComparison(t)}});case"boolean.not":{const e=this.boolInput(t,"value",!1);return this.output(t,{value:{type:"boolean",value:ht(e,E(!1),E(!0))}})}case"boolean.and":return this.output(t,{value:{type:"boolean",value:this.compileBooleanBinary(t,"and")}});case"boolean.or":return this.output(t,{value:{type:"boolean",value:this.compileBooleanBinary(t,"or")}});case"compose.vec2":return this.output(t,{value:{type:"vec2",value:Ut(this.floatInput(t,"x",0),this.floatInput(t,"y",0))}});case"compose.vec3":return this.output(t,{value:{type:"vec3",value:Bt(this.floatInput(t,"x",0),this.floatInput(t,"y",0),this.floatInput(t,"z",0))}});case"compose.vec4":return this.output(t,{value:{type:"vec4",value:$t(this.floatInput(t,"x",0),this.floatInput(t,"y",0),this.floatInput(t,"z",0),this.floatInput(t,"w",0))}});case"compose.rgba":return this.output(t,{value:{type:"rgba",value:$t(this.floatInput(t,"r",1),this.floatInput(t,"g",1),this.floatInput(t,"b",1),this.floatInput(t,"a",1))}});case"decompose.component":{const e=this.expectNumeric(this.input(t,"value")),a=String(Ee(t,"component","x"));return this.output(t,{value:{type:"float",value:ke(e,a,t.id)}})}case"decompose.split":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,function(t,e){const a={},r=(r,u)=>{a[r]={type:"float",value:ke(t,u,e)}};switch(t.type){case"vec2":return r("x","x"),r("y","y"),r("u","x"),r("v","y"),a;case"vec3":return r("x","x"),r("y","y"),r("z","z"),a;case"rgb":return r("r","r"),r("g","g"),r("b","b"),r("x","x"),r("y","y"),r("z","z"),a;case"vec4":return r("x","x"),r("y","y"),r("z","z"),r("w","w"),a;case"rgba":return r("r","r"),r("g","g"),r("b","b"),r("a","a"),r("x","x"),r("y","y"),r("z","z"),r("w","w"),a;case"float":return a.x={type:"float",value:t.value},a}}(e,t.id))}case"color.gradient":{const e=this.expectType(this.input(t,"t",{type:"float",value:D(.5)}),["float"],t.id,"t"),a=_(function(t){const e=Ee(t,"stops",[]);if(!Array.isArray(e))return[];const a=e.map((t,a)=>{if(null==t||"object"!=typeof t||Array.isArray(t))return;const r=t,u="string"==typeof r.color?r.color:"#ffffff";return{position:je(r.position,Re(a,e.length)),color:u,alpha:je(r.alpha,1)}}).filter(t=>null!=t);return a.length>0?a:[]}(t)).sample(e.value);return this.output(t,{value:{type:"rgba",value:a}})}case"utility.curve":{const e=this.expectType(this.input(t,"t",{type:"float",value:D(.5)}),["float"],t.id,"t"),a=Ee(t,"curve","Linear"),r=Y(a,e.value)??W(we.decode(a)).sample(e.value);return this.output(t,{value:{type:"float",value:r}})}case"color.hueShift":{const e=this.expectType(this.input(t,"color"),["rgba","rgb","vec4","vec3"],t.id,"color"),a=e.value,r="rgba"===e.type||"vec4"===e.type?a.rgb??a.xyz:a,u=this.floatInput(t,"shift",0),i=Dt(r,u);return"rgba"===e.type||"vec4"===e.type?this.output(t,{value:{type:e.type,value:$t(i,a.a??a.w)}}):this.output(t,{value:{type:e.type,value:i}})}case"color.blend":{const e=this.expectType(this.input(t,"base"),["rgba","rgb","vec4","vec3"],t.id,"base"),a=this.expectType(this.input(t,"blend"),["rgba","rgb","vec4","vec3"],t.id,"blend"),r=String(Ee(t,"mode","multiply")),u=e.value,i=a.value,o="rgba"===e.type||"vec4"===e.type?u.rgb??u.xyz:u,n="rgba"===a.type||"vec4"===a.type?i.rgb??i.xyz:i;let s=Lt(o,n,r);if("rgba"===a.type||"vec4"===a.type){const t=i.a??i.w;s=at(o,s,t)}if("rgba"===e.type||"vec4"===e.type){const a=u.a??u.w;return this.output(t,{value:{type:e.type,value:$t(s,a)}})}return this.output(t,{value:{type:e.type,value:s}})}case"color.desaturate":{const e=this.expectType(this.input(t,"color"),["rgba","rgb","vec4","vec3"],t.id,"color"),a=e.value,r="rgba"===e.type||"vec4"===e.type?a.rgb??a.xyz:a,u=this.floatInput(t,"fraction",1),i=qt(r,u);return"rgba"===e.type||"vec4"===e.type?this.output(t,{value:{type:e.type,value:$t(i,a.a??a.w)}}):this.output(t,{value:{type:e.type,value:i}})}case"color.unpackNormal":{const e=this.expectType(this.input(t,"color"),["vec3","vec4","rgb","rgba"],t.id,"color"),a=this.floatInput(t,"scale",1),r=this.optionalInput(t,"normal");return this.output(t,{value:{type:"vec3",value:B(e.value,a,r?this.expectType(r,["vec3"],t.id,"normal").value:void 0)}})}case"texture.sampler2d":{const e=this.input(t,"texture");return this.output(t,{value:this.toSampler(e,t.id)})}case"texture.sample2d":{const e=this.toSampler(this.input(t,"sampler"),t.id),a=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv"),r=e.value.sample(a.value);return this.output(t,{rgba:{type:"rgba",value:r},rgb:{type:"rgb",value:r.rgb},r:{type:"float",value:r.r},g:{type:"float",value:r.g},b:{type:"float",value:r.b},a:{type:"float",value:r.a}})}case"texture.triplanarMapping":{const e=this.input(t,"sampler"),a=this.toSampler(e,t.id),r=this.expectType(this.input(t,"scale",{type:"float",value:D(1)}),["float"],t.id,"scale"),u=this.expectType(this.input(t,"normal",{type:"vec3",value:Gt.normal}),["vec3"],t.id,"normal"),i=this.expectType(this.input(t,"position",{type:"vec3",value:Gt.position}),["vec3"],t.id,"position"),o=Mt(a.value,r.value,u.value,i.value);return this.output(t,{rgba:{type:"rgba",value:o},rgb:{type:"rgb",value:o.rgb},r:{type:"float",value:o.r},g:{type:"float",value:o.g},b:{type:"float",value:o.b},a:{type:"float",value:o.a}})}case"scene.sampleColor":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:Qt}),["vec2"],t.id,"uv"),a=te(e.value);return this.output(t,{rgba:{type:"rgba",value:a},rgb:{type:"rgb",value:a.rgb},r:{type:"float",value:a.r},g:{type:"float",value:a.g},b:{type:"float",value:a.b},a:{type:"float",value:a.a}})}case"scene.sampleDepth":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:Qt}),["vec2"],t.id,"uv");return this.output(t,{depth:{type:"float",value:Jt(e.value)},linearEyeDepth:{type:"float",value:Kt(e.value)}})}case"scene.fragmentDepth":return this.output(t,{linearEyeDepth:{type:"float",value:Yt}});case"transform.translate":{const e=this.expectType(this.input(t,"offset",{type:"vec3",value:Bt(0,0,0)}),["vec3","rgb"],t.id,"offset");return this.output(t,{value:{type:"mat4",value:St(e.value)}})}case"transform.scale":{const e=this.expectType(this.input(t,"scale",{type:"vec3",value:Bt(1,1,1)}),["vec3","rgb"],t.id,"scale").value;return this.output(t,{value:{type:"mat4",value:gt(e.x,e.y,e.z)}})}case"transform.rotateAxis":{const e=this.expectType(this.input(t,"axis",{type:"vec3",value:Bt(0,1,0)}),["vec3","rgb"],t.id,"axis"),a=this.expectType(this.input(t,"angle",{type:"float",value:D(0)}),["float"],t.id,"angle");return this.output(t,{value:{type:"mat4",value:ne(e.value,a.value)}})}case"uv.rotate":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"angle",{type:"float",value:D(0)}),["float"],t.id,"angle").value,r=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value;return this.output(t,{value:{type:"vec2",value:Ve(e,a,r)}})}case"uv.twirl":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"strength",{type:"float",value:D(1)}),["float"],t.id,"strength").value,r=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value,u=this.expectType(this.input(t,"offset",{type:"vec2",value:Ut(0,0)}),["vec2"],t.id,"offset").value;return this.output(t,{value:{type:"vec2",value:Ct(e,a,r,u)}})}case"uv.radial":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=At(e.subtractScalar(.5));return this.output(t,{coords:{type:"vec2",value:a.coords},radius:{type:"float",value:a.radius},angle:{type:"float",value:a.angle}})}case"uv.bulge":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value,r=this.expectType(this.input(t,"power",{type:"float",value:D(1)}),["float"],t.id,"power").value;return this.output(t,{value:{type:"vec2",value:N(e,a,r)}})}case"uv.flipbook":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"columns",Ge(t,"columns",1)),r=this.floatInput(t,"rows",Ge(t,"rows",1)),u=this.floatInput(t,"fps",Ge(t,"fps",60)),i=this.expectType(this.input(t,"time",{type:"float",value:Tt.elapsed}),["float"],t.id,"time").value,o=String(Ee(t,"mode","clamp"));return this.output(t,{value:{type:"vec2",value:se(e,a,r,i,u,o)}})}case"uv.pom":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.input(t,"heightMap"),r=this.toSampler(a,t.id).value,u=this.floatInput(t,"heightScale",.05),i=Ge(t,"minLayers",8),o=Ge(t,"maxLayers",24);return this.output(t,{value:{type:"vec2",value:le(e,r,u,i,o)}})}case"shape.rectangle":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value;return this.output(t,{value:{type:"float",value:Ft(e,this.floatInput(t,"width",.5),this.floatInput(t,"height",.5))}})}case"shape.roundedRectangle":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value;return this.output(t,{value:{type:"float",value:Rt(e,this.floatInput(t,"width",.5),this.floatInput(t,"height",.5),this.floatInput(t,"radius",.1))}})}case"noise.simplex":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"scale",8);return this.output(t,{value:{type:"float",value:new ie(e.multiplyScalar(a))}})}case"noise.voronoi2d":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"scale",8);return this.output(t,{value:{type:"float",value:new oe(e.multiplyScalar(a))}})}case"effect.fresnel":return this.output(t,{value:{type:"float",value:C(Wt(this.floatInput(t,"power",1)))}});case"effect.edgeDepth":{const e=this.floatInput(t,"power",1);return this.output(t,{value:{type:"float",value:_t(e)}})}case"effect.depthFade":{const e=this.floatInput(t,"distance",1);return this.output(t,{value:{type:"float",value:Ht(e)}})}case"util.panner":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"coord"),a=this.expectType(this.input(t,"speed",{type:"vec2",value:Ut(0,0)}),["vec2"],t.id,"speed"),r=this.expectType(this.input(t,"tile",{type:"vec2",value:Ut(1,1)}),["vec2"],t.id,"tile"),u=this.expectType(this.input(t,"time",{type:"float",value:Tt.elapsed}),["float"],t.id,"time");return this.output(t,{value:{type:"vec2",value:e.value.multiply(r.value).add(a.value.multiplyScalar(u.value))}})}}}compileParameterNode(t){const e=String(Ee(t,"parameter","")),a=this.graph.parameters?.find(t=>t.name===e||t.id===e);if(null==a)throw new ShaderGraphCompileError(`Parameter "${e}" does not exist`,t.id);const r=ve(a.type),u={type:r,value:Be(this.options.parameters?.[a.name]??a.defaultValue,r,a.name)};if("sampler2d"!==r)return{value:u};const i=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv"),o=u.value.sample(i.value);return{value:{type:"rgba",value:o},rgb:{type:"rgb",value:o.rgb},r:{type:"float",value:o.r},g:{type:"float",value:o.g},b:{type:"float",value:o.b},a:{type:"float",value:o.a},sampler:u}}compileBinaryMath(t){const e=this.expectBinaryMathValue(this.input(t,"a")),a=this.expectBinaryMathValue(this.input(t,"b")),r=t.kind.split(".")[1];if("mat4"===e.type||"mat4"===a.type)return function(t,e,a,r){if("mat4"===t.type&&"mat4"===e.type&&"divide"!==a)return{type:"mat4",value:$e(t.value,e.value,a,r)};if("mat4"===t.type&&"float"===e.type&&("multiply"===a||"divide"===a))return{type:"mat4",value:$e(t.value,e.value,a,r)};if("float"===t.type&&"mat4"===e.type&&"multiply"===a)return{type:"mat4",value:$e(e.value,t.value,a,r)};if("mat4"===t.type&&"vec4"===e.type&&"multiply"===a)return{type:"vec4",value:t.value.multiplyVec(e.value)};throw new ShaderGraphCompileError(`Cannot ${a} ${t.type} and ${e.type}`,r)}(e,a,r,t.id);if(e.type===a.type)return{type:e.type,value:$e(e.value,a.value,r,t.id)};if("float"===e.type&&"float"!==a.type&&"multiply"===r)return{type:a.type,value:$e(a.value,e.value,r,t.id)};if("float"!==e.type&&"float"===a.type)return{type:e.type,value:$e(e.value,a.value,r,t.id)};throw new ShaderGraphCompileError(`Cannot ${r} ${e.type} and ${a.type}`,t.id)}expectBinaryMathValue(t){if(!Pe(t.type)&&"mat4"!==t.type)throw new ShaderGraphCompileError(`Expected a numeric value but got ${t.type}`);return t}compileUnaryMath(t,e){const a=this.expectNumeric(this.input(t,"value"));return{type:a.type,value:e(a.value)}}compileAtan2(t){const e=this.expectNumeric(this.input(t,"y")),a=this.expectNumeric(this.input(t,"x"));return{type:function(t,e,a){if(t===e)return t;if("rgb"===t&&"vec3"===e||"vec3"===t&&"rgb"===e)return"vec3";if("rgba"===t&&"vec4"===e||"vec4"===t&&"rgba"===e)return"vec4";throw new ShaderGraphCompileError(`Cannot mix ${t} and ${e}`,a)}(e.type,a.type,t.id),value:M(e.value,a.value)}}compileBinaryFunction(t,e,a=!1){const r=this.expectNumeric(this.input(t,"a")),u=this.expectNumeric(this.input(t,"b"));return{type:a&&"float"===u.type?r.type:ze(r.type,u.type,t.id),value:e(r.value,u.value)}}compilePaintedLayerMix(t){const e=this.expectNumeric(this.input(t,"base")),a=[e.value],r=[zt(0)];let u=e.type;for(let e=1;e<=8;e++){const i=this.optionalInput(t,`layer${e}`);if(null==i)continue;const o=this.expectNumeric(i);u=ze(u,o.type,t.id),a.push(o.value),r.push(zt(e))}return 1===a.length?e:{type:u,value:rt({layerColors:a,layerWeights:r,enableNoise:Boolean(Ee(t,"enableNoise",!0)),noiseScale:this.floatInput(t,"noiseScale",Ge(t,"noiseScale",.1)),noiseAmount:this.floatInput(t,"noiseAmount",Ge(t,"noiseAmount",.5)),decay:this.floatInput(t,"softness",Ge(t,"softness",.3)),mode:"hard"===String(Ee(t,"mode","soft"))?K.hard:K.soft})}}defaultUV(){return"trail"===this.graph.target?ue:"decal"===this.graph.target?ae:C(S.uv)}input(t,e,a){const r=t.inputs?.[e];if(null!=r)return this.resolveInput(r,t.id,e);const u=(this.graph.edges??[]).find(a=>a.to.nodeId===t.id&&a.to.port===e);if(null!=u)return this.resolveSocket(u.from,t.id,e);if(null!=a)return a;const i=this.inlineLiteralFallback(t,e);if(null!=i)return i;throw new ShaderGraphCompileError(`Missing input "${e}"`,t.id,e)}optionalInput(t,e){const a=t.inputs?.[e];if(null!=a)return this.resolveInput(a,t.id,e);const r=(this.graph.edges??[]).find(a=>a.to.nodeId===t.id&&a.to.port===e);return null!=r?this.resolveSocket(r.from,t.id,e):void 0}floatInput(t,e,a){return this.expectType(this.input(t,e,{type:"float",value:D(a)}),["float"],t.id,e).value}boolInput(t,e,a){return this.expectType(this.input(t,e,{type:"boolean",value:E(a)}),["boolean"],t.id,e).value}compileComparison(t){const e=this.expectType(this.input(t,"a"),["float"],t.id,"a").value,a=this.expectType(this.input(t,"b"),["float"],t.id,"b").value;switch(t.kind){case"compare.greaterThan":return e.gt(a);case"compare.greaterThanOrEqual":return e.gte(a);case"compare.lessThan":return e.lt(a);case"compare.lessThanOrEqual":return e.lte(a);case"compare.equal":return e.equals(a);case"compare.notEqual":return e.notEquals(a)}throw new ShaderGraphCompileError(`Unsupported comparison node "${t.kind}"`,t.id)}compileBooleanBinary(t,e){const a=this.boolInput(t,"a",!1),r=this.boolInput(t,"b",!1);return"and"===e?a.and(r):a.or(r)}resolveOutputBinding(t,e){if(null!=t.input)return this.resolveSocket(t.input,void 0,e);if(void 0!==t.value)return Ue(t.value);throw new ShaderGraphCompileError(`Output "${e}" is missing an input or value`)}floatOutput(t,e){return this.expectType(this.resolveOutputBinding(t,e),["float"],e).value}resolveInput(t,e,a){return function(t){return null!=t.nodeId}(t)?this.resolveSocket(t,e,a):Ue(t.value,t.valueType)}inlineLiteralFallback(t,e){const a=he[t.kind]?.inputs.find(t=>t.name===e);if(null==a)return;const r=ce(t.kind,a),u=pe(t.kind,a);return null!=r&&void 0!==u?Ue(u,r):void 0}resolveSocket(t,e,a){const r=this.compileNode(t.nodeId).outputs[t.port];if(null==r)throw new ShaderGraphCompileError(`Node "${t.nodeId}" does not have output "${t.port}"`,e??t.nodeId,a??t.port);return r}expectType(t,e,a,r){if(!e.includes(t.type))throw new ShaderGraphCompileError(`Expected ${e.join(" or ")} but got ${t.type}`,a,r);return t}expectNumeric(t){if(!Pe(t.type))throw new ShaderGraphCompileError(`Expected a numeric value but got ${t.type}`);return t}toSampler(t,e){if("sampler2d"===t.type)return t;if("texture2d"===t.type){const a=t.value;if(null==a)throw new ShaderGraphCompileError("Texture input is empty",e);return{type:"sampler2d",value:wt(a)}}throw new ShaderGraphCompileError(`Expected texture2d or sampler2d but got ${t.type}`,e)}toColorOutput(t){switch(t.type){case"float":case"vec2":case"vec3":case"vec4":case"rgb":case"rgba":return t.value;case"boolean":{const e=ht(t.value,D(1),D(0));return lt(Bt(e,e,e),1)}case"mat4":throw new ShaderGraphCompileError("mat4 values cannot be used as color");case"texture2d":case"sampler2d":throw new ShaderGraphCompileError(`${t.type} must be sampled before it can be used as color`)}}toVec3Output(t,e){if("vec3"===t.type||"rgb"===t.type)return t.value;if("vec4"===t.type||"rgba"===t.type)return t.value.xyz;throw new ShaderGraphCompileError(`Output "${e}" expects vec3/rgb but got ${t.type}`)}toMat4Output(t,e){if("mat4"===t.type)return t.value;throw new ShaderGraphCompileError(`Output "${e}" expects mat4 but got ${t.type}`)}output(t,e){return{node:t,outputs:e}}}export function compileShaderGraph(t,e={}){return new ShaderGraphCompiler(t,e).compile()}export function compileShaderGraphPreview(t,e,a={}){if(null==e)return compileShaderGraph(t,a).output;const r=new ShaderGraphCompiler(t,a).compileNode(e),u=Object.values(r.outputs)[0];if(null==u)throw new ShaderGraphCompileError(`Node "${e}" has no previewable output`,e);return{color:Oe(u),transparent:"rgba"===u.type||"vec4"===u.type}}export function buildShaderGraphMaterial(t,a={}){if("postProcess"===t.target)return buildShaderGraphPostProcessMaterial(t,a);const r=null!=a.previewNodeId?compileShaderGraphPreview(t,a.previewNodeId,a):compileShaderGraph(t,a).output;if("sprite"===t.target)return new Vt({color:r.color,discard:r.discard,transparent:r.transparent??!0,position:kt(new f("rotation",0),new f("screenSpaceSize",0)),uniforms:{color:{value:new e(16777215)}}});if("trail"===t.target){const{position:e}=re.getTrailShaderNodes(a.trailBillboard??!1),u=new h({...r,position:e});return re.applyTrailShaderParameters(u),Se(u,t),u}if("decal"===t.target){const e=null!=r.discard?ee.or(r.discard):ee,a=new h({...r,transparent:!1,discard:e});return a.userData.isDecal=!0,Se(a,t),a}const u=new h({transparent:!1,...r});return Se(u,t),u}export function buildShaderGraphPostProcessMaterial(t,e={}){const a=null!=e.previewNodeId?Te(compileShaderGraphPreview(t,e.previewNodeId,e).color):compileShaderGraph(t,e).output,r=new h({color:a.color,transparent:!1,fog:!1,lights:!1,outputEncoding:!1});return r.depthWrite=!1,r.depthTest=!1,r.toneMapped=!1,r.userData.isPostProcessShaderGraph=!0,r}function Te(t,e){const a=te(Qt),r=Nt("hology_post_process_weight",1),u=ct(null!=e?r.multiply(e):r);return{color:at(a,t,u),transparent:!1,...null!=e?{opacity:e}:{}}}export function shaderGraphMaterialSideToThree(e){switch(e){case"back":return t;case"double":return a;default:return r}}function Ie(t){return"decal"!==t.target&&(t.materialOptions?.transparent??"sprite"===t.target)}function Se(t,e){"surface"===e.target&&(t.side=shaderGraphMaterialSideToThree(e.materialOptions?.side)),null!=e.materialOptions?.transparent&&(t.transparent=e.materialOptions.transparent),null!=e.materialOptions?.alphaTest&&0===t.alphaTest&&(t.alphaTest=e.materialOptions.alphaTest),null!=e.materialOptions?.bloom&&(t.userData.hasBloom=e.materialOptions.bloom)}function Oe(t){switch(t.type){case"float":return Me(t.value);case"vec2":{const e=t.value;return lt(Bt(e.x,e.y,0),1)}case"vec3":case"rgb":return lt(t.value,1);case"vec4":case"rgba":return t.value;case"boolean":return Me(ht(t.value,D(1),D(0)));case"mat4":throw new ShaderGraphCompileError("mat4 values cannot be previewed as color");case"texture2d":case"sampler2d":throw new ShaderGraphCompileError(`${t.type} nodes require a sampled output to preview`)}}function Me(t){return lt(Bt(t,t,t),1)}function Ce(t){return t instanceof p?Bt(t,t,t).rgb:t instanceof g?Bt(t.x,t.y,0).rgb:t}function Ne(t){return t.rgb}function Ee(t,e,a){const r=t.params?.[e];return void 0===r?a:r}function Ge(t,e,a){const r=Ee(t,e,a);return"number"==typeof r?r:Number(r??a)}function Ue(t,e){if(null!=(a=t)&&"object"==typeof a&&!Array.isArray(a)&&"value"in a)return Ue(t.value,t.valueType??e);var a;const r=e??function(t){if("boolean"==typeof t)return"boolean";if("number"==typeof t)return"float";if(Array.isArray(t))return 2===t.length?"vec2":3===t.length?"vec3":16===t.length?"mat4":"vec4";return"string"==typeof t?"rgb":"float"}(t);return{type:r,value:Be(t,r,"literal")}}function Be(t,a,r){switch(a){case"boolean":return t instanceof l?t:E(Boolean(t));case"float":return t instanceof p?t:D(je(t,0));case"vec2":return t instanceof g?t:Le(t);case"vec3":return t instanceof b?t:qe(t);case"vec4":return t instanceof x?t:function(t){const[e,a,r,u]=De(t,4,1);return $t(e,a,r,u)}(t);case"mat4":return t instanceof c?t:function(t){if(t instanceof u)return Z(t);const e=new u;Array.isArray(t)&&16===t.length&&e.fromArray(t.map(t=>je(t,0)));return Z(e)}(t);case"rgb":return t instanceof v?t:function(t){if("string"==typeof t||"number"==typeof t||t instanceof e)return pt(t);const[a,r,u]=De(t,3);return Bt(a,r,u).rgb}(t);case"rgba":return t instanceof y||t instanceof x?t:Fe(t);case"texture2d":return t;case"sampler2d":if(function(t){const e=t;return t instanceof m||t instanceof d||"function"==typeof e?.isSampler2D||!0===e?.isSampler2D}(t))return t;if(t instanceof i)return wt(t);throw new ShaderGraphCompileError(`Parameter "${r}" needs a texture value`)}}function $e(t,e,a,r){const u=`${a}Scalar`;if(e instanceof p&&"function"==typeof t[u])return t[u](e);if("function"==typeof t[a])return t[a](e);throw new ShaderGraphCompileError(`Node does not support ${a}`,r)}function ze(t,e,a){if(t===e)return t;if("rgb"===t&&"vec3"===e||"vec3"===t&&"rgb"===e)return"vec3";if("rgba"===t&&"vec4"===e||"vec4"===t&&"rgba"===e)return"vec4";if("float"===t&&Pe(e))return e;if("float"===e&&Pe(t))return t;throw new ShaderGraphCompileError(`Cannot mix ${t} and ${e}`,a)}function Ve(t,e,a){const r=t.subtract(a),u=yt(e),i=$(e);return Ut(i.multiply(r.x).subtract(u.multiply(r.y)).add(a.x),u.multiply(r.x).add(i.multiply(r.y)).add(a.y))}function ke(t,e,a){const r=t.value["u"===e?"x":"v"===e?"y":e];if(r instanceof p)return r;throw new ShaderGraphCompileError(`Component "${e}" is not available on ${t.type}`,a)}function Pe(t){return"float"===t||"vec2"===t||"vec3"===t||"vec4"===t||"rgb"===t||"rgba"===t}function Ae(t){return Number.isFinite(t)?Math.min(1,Math.max(0,t)):0}function je(t,e){if("number"==typeof t)return t;if("string"==typeof t){const a=parseFloat(t);return Number.isFinite(a)?a:e}return"boolean"==typeof t?t?1:0:e}function De(t,a,r=0){if(Array.isArray(t))return Array.from({length:a},(e,a)=>je(t[a],r));if(t instanceof o||t instanceof n||t instanceof s)return Array.from({length:a},(e,a)=>t.toArray()[a]??r);if(t instanceof e){const e=t.toArray();return Array.from({length:a},(t,a)=>e[a]??(3===a?1:r))}if(null!=t&&"object"==typeof t){const e=t,u=["x","y","z","w"];if(u.some(t=>null!=e[t]))return Array.from({length:a},(t,a)=>je(e[u[a]],r));const i=["r","g","b","a"];if(i.some(t=>null!=e[t]))return Array.from({length:a},(t,a)=>je(e[i[a]],3===a?1:r))}return Array.from({length:a},()=>je(t,r))}function Le(t){const[e,a]=De(t,2);return Ut(e,a)}function qe(t){const[e,a,r]=De(t,3);return Bt(e,a,r)}function Fe(t,a=1){if("string"==typeof t||"number"==typeof t||t instanceof e)return lt(t,a);if(t instanceof b)return lt(t,a);const[r,u,i,o]=De(t,4,a);return $t(r,u,i,o)}function Re(t,e){return e<=1?0:t/(e-1)}/*
|
|
1
|
+
import{BackSide as t,Color as e,DoubleSide as a,FrontSide as r,Matrix4 as u,Texture as i,Vector2 as o,Vector3 as n,Vector4 as s}from"three";import{BooleanNode as l,FloatNode as p,Mat4Node as c,NodeShaderMaterial as h,RgbNode as v,RgbaNode as y,Sampler2DNode as m,Texture2dLookupNode as d,UniformFloatNode as f,Vec2Node as g,Vec3Node as b,Vec4Node as x,abs as w,acos as T,asin as I,attributes as S,atan as O,atan2 as M,autoVarying as C,bulge as N,bool as E,ceil as G,clamp as U,colorToNormal as B,cos as $,cross as z,degrees as V,distance as k,dot as P,exp as A,exp2 as j,float as D,floor as L,fract as q,inversesqrt as F,batchingMatrix as R,colorGradientSampler as _,curveSampler as W,ifDefApply as H,sampleNamedEasingCurve as Y,length as J,LayerMixMode as K,log as Q,log2 as X,mat4 as Z,max as tt,min as et,mix as at,mixColorsByLayer as rt,particleUniforms as ut,mod as it,normalize as ot,pow as nt,radians as st,rgba as lt,rgb as pt,saturate as ct,select as ht,sign as vt,sin as yt,smoothstep as mt,sqrt as dt,standardMaterial as ft,scaleTransform as gt,step as bt,tan as xt,textureSampler2d as wt,timeUniforms as Tt,toonMaterial as It,translate as St,transformed as Ot,triplanarMapping as Mt,twirl as Ct,uniformFloat as Nt,uniforms as Et,varyingAttributes as Gt,vec2 as Ut,vec3 as Bt,vec4 as $t,getPaintedMaterialLayerWeight as zt}from"../../shader-nodes/index.js";import{SpriteNodeShaderMaterial as Vt,getSpritePosition as kt}from"../sprite-shader.js";import{oneMinus as Pt}from"../../shader-nodes/index.js";import{vectorToRadial as At,remap as jt,hueShift as Dt,blendColor as Lt,desaturateColor as qt}from"../../shader-nodes/math.js";import{rectangleFloat as Ft,roundedRectangleFloat as Rt}from"../../shader-nodes/shapes.js";import{edgeDepthEffect as _t,fresnelEffect as Wt,depthFadeEffect as Ht}from"../../shader-nodes/effects.js";import{fragmentLinearEyeDepth as Yt,sampleSceneDepth as Jt,sampleSceneLinearEyeDepth as Kt,screenUV as Qt,nearUniformName as Xt,farUniformName as Zt}from"../../shader-nodes/depth.js";import{sampleSceneColor as te}from"../../shader-nodes/scene-sample.js";import{decalDiscard as ee,decalUV as ae}from"../../shader-nodes/decal.js";import{Trail as re,trailUV as ue}from"../../effects/vfx/trail-renderer.js";import{SimplexNoiseNode as ie,Voronoi2d as oe,rotateAxis as ne}from"../../shader-nodes/index.js";import{flipbookUv as se}from"../../shader-nodes/texture-sequence.js";import{parallaxOcclusionMapping as le}from"../../shader-nodes/pom.js";import{defaultInlineLiteralValueForPort as pe,inlineLiteralTypeForPort as ce,SHADER_GRAPH_NODE_DEFINITIONS as he}from"./registry.js";import{shaderGraphParameterTypeToValueType as ve}from"./parameters.js";import{varying as ye,reflect as me,refract as de,dFdx as fe,dFdy as ge,fwidth as be}from"three-shader-graph";import{decalNormal as xe}from"../../shader-nodes/decal.js";import{Curve2 as we}from"../../utils/curve.js";export class ShaderGraphCompileError extends Error{constructor(t,e,a){super(t),this.nodeId=e,this.port=a,this.name="ShaderGraphCompileError"}}export const shaderGraphPostProcessWeightUniformName="hology_post_process_weight";export class ShaderGraphCompiler{constructor(t,e={}){this.graph=t,this.options=e,this.compiled=new Map,this.nodesById=new Map((t.nodes??[]).map(t=>[t.id,t]))}validate(){this.compile()}compile(){if(1!==this.graph.version)throw new ShaderGraphCompileError(`Unsupported shader graph version ${this.graph.version}`);return this.validateEdges(),{output:this.compileOutput(),nodes:this.compiled}}validateEdges(){for(const t of this.graph.edges??[]){if(!this.nodesById.has(t.from.nodeId))throw new ShaderGraphCompileError(`Edge references missing source node "${t.from.nodeId}"`,t.from.nodeId,t.from.port);if(!this.nodesById.has(t.to.nodeId))throw new ShaderGraphCompileError(`Edge references missing target node "${t.to.nodeId}"`,t.to.nodeId,t.to.port)}}compileOutput(){if("postProcess"===this.graph.target)return this.compilePostProcessOutput();const t=this.graph.outputs?.color,e={color:null!=t?this.toColorOutput(this.resolveOutputBinding(t,"color")):lt("#ffffff",1),transparent:Se(this.graph)},a=this.graph.outputs?.opacity;null!=a&&(e.opacity=this.expectType(this.resolveOutputBinding(a,"opacity"),["float"],"opacity").value);const r=this.graph.outputs?.roughness;null!=r&&(e.roughness=this.expectType(this.resolveOutputBinding(r,"roughness"),["float"],"roughness").value);const u=this.graph.outputs?.metalness;null!=u&&(e.metalness=this.floatOutput(u,"metalness"));const i=this.graph.outputs?.normal;null!=i&&(e.normal=this.toVec3Output(this.resolveOutputBinding(i,"normal"),"normal"));const o=this.graph.outputs?.emissive;null!=o&&(e.emissive=this.toVec3Output(this.resolveOutputBinding(o,"emissive"),"emissive"));const n=this.graph.outputs?.ambientOcclusion;null!=n&&(e.ambientOcclusion=this.floatOutput(n,"ambientOcclusion"));const s=this.graph.outputs?.ambientOcclusionIntensity;null!=s&&(e.ambientOcclusionIntensity=this.floatOutput(s,"ambientOcclusionIntensity"));const l=this.graph.outputs?.sheenColor;null!=l&&(e.sheenColor=this.toVec3Output(this.resolveOutputBinding(l,"sheenColor"),"sheenColor"));const p=this.graph.outputs?.sheenRoughness;null!=p&&(e.sheenRoughness=this.floatOutput(p,"sheenRoughness"));const c=this.graph.outputs?.anisotropy;null!=c&&(e.anisotropy=this.floatOutput(c,"anisotropy"));const h=this.graph.outputs?.anisotropyDirection;null!=h&&(e.anisotropyDirection=this.expectType(this.resolveOutputBinding(h,"anisotropyDirection"),["vec2"],"anisotropyDirection").value);const v=this.graph.outputs?.bakedLight;null!=v&&(e.bakedLight=this.toVec3Output(this.resolveOutputBinding(v,"bakedLight"),"bakedLight"));const y=this.graph.outputs?.transform;null!=y&&"decal"!==this.graph.target&&(e.transform=this.toMat4Output(this.resolveOutputBinding(y,"transform"),"transform"));const m=this.graph.outputs?.discard;null!=m&&(e.discard=this.expectType(this.resolveOutputBinding(m,"discard"),["boolean"],"discard").value);const d=this.graph.outputs?.transparent;null!=d&&null!=d.value&&(e.transparent=Boolean(d.value));const f=this.graph.outputs?.alphaTest;return null!=f&&null!=f.value&&(e.alphaTest=Number(f.value)),this.applyShadingModel(e)}compilePostProcessOutput(){const t=this.graph.outputs?.color,e=null!=t?this.toColorOutput(this.resolveOutputBinding(t,"color")):te(Qt),a=this.graph.outputs?.opacity;return Te(e,null!=a?this.expectType(this.resolveOutputBinding(a,"opacity"),["float"],"opacity").value:void 0)}applyShadingModel(t){const e=null!=t.opacity?function(t,e){if(t instanceof p)return lt(Bt(t,t,t),e);if(t instanceof g)return lt(Bt(t.x,t.y,0),e);if(t instanceof x)return lt(t.rgb,t.w.multiply(e));return lt(t,e)}(t.color,t.opacity):t.color;switch(this.graph.shadingModel??"standard"){case"standard":{const a={color:Ne(e),roughness:t.roughness??D(.5),...null!=t.metalness?{metalness:t.metalness}:{},..."decal"===this.graph.target?{normal:ot(ye(Et.normalMatrix).multiplyVec(xe))}:{},...null!=t.normal?{normal:t.normal}:{},...null!=t.emissive?{emissive:Ee(t.emissive)}:{},...null!=t.ambientOcclusion?{ambientOcclusion:t.ambientOcclusion}:{},...null!=t.ambientOcclusionIntensity?{ambientOcclusionIntensity:t.ambientOcclusionIntensity}:{},...null!=t.sheenColor?{sheenColor:t.sheenColor.rgb}:{},...null!=t.sheenRoughness?{sheenRoughness:t.sheenRoughness}:{},...null!=t.anisotropy?{anisotropy:t.anisotropy}:{},...null!=t.anisotropyDirection?{anisotropyDirection:t.anisotropyDirection}:{},...null!=t.bakedLight?{bakedLight:t.bakedLight}:{}};return{...t,color:ft(a)}}case"toon":{const a={color:Ne(e),...null!=t.normal?{normal:t.normal}:{},...null!=t.emissive?{emissive:Ee(t.emissive)}:{},...null!=t.ambientOcclusion?{ambientOcclusion:t.ambientOcclusion}:{},...null!=t.ambientOcclusionIntensity?{ambientOcclusionIntensity:t.ambientOcclusionIntensity}:{},...null!=t.bakedLight?{bakedLight:t.bakedLight}:{}};return{...t,color:It(a)}}case"unlit":return{...t,color:e}}}compileNode(t){const e=this.compiled.get(t);if(null!=e)return e;const a=this.nodesById.get(t);if(null==a)throw new ShaderGraphCompileError(`Missing shader graph node "${t}"`,t);if(null==he[a.kind])throw new ShaderGraphCompileError(`Unsupported shader graph node "${a.kind}"`,a.id);const r=this.compileNodeInternal(a);return this.compiled.set(t,r),r}compileNodeInternal(t){switch(t.kind){case"input.parameter":return this.output(t,this.compileParameterNode(t));case"input.slider":return this.output(t,{value:{type:"float",value:D(je(Ue(t,"value",.5)))}});case"constant.boolean":return this.output(t,{value:{type:"boolean",value:E(Boolean(Ge(t,"value",!1)))}});case"constant.float":return this.output(t,{value:{type:"float",value:D(Ue(t,"value",0))}});case"constant.vec2":return this.output(t,{value:{type:"vec2",value:qe(Ge(t,"value",[0,0]))}});case"constant.vec3":return this.output(t,{value:{type:"vec3",value:Fe(Ge(t,"value",[0,0,0]))}});case"constant.rgba":return this.output(t,{value:{type:"rgba",value:Re(Ge(t,"value","#ffffff"),Ue(t,"alpha",1))}});case"builtin.uv":{const e=this.defaultUV();return this.output(t,{value:{type:"vec2",value:!0===Ge(t,"flipY",!1)?Ut(e.x,Pt(e.y)):e},u:{type:"float",value:e.x},v:{type:"float",value:e.y}})}case"builtin.screenUv":return this.output(t,{value:{type:"vec2",value:Qt}});case"builtin.color":{const e=C(S.color);return this.output(t,{value:{type:"rgba",value:e},rgb:{type:"rgb",value:e.rgb},r:{type:"float",value:e.r},g:{type:"float",value:e.g},b:{type:"float",value:e.b},a:{type:"float",value:e.a}})}case"builtin.position":{const e=C(S.position);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.worldPosition":{const e=C(Ot.worldPosition);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.objectPosition":{let e=Et.instanceMatrix.multiplyVec($t(0,0,0,1));e=H("USE_BATCHING",e,t=>R.multiplyVec(t));const a=C(Et.modelMatrix.multiplyVec(e).xyz);return this.output(t,{value:{type:"vec3",value:a},x:{type:"float",value:a.x},y:{type:"float",value:a.y},z:{type:"float",value:a.z}})}case"builtin.viewDir":{const e=C(Ot.viewDir);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.normal":{const e=C(S.normal);return this.output(t,{value:{type:"vec3",value:e},x:{type:"float",value:e.x},y:{type:"float",value:e.y},z:{type:"float",value:e.z}})}case"builtin.time":return this.output(t,{value:{type:"float",value:Tt.elapsed}});case"builtin.camera":{const e=Nt(Xt),a=Nt(Zt),r=Et.cameraPosition;return this.output(t,{position:{type:"vec3",value:r},x:{type:"float",value:r.x},y:{type:"float",value:r.y},z:{type:"float",value:r.z},near:{type:"float",value:e},far:{type:"float",value:a}})}case"builtin.viewMatrix":return this.output(t,{value:{type:"mat4",value:Et.viewMatrix}});case"builtin.projectionMatrix":return this.output(t,{value:{type:"mat4",value:Et.projectionMatrix}});case"builtin.modelViewMatrix":return this.output(t,{value:{type:"mat4",value:Et.modelViewMatrix}});case"builtin.particle":return this.output(t,{energy:{type:"float",value:ut.energy},color:{type:"rgb",value:ut.color},opacity:{type:"float",value:ut.opacity},time:{type:"float",value:ut.time}});case"math.add":case"math.subtract":case"math.multiply":case"math.divide":return this.output(t,{value:this.compileBinaryMath(t)});case"math.oneMinus":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:e.type,value:Pt(e.value)}})}case"math.abs":return this.output(t,{value:this.compileUnaryMath(t,w)});case"math.sign":return this.output(t,{value:this.compileUnaryMath(t,vt)});case"math.floor":return this.output(t,{value:this.compileUnaryMath(t,L)});case"math.ceil":return this.output(t,{value:this.compileUnaryMath(t,G)});case"math.fract":return this.output(t,{value:this.compileUnaryMath(t,q)});case"math.sin":return this.output(t,{value:this.compileUnaryMath(t,yt)});case"math.cos":return this.output(t,{value:this.compileUnaryMath(t,$)});case"math.tan":return this.output(t,{value:this.compileUnaryMath(t,xt)});case"math.asin":return this.output(t,{value:this.compileUnaryMath(t,I)});case"math.acos":return this.output(t,{value:this.compileUnaryMath(t,T)});case"math.atan":return this.output(t,{value:this.compileUnaryMath(t,O)});case"math.atan2":return this.output(t,{value:this.compileAtan2(t)});case"math.radians":return this.output(t,{value:this.compileUnaryMath(t,st)});case"math.degrees":return this.output(t,{value:this.compileUnaryMath(t,V)});case"math.sqrt":return this.output(t,{value:this.compileUnaryMath(t,dt)});case"math.inverseSqrt":return this.output(t,{value:this.compileUnaryMath(t,F)});case"math.exp":return this.output(t,{value:this.compileUnaryMath(t,A)});case"math.exp2":return this.output(t,{value:this.compileUnaryMath(t,j)});case"math.log":return this.output(t,{value:this.compileUnaryMath(t,Q)});case"math.log2":return this.output(t,{value:this.compileUnaryMath(t,X)});case"math.saturate":return this.output(t,{value:this.compileUnaryMath(t,ct)});case"math.length":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:"float",value:J(e.value)}})}case"math.normalize":return this.output(t,{value:this.compileUnaryMath(t,ot)});case"math.clamp":{const e=this.expectNumeric(this.input(t,"value")),a=this.expectNumeric(this.input(t,"min",{type:"float",value:D(0)})),r=this.expectNumeric(this.input(t,"max",{type:"float",value:D(1)}));return this.output(t,{value:{type:e.type,value:U(e.value,a.value,r.value)}})}case"math.min":return this.output(t,{value:this.compileBinaryFunction(t,et)});case"math.max":return this.output(t,{value:this.compileBinaryFunction(t,tt)});case"math.pow":return this.output(t,{value:this.compileBinaryFunction(t,nt)});case"math.mod":return this.output(t,{value:this.compileBinaryFunction(t,it)});case"math.step":return this.output(t,{value:this.compileBinaryFunction(t,bt,!0)});case"math.smoothstep":{const e=this.expectNumeric(this.input(t,"edge0",{type:"float",value:D(0)})),a=this.expectNumeric(this.input(t,"edge1",{type:"float",value:D(1)})),r=this.expectNumeric(this.input(t,"value"));return this.output(t,{value:{type:r.type,value:mt(e.value,a.value,r.value)}})}case"math.mix":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b")),r=this.expectNumeric(this.input(t,"t",{type:"float",value:D(.5)})),u=Ve(e.type,a.type,t.id);return this.output(t,{value:{type:u,value:at(e.value,a.value,r.value)}})}case"math.remap":{const e=this.expectType(this.input(t,"value"),["float"],t.id,"value").value,a=this.floatInput(t,"inMin",-1),r=this.floatInput(t,"inMax",1),u=this.floatInput(t,"outMin",0),i=this.floatInput(t,"outMax",1);return this.output(t,{value:{type:"float",value:jt(e,a,r,u,i)}})}case"math.select":{const e=this.boolInput(t,"condition",!1),a=this.expectNumeric(this.input(t,"a")),r=this.expectNumeric(this.input(t,"b")),u=Ve(a.type,r.type,t.id);return this.output(t,{value:{type:u,value:ht(e,a.value,r.value)}})}case"math.reflect":{const e=this.expectType(this.input(t,"incident"),["vec2","vec3","vec4","rgb","rgba"],t.id,"incident"),a=this.expectType(this.input(t,"normal"),["vec2","vec3","vec4","rgb","rgba"],t.id,"normal");return this.output(t,{value:{type:e.type,value:me(e.value,a.value)}})}case"math.refract":{const e=this.expectType(this.input(t,"incident"),["vec2","vec3","vec4","rgb","rgba"],t.id,"incident"),a=this.expectType(this.input(t,"normal"),["vec2","vec3","vec4","rgb","rgba"],t.id,"normal"),r=this.floatInput(t,"ior",1.5);return this.output(t,{value:{type:e.type,value:de(e.value,a.value,r)}})}case"math.derivative":{const e=this.expectNumeric(this.input(t,"value")),a=String(Ge(t,"mode","fwidth"));let r;return r="dFdx"===a?fe(e.value):"dFdy"===a?ge(e.value):be(e.value),this.output(t,{value:{type:e.type,value:r}})}case"layer.mixPainted":return this.output(t,{value:this.compilePaintedLayerMix(t)});case"math.dot":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b"));return Ve(e.type,a.type,t.id),this.output(t,{value:{type:"float",value:P(e.value,a.value)}})}case"math.distance":{const e=this.expectNumeric(this.input(t,"a")),a=this.expectNumeric(this.input(t,"b"));return Ve(e.type,a.type,t.id),this.output(t,{value:{type:"float",value:k(e.value,a.value)}})}case"math.cross":{const e=this.expectType(this.input(t,"a"),["vec3","rgb"],t.id,"a"),a=this.expectType(this.input(t,"b"),["vec3","rgb"],t.id,"b");return this.output(t,{value:{type:"vec3",value:z(e.value,a.value)}})}case"compare.greaterThan":case"compare.greaterThanOrEqual":case"compare.lessThan":case"compare.lessThanOrEqual":case"compare.equal":case"compare.notEqual":return this.output(t,{value:{type:"boolean",value:this.compileComparison(t)}});case"boolean.not":{const e=this.boolInput(t,"value",!1);return this.output(t,{value:{type:"boolean",value:ht(e,E(!1),E(!0))}})}case"boolean.and":return this.output(t,{value:{type:"boolean",value:this.compileBooleanBinary(t,"and")}});case"boolean.or":return this.output(t,{value:{type:"boolean",value:this.compileBooleanBinary(t,"or")}});case"compose.vec2":return this.output(t,{value:{type:"vec2",value:Ut(this.floatInput(t,"x",0),this.floatInput(t,"y",0))}});case"compose.vec3":return this.output(t,{value:{type:"vec3",value:Bt(this.floatInput(t,"x",0),this.floatInput(t,"y",0),this.floatInput(t,"z",0))}});case"compose.vec4":return this.output(t,{value:{type:"vec4",value:$t(this.floatInput(t,"x",0),this.floatInput(t,"y",0),this.floatInput(t,"z",0),this.floatInput(t,"w",0))}});case"compose.rgba":return this.output(t,{value:{type:"rgba",value:$t(this.floatInput(t,"r",1),this.floatInput(t,"g",1),this.floatInput(t,"b",1),this.floatInput(t,"a",1))}});case"decompose.component":{const e=this.expectNumeric(this.input(t,"value")),a=String(Ge(t,"component","x"));return this.output(t,{value:{type:"float",value:Pe(e,a,t.id)}})}case"decompose.split":{const e=this.expectNumeric(this.input(t,"value"));return this.output(t,function(t,e){const a={},r=(r,u)=>{a[r]={type:"float",value:Pe(t,u,e)}};switch(t.type){case"vec2":return r("x","x"),r("y","y"),r("u","x"),r("v","y"),a;case"vec3":return r("x","x"),r("y","y"),r("z","z"),a;case"rgb":return r("r","r"),r("g","g"),r("b","b"),r("x","x"),r("y","y"),r("z","z"),a;case"vec4":return r("x","x"),r("y","y"),r("z","z"),r("w","w"),a;case"rgba":return r("r","r"),r("g","g"),r("b","b"),r("a","a"),r("x","x"),r("y","y"),r("z","z"),r("w","w"),a;case"float":return a.x={type:"float",value:t.value},a}}(e,t.id))}case"color.gradient":{const e=this.expectType(this.input(t,"t",{type:"float",value:D(.5)}),["float"],t.id,"t"),a=_(function(t){const e=Ge(t,"stops",[]);if(!Array.isArray(e))return[];const a=e.map((t,a)=>{if(null==t||"object"!=typeof t||Array.isArray(t))return;const r=t,u="string"==typeof r.color?r.color:"#ffffff";return{position:De(r.position,_e(a,e.length)),color:u,alpha:De(r.alpha,1)}}).filter(t=>null!=t);return a.length>0?a:[]}(t)).sample(e.value);return this.output(t,{value:{type:"rgba",value:a}})}case"utility.curve":{const e=this.expectType(this.input(t,"t",{type:"float",value:D(.5)}),["float"],t.id,"t"),a=Ge(t,"curve","Linear"),r=Y(a,e.value)??W(we.decode(a)).sample(e.value);return this.output(t,{value:{type:"float",value:r}})}case"color.hueShift":{const e=this.expectType(this.input(t,"color"),["rgba","rgb","vec4","vec3"],t.id,"color"),a=e.value,r="rgba"===e.type||"vec4"===e.type?a.rgb??a.xyz:a,u=this.floatInput(t,"shift",0),i=Dt(r,u);return"rgba"===e.type||"vec4"===e.type?this.output(t,{value:{type:e.type,value:$t(i,a.a??a.w)}}):this.output(t,{value:{type:e.type,value:i}})}case"color.blend":{const e=this.expectType(this.input(t,"base"),["rgba","rgb","vec4","vec3"],t.id,"base"),a=this.expectType(this.input(t,"blend"),["rgba","rgb","vec4","vec3"],t.id,"blend"),r=String(Ge(t,"mode","multiply")),u=e.value,i=a.value,o="rgba"===e.type||"vec4"===e.type?u.rgb??u.xyz:u,n="rgba"===a.type||"vec4"===a.type?i.rgb??i.xyz:i;let s=Lt(o,n,r);if("rgba"===a.type||"vec4"===a.type){const t=i.a??i.w;s=at(o,s,t)}if("rgba"===e.type||"vec4"===e.type){const a=u.a??u.w;return this.output(t,{value:{type:e.type,value:$t(s,a)}})}return this.output(t,{value:{type:e.type,value:s}})}case"color.desaturate":{const e=this.expectType(this.input(t,"color"),["rgba","rgb","vec4","vec3"],t.id,"color"),a=e.value,r="rgba"===e.type||"vec4"===e.type?a.rgb??a.xyz:a,u=this.floatInput(t,"fraction",1),i=qt(r,u);return"rgba"===e.type||"vec4"===e.type?this.output(t,{value:{type:e.type,value:$t(i,a.a??a.w)}}):this.output(t,{value:{type:e.type,value:i}})}case"color.unpackNormal":{const e=this.expectType(this.input(t,"color"),["vec3","vec4","rgb","rgba"],t.id,"color"),a=this.floatInput(t,"scale",1),r=this.optionalInput(t,"normal");return this.output(t,{value:{type:"vec3",value:B(e.value,a,r?this.expectType(r,["vec3"],t.id,"normal").value:void 0)}})}case"texture.sampler2d":{const e=this.input(t,"texture");return this.output(t,{value:this.toSampler(e,t.id)})}case"texture.sample2d":{const e=this.toSampler(this.input(t,"sampler"),t.id),a=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv"),r=e.value.sample(a.value);return this.output(t,{rgba:{type:"rgba",value:r},rgb:{type:"rgb",value:r.rgb},r:{type:"float",value:r.r},g:{type:"float",value:r.g},b:{type:"float",value:r.b},a:{type:"float",value:r.a}})}case"texture.triplanarMapping":{const e=this.input(t,"sampler"),a=this.toSampler(e,t.id),r=this.expectType(this.input(t,"scale",{type:"float",value:D(1)}),["float"],t.id,"scale"),u=this.expectType(this.input(t,"normal",{type:"vec3",value:Gt.normal}),["vec3"],t.id,"normal"),i=this.expectType(this.input(t,"position",{type:"vec3",value:Gt.position}),["vec3"],t.id,"position"),o=Mt(a.value,r.value,u.value,i.value);return this.output(t,{rgba:{type:"rgba",value:o},rgb:{type:"rgb",value:o.rgb},r:{type:"float",value:o.r},g:{type:"float",value:o.g},b:{type:"float",value:o.b},a:{type:"float",value:o.a}})}case"scene.sampleColor":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:Qt}),["vec2"],t.id,"uv"),a=te(e.value);return this.output(t,{rgba:{type:"rgba",value:a},rgb:{type:"rgb",value:a.rgb},r:{type:"float",value:a.r},g:{type:"float",value:a.g},b:{type:"float",value:a.b},a:{type:"float",value:a.a}})}case"scene.sampleDepth":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:Qt}),["vec2"],t.id,"uv");return this.output(t,{depth:{type:"float",value:Jt(e.value)},linearEyeDepth:{type:"float",value:Kt(e.value)}})}case"scene.fragmentDepth":return this.output(t,{linearEyeDepth:{type:"float",value:Yt}});case"transform.translate":{const e=this.expectType(this.input(t,"offset",{type:"vec3",value:Bt(0,0,0)}),["vec3","rgb"],t.id,"offset");return this.output(t,{value:{type:"mat4",value:St(e.value)}})}case"transform.scale":{const e=this.expectType(this.input(t,"scale",{type:"vec3",value:Bt(1,1,1)}),["vec3","rgb"],t.id,"scale").value;return this.output(t,{value:{type:"mat4",value:gt(e.x,e.y,e.z)}})}case"transform.rotateAxis":{const e=this.expectType(this.input(t,"axis",{type:"vec3",value:Bt(0,1,0)}),["vec3","rgb"],t.id,"axis"),a=this.expectType(this.input(t,"angle",{type:"float",value:D(0)}),["float"],t.id,"angle");return this.output(t,{value:{type:"mat4",value:ne(e.value,a.value)}})}case"uv.rotate":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"angle",{type:"float",value:D(0)}),["float"],t.id,"angle").value,r=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value;return this.output(t,{value:{type:"vec2",value:ke(e,a,r)}})}case"uv.twirl":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"strength",{type:"float",value:D(1)}),["float"],t.id,"strength").value,r=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value,u=this.expectType(this.input(t,"offset",{type:"vec2",value:Ut(0,0)}),["vec2"],t.id,"offset").value;return this.output(t,{value:{type:"vec2",value:Ct(e,a,r,u)}})}case"uv.radial":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=At(e.subtractScalar(.5));return this.output(t,{coords:{type:"vec2",value:a.coords},radius:{type:"float",value:a.radius},angle:{type:"float",value:a.angle}})}case"uv.bulge":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.expectType(this.input(t,"center",{type:"vec2",value:Ut(.5,.5)}),["vec2"],t.id,"center").value,r=this.expectType(this.input(t,"power",{type:"float",value:D(1)}),["float"],t.id,"power").value;return this.output(t,{value:{type:"vec2",value:N(e,a,r)}})}case"uv.flipbook":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"columns",Ue(t,"columns",1)),r=this.floatInput(t,"rows",Ue(t,"rows",1)),u=this.floatInput(t,"fps",Ue(t,"fps",60)),i=this.expectType(this.input(t,"time",{type:"float",value:Tt.elapsed}),["float"],t.id,"time").value,o=String(Ge(t,"mode","clamp"));return this.output(t,{value:{type:"vec2",value:se(e,a,r,i,u,o)}})}case"uv.pom":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.input(t,"heightMap"),r=this.toSampler(a,t.id).value,u=this.floatInput(t,"heightScale",.05),i=Ue(t,"minLayers",8),o=Ue(t,"maxLayers",24);return this.output(t,{value:{type:"vec2",value:le(e,r,u,i,o)}})}case"shape.rectangle":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value;return this.output(t,{value:{type:"float",value:Ft(e,this.floatInput(t,"width",.5),this.floatInput(t,"height",.5))}})}case"shape.roundedRectangle":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value;return this.output(t,{value:{type:"float",value:Rt(e,this.floatInput(t,"width",.5),this.floatInput(t,"height",.5),this.floatInput(t,"radius",.1))}})}case"noise.simplex":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"scale",8);return this.output(t,{value:{type:"float",value:new ie(e.multiplyScalar(a))}})}case"noise.voronoi2d":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv").value,a=this.floatInput(t,"scale",8);return this.output(t,{value:{type:"float",value:new oe(e.multiplyScalar(a))}})}case"effect.fresnel":return this.output(t,{value:{type:"float",value:C(Wt(this.floatInput(t,"power",1)))}});case"effect.edgeDepth":{const e=this.floatInput(t,"power",1);return this.output(t,{value:{type:"float",value:_t(e)}})}case"effect.depthFade":{const e=this.floatInput(t,"distance",1);return this.output(t,{value:{type:"float",value:Ht(e)}})}case"util.panner":{const e=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"coord"),a=this.expectType(this.input(t,"speed",{type:"vec2",value:Ut(0,0)}),["vec2"],t.id,"speed"),r=this.expectType(this.input(t,"tile",{type:"vec2",value:Ut(1,1)}),["vec2"],t.id,"tile"),u=this.expectType(this.input(t,"time",{type:"float",value:Tt.elapsed}),["float"],t.id,"time");return this.output(t,{value:{type:"vec2",value:e.value.multiply(r.value).add(a.value.multiplyScalar(u.value))}})}}}compileParameterNode(t){const e=String(Ge(t,"parameter","")),a=this.graph.parameters?.find(t=>t.name===e||t.id===e);if(null==a)throw new ShaderGraphCompileError(`Parameter "${e}" does not exist`,t.id);const r=ve(a.type),u={type:r,value:$e(this.options.parameters?.[a.name]??a.defaultValue,r,a.name)};if("sampler2d"!==r)return{value:u};const i=this.expectType(this.input(t,"uv",{type:"vec2",value:this.defaultUV()}),["vec2"],t.id,"uv"),o=u.value.sample(i.value);return{value:{type:"rgba",value:o},rgb:{type:"rgb",value:o.rgb},r:{type:"float",value:o.r},g:{type:"float",value:o.g},b:{type:"float",value:o.b},a:{type:"float",value:o.a},sampler:u}}compileBinaryMath(t){const e=this.expectBinaryMathValue(this.input(t,"a")),a=this.expectBinaryMathValue(this.input(t,"b")),r=t.kind.split(".")[1];if("mat4"===e.type||"mat4"===a.type)return function(t,e,a,r){if("mat4"===t.type&&"mat4"===e.type&&"divide"!==a)return{type:"mat4",value:ze(t.value,e.value,a,r)};if("mat4"===t.type&&"float"===e.type&&("multiply"===a||"divide"===a))return{type:"mat4",value:ze(t.value,e.value,a,r)};if("float"===t.type&&"mat4"===e.type&&"multiply"===a)return{type:"mat4",value:ze(e.value,t.value,a,r)};if("mat4"===t.type&&"vec4"===e.type&&"multiply"===a)return{type:"vec4",value:t.value.multiplyVec(e.value)};throw new ShaderGraphCompileError(`Cannot ${a} ${t.type} and ${e.type}`,r)}(e,a,r,t.id);if(e.type===a.type)return{type:e.type,value:ze(e.value,a.value,r,t.id)};if("float"===e.type&&"float"!==a.type&&"multiply"===r)return{type:a.type,value:ze(a.value,e.value,r,t.id)};if("float"!==e.type&&"float"===a.type)return{type:e.type,value:ze(e.value,a.value,r,t.id)};throw new ShaderGraphCompileError(`Cannot ${r} ${e.type} and ${a.type}`,t.id)}expectBinaryMathValue(t){if(!Ae(t.type)&&"mat4"!==t.type)throw new ShaderGraphCompileError(`Expected a numeric value but got ${t.type}`);return t}compileUnaryMath(t,e){const a=this.expectNumeric(this.input(t,"value"));return{type:a.type,value:e(a.value)}}compileAtan2(t){const e=this.expectNumeric(this.input(t,"y")),a=this.expectNumeric(this.input(t,"x"));return{type:function(t,e,a){if(t===e)return t;if("rgb"===t&&"vec3"===e||"vec3"===t&&"rgb"===e)return"vec3";if("rgba"===t&&"vec4"===e||"vec4"===t&&"rgba"===e)return"vec4";throw new ShaderGraphCompileError(`Cannot mix ${t} and ${e}`,a)}(e.type,a.type,t.id),value:M(e.value,a.value)}}compileBinaryFunction(t,e,a=!1){const r=this.expectNumeric(this.input(t,"a")),u=this.expectNumeric(this.input(t,"b"));return{type:a&&"float"===u.type?r.type:Ve(r.type,u.type,t.id),value:e(r.value,u.value)}}compilePaintedLayerMix(t){const e=this.expectNumeric(this.input(t,"base")),a=[e.value],r=[zt(0)];let u=e.type;for(let e=1;e<=8;e++){const i=this.optionalInput(t,`layer${e}`);if(null==i)continue;const o=this.expectNumeric(i);u=Ve(u,o.type,t.id),a.push(o.value),r.push(zt(e))}return 1===a.length?e:{type:u,value:rt({layerColors:a,layerWeights:r,enableNoise:Boolean(Ge(t,"enableNoise",!0)),noiseScale:this.floatInput(t,"noiseScale",Ue(t,"noiseScale",.1)),noiseAmount:this.floatInput(t,"noiseAmount",Ue(t,"noiseAmount",.5)),decay:this.floatInput(t,"softness",Ue(t,"softness",.3)),mode:"hard"===String(Ge(t,"mode","soft"))?K.hard:K.soft})}}defaultUV(){return"trail"===this.graph.target?ue:"decal"===this.graph.target?ae:C(S.uv)}input(t,e,a){const r=t.inputs?.[e];if(null!=r)return this.resolveInput(r,t.id,e);const u=(this.graph.edges??[]).find(a=>a.to.nodeId===t.id&&a.to.port===e);if(null!=u)return this.resolveSocket(u.from,t.id,e);if(null!=a)return a;const i=this.inlineLiteralFallback(t,e);if(null!=i)return i;throw new ShaderGraphCompileError(`Missing input "${e}"`,t.id,e)}optionalInput(t,e){const a=t.inputs?.[e];if(null!=a)return this.resolveInput(a,t.id,e);const r=(this.graph.edges??[]).find(a=>a.to.nodeId===t.id&&a.to.port===e);return null!=r?this.resolveSocket(r.from,t.id,e):void 0}floatInput(t,e,a){return this.expectType(this.input(t,e,{type:"float",value:D(a)}),["float"],t.id,e).value}boolInput(t,e,a){return this.expectType(this.input(t,e,{type:"boolean",value:E(a)}),["boolean"],t.id,e).value}compileComparison(t){const e=this.expectType(this.input(t,"a"),["float"],t.id,"a").value,a=this.expectType(this.input(t,"b"),["float"],t.id,"b").value;switch(t.kind){case"compare.greaterThan":return e.gt(a);case"compare.greaterThanOrEqual":return e.gte(a);case"compare.lessThan":return e.lt(a);case"compare.lessThanOrEqual":return e.lte(a);case"compare.equal":return e.equals(a);case"compare.notEqual":return e.notEquals(a)}throw new ShaderGraphCompileError(`Unsupported comparison node "${t.kind}"`,t.id)}compileBooleanBinary(t,e){const a=this.boolInput(t,"a",!1),r=this.boolInput(t,"b",!1);return"and"===e?a.and(r):a.or(r)}resolveOutputBinding(t,e){if(null!=t.input)return this.resolveSocket(t.input,void 0,e);if(void 0!==t.value)return Be(t.value);throw new ShaderGraphCompileError(`Output "${e}" is missing an input or value`)}floatOutput(t,e){return this.expectType(this.resolveOutputBinding(t,e),["float"],e).value}resolveInput(t,e,a){return function(t){return null!=t.nodeId}(t)?this.resolveSocket(t,e,a):Be(t.value,t.valueType)}inlineLiteralFallback(t,e){const a=he[t.kind]?.inputs.find(t=>t.name===e);if(null==a)return;const r=ce(t.kind,a),u=pe(t.kind,a);return null!=r&&void 0!==u?Be(u,r):void 0}resolveSocket(t,e,a){const r=this.compileNode(t.nodeId).outputs[t.port];if(null==r)throw new ShaderGraphCompileError(`Node "${t.nodeId}" does not have output "${t.port}"`,e??t.nodeId,a??t.port);return r}expectType(t,e,a,r){if(!e.includes(t.type))throw new ShaderGraphCompileError(`Expected ${e.join(" or ")} but got ${t.type}`,a,r);return t}expectNumeric(t){if(!Ae(t.type))throw new ShaderGraphCompileError(`Expected a numeric value but got ${t.type}`);return t}toSampler(t,e){if("sampler2d"===t.type)return t;if("texture2d"===t.type){const a=t.value;if(null==a)throw new ShaderGraphCompileError("Texture input is empty",e);return{type:"sampler2d",value:wt(a)}}throw new ShaderGraphCompileError(`Expected texture2d or sampler2d but got ${t.type}`,e)}toColorOutput(t){switch(t.type){case"float":case"vec2":case"vec3":case"vec4":case"rgb":case"rgba":return t.value;case"boolean":{const e=ht(t.value,D(1),D(0));return lt(Bt(e,e,e),1)}case"mat4":throw new ShaderGraphCompileError("mat4 values cannot be used as color");case"texture2d":case"sampler2d":throw new ShaderGraphCompileError(`${t.type} must be sampled before it can be used as color`)}}toVec3Output(t,e){if("vec3"===t.type||"rgb"===t.type)return t.value;if("vec4"===t.type||"rgba"===t.type)return t.value.xyz;throw new ShaderGraphCompileError(`Output "${e}" expects vec3/rgb but got ${t.type}`)}toMat4Output(t,e){if("mat4"===t.type)return t.value;throw new ShaderGraphCompileError(`Output "${e}" expects mat4 but got ${t.type}`)}output(t,e){return{node:t,outputs:e}}}export function compileShaderGraph(t,e={}){return new ShaderGraphCompiler(t,e).compile()}export function compileShaderGraphPreview(t,e,a={}){if(null==e)return compileShaderGraph(t,a).output;const r=new ShaderGraphCompiler(t,a).compileNode(e),u=Object.values(r.outputs)[0];if(null==u)throw new ShaderGraphCompileError(`Node "${e}" has no previewable output`,e);return{color:Me(u),transparent:"rgba"===u.type||"vec4"===u.type}}export function buildShaderGraphMaterial(t,a={}){if("postProcess"===t.target)return buildShaderGraphPostProcessMaterial(t,a);const r=null!=a.previewNodeId?compileShaderGraphPreview(t,a.previewNodeId,a):compileShaderGraph(t,a).output;if("sprite"===t.target)return new Vt({color:r.color,discard:r.discard,transparent:r.transparent??!0,position:kt(new f("rotation",0),new f("screenSpaceSize",0)),uniforms:{color:{value:new e(16777215)}}});if("trail"===t.target){const{position:e}=re.getTrailShaderNodes(a.trailBillboard??!1),u=new h({...r,position:e});return re.applyTrailShaderParameters(u),Oe(u,t),u}if("decal"===t.target){const e=null!=r.discard?ee.or(r.discard):ee,a=new h({...r,transparent:!1,discard:e});return a.userData.isDecal=!0,Oe(a,t),a}const u=new h({transparent:!1,...r});return Oe(u,t),u}export function buildShaderGraphPostProcessMaterial(t,e={}){const a=null!=e.previewNodeId?Te(compileShaderGraphPreview(t,e.previewNodeId,e).color):compileShaderGraph(t,e).output,r=new h({color:a.color,transparent:!1,fog:!1,lights:!1,outputEncoding:!1});return r.depthWrite=!1,r.depthTest=!1,r.toneMapped=!1,r.userData.isPostProcessShaderGraph=!0,r}function Te(t,e){const a=te(Qt),r=Nt("hology_post_process_weight",1),u=ct(null!=e?r.multiply(e):r);return{color:at(a.rgb,Ie(t),u),transparent:!1,...null!=e?{opacity:e}:{}}}function Ie(t){return t instanceof p?Bt(t,t,t):t instanceof g?Bt(t.x,t.y,0):t instanceof x?t.xyz:t}export function shaderGraphMaterialSideToThree(e){switch(e){case"back":return t;case"double":return a;default:return r}}function Se(t){return"decal"!==t.target&&(t.materialOptions?.transparent??"sprite"===t.target)}function Oe(t,e){"surface"===e.target&&(t.side=shaderGraphMaterialSideToThree(e.materialOptions?.side)),null!=e.materialOptions?.transparent&&(t.transparent=e.materialOptions.transparent),null!=e.materialOptions?.alphaTest&&0===t.alphaTest&&(t.alphaTest=e.materialOptions.alphaTest),null!=e.materialOptions?.bloom&&(t.userData.hasBloom=e.materialOptions.bloom)}function Me(t){switch(t.type){case"float":return Ce(t.value);case"vec2":{const e=t.value;return lt(Bt(e.x,e.y,0),1)}case"vec3":case"rgb":return lt(t.value,1);case"vec4":case"rgba":return t.value;case"boolean":return Ce(ht(t.value,D(1),D(0)));case"mat4":throw new ShaderGraphCompileError("mat4 values cannot be previewed as color");case"texture2d":case"sampler2d":throw new ShaderGraphCompileError(`${t.type} nodes require a sampled output to preview`)}}function Ce(t){return lt(Bt(t,t,t),1)}function Ne(t){return t instanceof p?Bt(t,t,t).rgb:t instanceof g?Bt(t.x,t.y,0).rgb:t}function Ee(t){return t.rgb}function Ge(t,e,a){const r=t.params?.[e];return void 0===r?a:r}function Ue(t,e,a){const r=Ge(t,e,a);return"number"==typeof r?r:Number(r??a)}function Be(t,e){if(null!=(a=t)&&"object"==typeof a&&!Array.isArray(a)&&"value"in a)return Be(t.value,t.valueType??e);var a;const r=e??function(t){if("boolean"==typeof t)return"boolean";if("number"==typeof t)return"float";if(Array.isArray(t))return 2===t.length?"vec2":3===t.length?"vec3":16===t.length?"mat4":"vec4";return"string"==typeof t?"rgb":"float"}(t);return{type:r,value:$e(t,r,"literal")}}function $e(t,a,r){switch(a){case"boolean":return t instanceof l?t:E(Boolean(t));case"float":return t instanceof p?t:D(De(t,0));case"vec2":return t instanceof g?t:qe(t);case"vec3":return t instanceof b?t:Fe(t);case"vec4":return t instanceof x?t:function(t){const[e,a,r,u]=Le(t,4,1);return $t(e,a,r,u)}(t);case"mat4":return t instanceof c?t:function(t){if(t instanceof u)return Z(t);const e=new u;Array.isArray(t)&&16===t.length&&e.fromArray(t.map(t=>De(t,0)));return Z(e)}(t);case"rgb":return t instanceof v?t:function(t){if("string"==typeof t||"number"==typeof t||t instanceof e)return pt(t);const[a,r,u]=Le(t,3);return Bt(a,r,u).rgb}(t);case"rgba":return t instanceof y||t instanceof x?t:Re(t);case"texture2d":return t;case"sampler2d":if(function(t){const e=t;return t instanceof m||t instanceof d||"function"==typeof e?.isSampler2D||!0===e?.isSampler2D}(t))return t;if(t instanceof i)return wt(t);throw new ShaderGraphCompileError(`Parameter "${r}" needs a texture value`)}}function ze(t,e,a,r){const u=`${a}Scalar`;if(e instanceof p&&"function"==typeof t[u])return t[u](e);if("function"==typeof t[a])return t[a](e);throw new ShaderGraphCompileError(`Node does not support ${a}`,r)}function Ve(t,e,a){if(t===e)return t;if("rgb"===t&&"vec3"===e||"vec3"===t&&"rgb"===e)return"vec3";if("rgba"===t&&"vec4"===e||"vec4"===t&&"rgba"===e)return"vec4";if("float"===t&&Ae(e))return e;if("float"===e&&Ae(t))return t;throw new ShaderGraphCompileError(`Cannot mix ${t} and ${e}`,a)}function ke(t,e,a){const r=t.subtract(a),u=yt(e),i=$(e);return Ut(i.multiply(r.x).subtract(u.multiply(r.y)).add(a.x),u.multiply(r.x).add(i.multiply(r.y)).add(a.y))}function Pe(t,e,a){const r=t.value["u"===e?"x":"v"===e?"y":e];if(r instanceof p)return r;throw new ShaderGraphCompileError(`Component "${e}" is not available on ${t.type}`,a)}function Ae(t){return"float"===t||"vec2"===t||"vec3"===t||"vec4"===t||"rgb"===t||"rgba"===t}function je(t){return Number.isFinite(t)?Math.min(1,Math.max(0,t)):0}function De(t,e){if("number"==typeof t)return t;if("string"==typeof t){const a=parseFloat(t);return Number.isFinite(a)?a:e}return"boolean"==typeof t?t?1:0:e}function Le(t,a,r=0){if(Array.isArray(t))return Array.from({length:a},(e,a)=>De(t[a],r));if(t instanceof o||t instanceof n||t instanceof s)return Array.from({length:a},(e,a)=>t.toArray()[a]??r);if(t instanceof e){const e=t.toArray();return Array.from({length:a},(t,a)=>e[a]??(3===a?1:r))}if(null!=t&&"object"==typeof t){const e=t,u=["x","y","z","w"];if(u.some(t=>null!=e[t]))return Array.from({length:a},(t,a)=>De(e[u[a]],r));const i=["r","g","b","a"];if(i.some(t=>null!=e[t]))return Array.from({length:a},(t,a)=>De(e[i[a]],3===a?1:r))}return Array.from({length:a},()=>De(t,r))}function qe(t){const[e,a]=Le(t,2);return Ut(e,a)}function Fe(t){const[e,a,r]=Le(t,3);return Bt(e,a,r)}function Re(t,a=1){if("string"==typeof t||"number"==typeof t||t instanceof e)return lt(t,a);if(t instanceof b)return lt(t,a);const[r,u,i,o]=Le(t,4,a);return $t(r,u,i,o)}function _e(t,e){return e<=1?0:t/(e-1)}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/shader/parameter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"reflect-metadata";import{reflect as e,decorateProperty as t}from"@plumier/reflect";import{ArrayMap as n}from"../utils/collections.js";Symbol("format");const
|
|
1
|
+
import"reflect-metadata";import{reflect as e,decorateProperty as t}from"@plumier/reflect";import{ArrayMap as n}from"../utils/collections.js";Symbol("format");const r=Symbol("parameterDefinition"),a=Symbol("dataAssetDefinition");export function shaderParameterUniformName(e){return`pu_${e}`}class i{constructor(e){this.options=e,this.isParameterDecorator=!0}}new Map;const o=new n,s=new Map,f=new Map,l=new WeakMap,p=new Map,u=new Map,c=new WeakMap;export function ParameterDefinition(e,t={}){return function(n){registerParameterDefinition(e??n.name,n,t)}}export function DataAssetDefinition(e,t={}){return function(n){registerDataAssetDefinition(e??n.name,n,t)}}export function registerParameterDefinition(e,t,n={}){if(null==e||""===e.trim())throw new Error("Parameter definition id must be a non-empty string");const a=s.get(e);null!=a&&a!==t&&console.warn(`Replacing parameter definition "${e}"`,{existing:a,type:t}),s.set(e,t),f.set(e,{id:e,type:t,...!0===n.abstract?{abstract:!0}:{}}),l.set(t,e),Reflect.defineMetadata(r,f.get(e),t)}export function getParameterDefinitionType(e){return s.get(e)}export function registerDataAssetDefinition(e,t,n={}){if(null==e||""===e.trim())throw new Error("Data asset definition id must be a non-empty string");const r=p.get(e);null!=r&&r!==t&&console.warn(`Replacing data asset definition "${e}"`,{existing:r,type:t}),p.set(e,t),u.set(e,{id:e,type:t,...!0===n.abstract?{abstract:!0}:{}}),c.set(t,e),Reflect.defineMetadata(a,u.get(e),t)}export function getDataAssetDefinitionType(e){return p.get(e)}export function getAssignableDataAssetDefinitions(e,t={}){if(null==e)return[];const n=getDataAssetDefinitionId(e);return Array.from(p.entries()).filter(([,t])=>isParameterDefinitionAssignableTo(t,e)).filter(([e])=>!0===t.includeAbstract||!isDataAssetDefinitionAbstract(e)).map(([e,t])=>({id:e,type:t,label:getParameterDefinitionDisplayName(t)})).sort((e,t)=>e.id===n?-1:t.id===n?1:e.label.localeCompare(t.label))}export function getDataAssetDefinitions(e={}){return Array.from(p.entries()).filter(([t])=>!0===e.includeAbstract||!isDataAssetDefinitionAbstract(t)).map(([e,t])=>({id:e,type:t,label:getParameterDefinitionDisplayName(t)})).sort((e,t)=>e.label.localeCompare(t.label))}export function getAssignableParameterDefinitions(e,t={}){if(null==e)return[];const n=getParameterDefinitionId(e);return Array.from(s.entries()).filter(([,t])=>isParameterDefinitionAssignableTo(t,e)).filter(([e])=>!0===t.includeAbstract||!isParameterDefinitionAbstract(e)).map(([e,t])=>({id:e,type:t,label:getParameterDefinitionDisplayName(t)})).sort((e,t)=>e.id===n?-1:t.id===n?1:e.label.localeCompare(t.label))}export function isParameterDefinitionAssignableTo(e,t){return null!=e&&null!=t&&(e===t||e.prototype instanceof t)}export function isParameterDefinitionStructAssignableTo(e,t){return null!=e&&null!=t&&(e===t||isParameterDefinitionAssignableTo(getParameterDefinitionType(e),getParameterDefinitionType(t)))}export function isParameterDefinitionAbstract(e){if(null==e)return!1;const t="string"==typeof e?f.get(e):getParameterDefinitionInfo(e);return!0===t?.abstract}export function isDataAssetDefinitionAbstract(e){if(null==e)return!1;const t="string"==typeof e?u.get(e):getDataAssetDefinitionInfo(e);return!0===t?.abstract}export function getParameterDefinitionDisplayName(e){return("string"==typeof e?e:e.name).replace(/Definition$/,"").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/[_-]+/g," ").trim().split(/\s+/).filter(e=>e.length>0).map(e=>e.length<=2&&e===e.toUpperCase()?e:e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}export function getParameterDefinitionId(e){if(null!=e)return l.get(e)??Reflect.getMetadata(r,e)?.id}export function getDataAssetDefinitionId(e){if(null!=e)return c.get(e)??Reflect.getMetadata(a,e)?.id}export function getParameterDefinitionInfo(e){if(null==e)return;const t=getParameterDefinitionId(e);return null!=t?f.get(t)??Reflect.getMetadata(r,e)??{id:t,type:e}:void 0}export function resolveParameterType(e){if(null!=e)return"function"==typeof e&&null==e.prototype?e():e}function m(e,t){const{enum:n,...r}=e,a=n??t;if(null==a||r.options?.length>0)return r;const i=function(e){return Object.entries(e).filter(([e])=>!function(e){return""!==e.trim()&&String(Number(e))===e}(e)).map(([e,t])=>({name:getParameterDefinitionDisplayName(e),value:t}))}(a);return{...r,type:r.type??g(i),defaultValue:void 0!==r.defaultValue?r.defaultValue:i[0]?.value,options:i}}function g(e){const t=new Set(e.map(e=>typeof e.value));if(1===t.size)return t.has("number")?Number:t.has("string")?String:void 0}export function getDataAssetDefinitionInfo(e){if(null==e)return;const t=getDataAssetDefinitionId(e);return null!=t?u.get(t)??Reflect.getMetadata(a,e)??{id:t,type:e}:void 0}export function Parameter(e){return function(n,r,a){if(null!=n){o.push(n.constructor,{name:r,options:e??{}});try{t(new i(e))(n,r,a)}catch(e){console.warn("Failed to decorate method ",n,r,a)}}}}export function extractShaderParameters(e){if(null==e)return[];const t=o.get(e).map(({name:t,options:n})=>{const r=Reflect.getMetadata("parameter:enum",e.prototype,t),a=Reflect.getMetadata("parameter:array",e.prototype,t),i=Reflect.getMetadata("parameter:arrayElementType",e.prototype,t),o=Reflect.getMetadata("parameter:dataAssetOf",e.prototype,t),s=m(n,r),f=Reflect.getMetadata("design:type",e.prototype,t),l=!0===s.array||!0===a||f===Array,p=resolveParameterType(s.type)??(l?i:void 0)??f,u=Reflect.getMetadata("prefab:type",e.prototype,t);return s.prefabOf??(s.prefabOf=u),s.dataAssetOf??(s.dataAssetOf=o),s.array=l,{name:t,type:p,options:s,definition:getParameterDefinitionInfo(p)}});return[...extractShaderParameters(Object.getPrototypeOf(e)).filter(e=>t.every(t=>t.name!==e.name)),...t]}export function ParameterCategory(e){}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/shader-nodes/pom.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{attributes as e,dFdx as t,dFdy as n,cross as r,float as a,normalize as i,transformed as f,uniforms as
|
|
1
|
+
import{attributes as e,dFdx as t,dFdy as n,cross as r,float as a,normalize as i,transformed as f,uniforms as v,varying as l,Vec2Node as p,vec4 as o,vec3 as s,abs as u,select as d,UniformSampler2dArraySlice as m}from"three-shader-graph";import{glslFunction as c}from"./glsl-node";export function computeTangent(e,a,f){const v=t(a),l=n(a),p=t(f),s=n(f),u=r(l,e),d=r(e,v),m=u.multiplyScalar(p.x).add(d.multiplyScalar(s.x));return o(i(m),1)}export function fallbackTangent(e){const t=u(e.y),n=d(t.lt(a(.999)),s(0,1,0),s(1,0,0));return i(r(n,e))}const S=e.normal,h=l(i(v.normalMatrix.multiplyVec(S))),x=l(f.mvPosition.xyz.multiplyScalar(-1));export function parallaxOcclusionMapping(e,t,n,r=8,i=24){if(function(e){return e instanceof m||"sampler2DArray"===e.constructor.typeName}(t)){const f=t.index??a(0);return c(p,{uv:e,heightScale:n,heightMap:t,heightMapLayer:f,minLayers:a(r),maxLayers:a(i),vN:h,vViewPosition:x},"\n vec3 N = normalize(vN);\n vec3 viewDir = normalize(vViewPosition);\n\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n\n vec3 dp2perp = cross(dp2, N);\n vec3 dp1perp = cross(N, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, N);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float nNumSamples = mix(float(maxLayers), float(minLayers), dot(-viewDir, N));\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 24; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture(heightMap, vec3(uv + vCurrOffset, heightMapLayer)).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n ")}return c(p,{uv:e,heightScale:n,heightMap:t,minLayers:a(r),maxLayers:a(i),vN:h,vViewPosition:x},"\n vec3 N = normalize(vN);\n vec3 viewDir = normalize(vViewPosition);\n\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, N);\n vec3 dp1perp = cross(N, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n // Construct TBN and transform view direction to tangent space\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, N);\n vec3 vv = -viewDir * tbn; \n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float nNumSamples = mix(float(maxLayers), float(minLayers), dot(-viewDir, N));\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 24; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n ")}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as e,__metadata as t}from"tslib";import{describe as a,expect as s,it as i,vi as o}from"vitest";o.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&o.fn()),e[t]),set:(e,t,a)=>(e[t]=a,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),o.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),o.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),o.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),o.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:o.fn()}));import{prepareClassParameters as n,prepareCustomParamsFromType as r,materializeDataAssetRef as d}from"../scene/materializer.js";import{SerializedParamType as m}from"../scene/model.js";import{DataAssetRef as l}from"../scene/objects/data-asset.js";import{DataAssetDefinition as p,getAssignableDataAssetDefinitions as c,getDataAssetDefinitionId as f,getDataAssetDefinitions as u,getDataAssetDefinitionType as y,isDataAssetDefinitionAbstract as v,Parameter as g,ParameterDefinition as B}from"../shader/parameter.js";let w=class{constructor(){this.amount=1}};e([g({type:Number}),t("design:type",Object)],w.prototype,"amount",void 0),w=e([B("test.data.statModifier")],w);let b=class{constructor(){this.displayName="Item"}};e([g({type:String}),t("design:type",Object)],b.prototype,"displayName",void 0),b=e([p("test.data.item",{abstract:!0})],b);let A=class extends b{constructor(){super(...arguments),this.damage=5,this.modifier=new w}};e([g({type:Number}),t("design:type",Object)],A.prototype,"damage",void 0),e([g({type:()=>w}),t("design:type",Object)],A.prototype,"modifier",void 0),A=e([p("test.data.weapon")],A);let
|
|
1
|
+
import{__decorate as e,__metadata as t}from"tslib";import{describe as a,expect as s,it as i,vi as o}from"vitest";o.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&o.fn()),e[t]),set:(e,t,a)=>(e[t]=a,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),o.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),o.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),o.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),o.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:o.fn()}));import{prepareClassParameters as n,prepareCustomParamsFromType as r,materializeDataAssetRef as d}from"../scene/materializer.js";import{SerializedParamType as m}from"../scene/model.js";import{DataAssetRef as l}from"../scene/objects/data-asset.js";import{DataAssetDefinition as p,getAssignableDataAssetDefinitions as c,getDataAssetDefinitionId as f,getDataAssetDefinitions as u,getDataAssetDefinitionType as y,isDataAssetDefinitionAbstract as v,Parameter as g,ParameterDefinition as B}from"../shader/parameter.js";let w=class{constructor(){this.amount=1}};e([g({type:Number}),t("design:type",Object)],w.prototype,"amount",void 0),w=e([B("test.data.statModifier")],w);let b=class{constructor(){this.displayName="Item"}};e([g({type:String}),t("design:type",Object)],b.prototype,"displayName",void 0),b=e([p("test.data.item",{abstract:!0})],b);let A=class extends b{constructor(){super(...arguments),this.damage=5,this.modifier=new w}};e([g({type:Number}),t("design:type",Object)],A.prototype,"damage",void 0),e([g({type:()=>w}),t("design:type",Object)],A.prototype,"modifier",void 0),A=e([p("test.data.weapon")],A);let h=class extends b{constructor(){super(...arguments),this.charges=1}};e([g({type:Number}),t("design:type",Object)],h.prototype,"charges",void 0),h=e([p("test.data.consumable")],h);class j{constructor(){this.item=null,this.items=[]}}e([g({type:()=>l,dataAssetOf:()=>b}),t("design:type",l)],j.prototype,"item",void 0),e([g({type:()=>l,dataAssetOf:()=>b,array:!0}),t("design:type",Array)],j.prototype,"items",void 0);class N{constructor(){this.items=[]}}function D(e){const t=new Map(e.map(e=>[e.id,e]));return{getAsset:o.fn(async e=>t.get(e)??null),getAssets:o.fn(async()=>e)}}e([g(),t("design:type",Array)],N.prototype,"items",void 0),Reflect.defineMetadata("design:type",Array,N.prototype,"items"),Reflect.defineMetadata("parameter:arrayElementType",l,N.prototype,"items"),Reflect.defineMetadata("parameter:dataAssetOf",b,N.prototype,"items"),a("data asset definitions",()=>{i("registers data asset definitions separately from parameter definitions",()=>{s(y("test.data.item")).toBe(b),s(f(A)).toBe("test.data.weapon"),s(v(b)).toBe(!0),s(v("test.data.item")).toBe(!0);const e=c(b);s(e.map(e=>e.id)).toEqual(["test.data.consumable","test.data.weapon"]);const t=u({includeAbstract:!0});s(t.some(e=>"test.data.item"===e.id)).toBe(!0),s(t.some(e=>"test.data.statModifier"===e.id)).toBe(!1),s(y("test.data.statModifier")).toBeUndefined()}),i("serializes data asset references as asset ids, including arrays",()=>{const e=r(j,{}),t=e.item,a=e.items;s(t.type).toBe(m.DataAsset),s(t.value).toBeNull(),s(a.type).toBe(m.Array),s(a.element).toBe(m.DataAsset),s(a.value).toEqual([])}),i("uses reflected metadata for data asset reference arrays",()=>{const e=r(N,{}).items;s(e.type).toBe(m.Array),s(e.element).toBe(m.DataAsset),s(e.value).toEqual([])}),i("materializes a data asset reference into a wrapper with nested inline structs",async()=>{const e={id:"asset.weapon",name:"Bronze Sword",type:"data",dataAsset:{definition:"test.data.weapon",params:{displayName:{type:m.String,value:"Bronze Sword"},damage:{type:m.Number,value:12},modifier:{type:m.Struct,struct:"test.data.statModifier",value:{amount:{type:m.Number,value:3}}}}}},t=D([e]),a=await n({item:{type:m.DataAsset,value:e.id},items:{type:m.Array,element:m.DataAsset,value:[e.id]}},j,t,{}),i=a.item;s(i).toBeInstanceOf(l),s(i.id).toBe(e.id),s(i.name).toBe("Bronze Sword"),s(i.asset).toBe(e),s(i.definitionId).toBe("test.data.weapon"),s(i.value).toBeInstanceOf(A),s(i.value.displayName).toBe("Bronze Sword"),s(i.value.damage).toBe(12),s(i.value.modifier).toBeInstanceOf(w),s(i.value.modifier.amount).toBe(3),s(a.items).toHaveLength(1),s(a.items[0].value.damage).toBe(12)}),i("resolves missing and invalid data asset references safely",async()=>{const e=o.spyOn(console,"warn").mockImplementation(()=>{}),t=D([{id:"asset.notData",name:"Texture pretending",type:"texture"},{id:"asset.unknownDefinition",name:"Unknown Definition",type:"data",dataAsset:{definition:"test.data.unknown",params:{}}},{id:"asset.abstractDefinition",name:"Abstract Definition",type:"data",dataAsset:{definition:"test.data.item",params:{}}},{id:"asset.invalidParams",name:"Invalid Params",type:"data",dataAsset:{definition:"test.data.weapon",params:"bad"}}]);await s(d("asset.missing",t,{})).resolves.toBeNull(),await s(d("asset.notData",t,{})).resolves.toBeNull(),await s(d("asset.unknownDefinition",t,{})).resolves.toBeNull(),await s(d("asset.abstractDefinition",t,{})).resolves.toBeNull(),await s(d("asset.invalidParams",t,{})).resolves.toBeNull();const a=await n({item:{type:m.DataAsset,value:"asset.missing"}},j,t,{});s(a.item).toBeUndefined(),s(e).toHaveBeenCalled(),e.mockRestore()})});/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|