sparcoon 0.7.2 → 0.9.0
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/README.md +124 -76
- package/dist/artifact/FXArtifact.d.ts +120 -0
- package/dist/artifact/FXArtifact.js +1 -0
- package/dist/coreLayout.d.ts +22 -0
- package/dist/coreLayout.js +32 -0
- package/dist/effect/FXEffect.d.ts +77 -0
- package/dist/effect/FXEffect.js +454 -0
- package/dist/effect/FXEffectSampling.Internal.d.ts +24 -0
- package/dist/effect/FXEffectSampling.Internal.js +165 -0
- package/dist/effect/FXEffectSpec.d.ts +115 -0
- package/dist/effect/FXEffectSpec.js +1 -0
- package/dist/emitter/FXEmitter.Internal.d.ts +23 -58
- package/dist/emitter/FXEmitter.Internal.js +13 -29
- package/dist/emitter/FXEmitter.d.ts +46 -48
- package/dist/emitter/FXEmitter.js +355 -186
- package/dist/emitter/FXFromArtifactsOptions.d.ts +13 -0
- package/dist/emitter/FXFromArtifactsOptions.js +1 -0
- package/dist/emitter/FXObjectMotion.Internal.d.ts +33 -0
- package/dist/emitter/FXObjectMotion.Internal.js +87 -0
- package/dist/emitter/FXSimulationHolder.d.ts +1 -0
- package/dist/emitter/FXSimulationHolder.js +43 -0
- package/dist/index.d.ts +10 -39
- package/dist/index.js +13 -36
- package/dist/instancedParticle/FXInstancedParticle.d.ts +1 -22
- package/dist/instancedParticle/FXInstancedParticle.js +145 -85
- package/dist/instancedParticle/glTypeInfo.d.ts +5 -0
- package/dist/instancedParticle/glTypeInfo.js +3 -0
- package/dist/instancedParticle/primitiveGeometry.d.ts +1 -0
- package/dist/instancedParticle/primitiveGeometry.js +30 -0
- package/dist/miscellaneous/asserts.d.ts +1 -18
- package/dist/miscellaneous/asserts.js +21 -28
- package/dist/miscellaneous/fxMath.d.ts +26 -0
- package/dist/miscellaneous/fxMath.js +261 -0
- package/dist/miscellaneous/math.d.ts +2 -7
- package/dist/miscellaneous/math.js +8 -9
- package/dist/miscellaneous/texture/fxDataTexture.d.ts +26 -0
- package/dist/miscellaneous/texture/fxDataTexture.js +20 -0
- package/dist/render/FXArtifactMaterial.Internal.d.ts +16 -0
- package/dist/render/FXArtifactMaterial.Internal.js +944 -0
- package/dist/render/FXArtifactMaterial.d.ts +1 -0
- package/dist/render/FXArtifactMaterial.js +79 -0
- package/dist/render/FXMaterialOptions.d.ts +27 -0
- package/dist/render/FXMaterialOptions.js +5 -0
- package/dist/render/FXMeshMaterial.d.ts +40 -0
- package/dist/render/FXMeshMaterial.js +77 -0
- package/dist/world/FXWorld.d.ts +42 -0
- package/dist/world/FXWorld.js +103 -0
- package/package.json +45 -29
- package/dist/_virtual/2d.js +0 -3
- package/dist/_virtual/3d.js +0 -3
- package/dist/_virtual/4d.js +0 -3
- package/dist/_virtual/mod.js +0 -5
- package/dist/_virtual/mod2.js +0 -3
- package/dist/emitter/behavior/FXBehavior.d.ts +0 -24
- package/dist/emitter/behavior/FXBehavior.js +0 -10
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.d.ts +0 -23
- package/dist/emitter/behavior/FXBehaviorDirectionalForce.js +0 -72
- package/dist/emitter/behavior/FXBehaviorPointForce.d.ts +0 -36
- package/dist/emitter/behavior/FXBehaviorPointForce.js +0 -94
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.d.ts +0 -24
- package/dist/emitter/behavior/FXBehaviorScaleOverLife.js +0 -55
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.d.ts +0 -20
- package/dist/emitter/behavior/FXBehaviorTorqueDamping.js +0 -48
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.d.ts +0 -25
- package/dist/emitter/behavior/FXBehaviorTorqueNoise.js +0 -67
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.d.ts +0 -19
- package/dist/emitter/behavior/FXBehaviorTorqueOverLife.js +0 -41
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.d.ts +0 -20
- package/dist/emitter/behavior/FXBehaviorVelocityDamping.js +0 -50
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.d.ts +0 -25
- package/dist/emitter/behavior/FXBehaviorVelocityNoise.js +0 -76
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.d.ts +0 -22
- package/dist/emitter/behavior/FXBehaviorVelocityOverLife.js +0 -55
- package/dist/emitter/spawn/FXSpawn.d.ts +0 -11
- package/dist/emitter/spawn/FXSpawn.js +0 -10
- package/dist/emitter/spawn/FXSpawnBox.d.ts +0 -18
- package/dist/emitter/spawn/FXSpawnBox.js +0 -50
- package/dist/emitter/spawn/FXSpawnLifetime.d.ts +0 -17
- package/dist/emitter/spawn/FXSpawnLifetime.js +0 -44
- package/dist/emitter/spawn/FXSpawnOffset.d.ts +0 -21
- package/dist/emitter/spawn/FXSpawnOffset.js +0 -49
- package/dist/emitter/spawn/FXSpawnPoint.d.ts +0 -18
- package/dist/emitter/spawn/FXSpawnPoint.js +0 -46
- package/dist/emitter/spawn/FXSpawnRotation.d.ts +0 -17
- package/dist/emitter/spawn/FXSpawnRotation.js +0 -42
- package/dist/emitter/spawn/FXSpawnScale.d.ts +0 -22
- package/dist/emitter/spawn/FXSpawnScale.js +0 -56
- package/dist/emitter/spawn/FXSpawnSphere.d.ts +0 -36
- package/dist/emitter/spawn/FXSpawnSphere.js +0 -87
- package/dist/emitter/spawn/FXSpawnTorque.d.ts +0 -17
- package/dist/emitter/spawn/FXSpawnTorque.js +0 -42
- package/dist/emitter/spawn/FXSpawnVelocity.d.ts +0 -29
- package/dist/emitter/spawn/FXSpawnVelocity.js +0 -91
- package/dist/instancedParticle/FXInstancedParticle.Internal.d.ts +0 -2
- package/dist/instancedParticle/shared.d.ts +0 -19
- package/dist/instancedParticle/shared.js +0 -116
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.d.ts +0 -24
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.Internal.js +0 -275
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.d.ts +0 -75
- package/dist/materials/FXDiffuseMaterial/FXDiffuseMaterial.js +0 -63
- package/dist/materials/FXMaterial/FXBlending.Internal.d.ts +0 -24
- package/dist/materials/FXMaterial/FXBlending.Internal.js +0 -64
- package/dist/materials/FXMaterial/FXDepthMaterial.Internal.d.ts +0 -4
- package/dist/materials/FXMaterial/FXDepthMaterial.Internal.js +0 -144
- package/dist/materials/FXMaterial/FXDistanceMaterial.Internal.d.ts +0 -4
- package/dist/materials/FXMaterial/FXDistanceMaterial.Internal.js +0 -175
- package/dist/materials/FXMaterial/FXMaterial.d.ts +0 -70
- package/dist/materials/FXMaterial/FXMaterial.js +0 -51
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.d.ts +0 -7
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.Internal.js +0 -103
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.d.ts +0 -7
- package/dist/materials/FXUnlitMaterial/FXUnlitMaterial.js +0 -21
- package/dist/miscellaneous/color/FXColor.Internal.d.ts +0 -7
- package/dist/miscellaneous/color/FXColor.Internal.js +0 -42
- package/dist/miscellaneous/color/FXColor.d.ts +0 -234
- package/dist/miscellaneous/color/FXColor.js +0 -636
- package/dist/miscellaneous/curve/FXCurve1D.Internal.d.ts +0 -20
- package/dist/miscellaneous/curve/FXCurve1D.d.ts +0 -17
- package/dist/miscellaneous/curve/FXCurve1D.js +0 -94
- package/dist/miscellaneous/miscellaneous.d.ts +0 -34
- package/dist/miscellaneous/miscellaneous.js +0 -85
- package/dist/miscellaneous/texture/FXTextureView.Internal.d.ts +0 -49
- package/dist/miscellaneous/texture/FXTextureView.Internal.js +0 -6
- package/dist/miscellaneous/texture/FXTextureView.d.ts +0 -72
- package/dist/miscellaneous/texture/FXTextureView.js +0 -234
- package/dist/miscellaneous/webglCapabilities.d.ts +0 -1
- package/dist/miscellaneous/webglCapabilities.js +0 -45
- package/dist/node_modules/fast-simplex-noise/lib/2d.js +0 -93
- package/dist/node_modules/fast-simplex-noise/lib/3d.js +0 -142
- package/dist/node_modules/fast-simplex-noise/lib/4d.js +0 -196
- package/dist/node_modules/fast-simplex-noise/lib/mod.js +0 -24
- package/dist/nodes/FXNode.d.ts +0 -5
- package/dist/nodes/FXNode.js +0 -10
- package/dist/nodes/blending/FXNodeBlending.d.ts +0 -6
- package/dist/nodes/blending/FXNodeBlending.js +0 -9
- package/dist/nodes/blending/FXNodeLightnessBlendingMask.d.ts +0 -19
- package/dist/nodes/blending/FXNodeLightnessBlendingMask.js +0 -65
- package/dist/nodes/color/FXNodeColor.d.ts +0 -6
- package/dist/nodes/color/FXNodeColor.js +0 -9
- package/dist/nodes/color/FXNodeColorOverLife.d.ts +0 -22
- package/dist/nodes/color/FXNodeColorOverLife.js +0 -64
- package/dist/nodes/color/FXNodeSphericalClip.d.ts +0 -21
- package/dist/nodes/color/FXNodeSphericalClip.js +0 -54
- package/dist/nodes/normal/FXNodeFlatNormal.d.ts +0 -6
- package/dist/nodes/normal/FXNodeFlatNormal.js +0 -17
- package/dist/nodes/normal/FXNodeNormal.d.ts +0 -6
- package/dist/nodes/normal/FXNodeNormal.js +0 -9
- package/dist/nodes/normal/FXNodeSphericalNormal.d.ts +0 -6
- package/dist/nodes/normal/FXNodeSphericalNormal.js +0 -24
- package/dist/nodes/texture/FXNodeAnimatedTexture.d.ts +0 -52
- package/dist/nodes/texture/FXNodeAnimatedTexture.js +0 -151
- package/dist/nodes/texture/FXNodeStaticTexture.d.ts +0 -20
- package/dist/nodes/texture/FXNodeStaticTexture.js +0 -67
- package/dist/nodes/texture/FXNodeTexture.d.ts +0 -6
- package/dist/nodes/texture/FXNodeTexture.js +0 -9
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { FXColor } from '../../miscellaneous/color/FXColor.js';
|
|
2
|
-
import { FXNodeSphericalNormal } from '../../nodes/normal/FXNodeSphericalNormal.js';
|
|
3
|
-
import { FXMaterial } from '../FXMaterial/FXMaterial.js';
|
|
4
|
-
import { buildFXDiffuseMaterial } from './FXDiffuseMaterial.Internal.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Diffuse particle material with lighting, normals, emission, and optional subsurface scattering
|
|
8
|
-
*/
|
|
9
|
-
class FXDiffuseMaterial extends FXMaterial {
|
|
10
|
-
/**
|
|
11
|
-
* @param options - Material configuration
|
|
12
|
-
*/
|
|
13
|
-
constructor(options = {}) {
|
|
14
|
-
super(options);
|
|
15
|
-
this._private_normalNodes = options.normalNodes ?? [new FXNodeSphericalNormal()];
|
|
16
|
-
this._private_emissionNodes = options.emissionNodes ?? [];
|
|
17
|
-
this._private_scatterUniforms =
|
|
18
|
-
options.enableScatter === true
|
|
19
|
-
? {
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
21
|
-
u_ScatterTint: { value: new FXColor(options.scatterTint ?? 0xffd999).toThreeColor() },
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
23
|
-
u_ScatterPower: { value: options.scatterPower ?? 10 },
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
25
|
-
u_ForwardScatterStrength: { value: options.forwardScatterStrength ?? 1 },
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
27
|
-
u_BackScatterStrength: { value: options.backScatterStrength ?? 1 },
|
|
28
|
-
}
|
|
29
|
-
: undefined;
|
|
30
|
-
this._private_shadowSensitivity = { value: options.shadowSensitivity ?? 1 };
|
|
31
|
-
}
|
|
32
|
-
/** Releases resources held by all albedo, normal, and emission nodes */
|
|
33
|
-
destroy() {
|
|
34
|
-
super.destroy();
|
|
35
|
-
for (const node of this._private_normalNodes) {
|
|
36
|
-
node.destroy?.();
|
|
37
|
-
}
|
|
38
|
-
for (const node of this._private_emissionNodes) {
|
|
39
|
-
node.destroy?.();
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/** @internal */
|
|
43
|
-
buildThreeMaterial(varyings) {
|
|
44
|
-
return buildFXDiffuseMaterial(varyings, this.blending, this.useAlphaHashing, this.alphaTest, this.albedoNodes, this._private_normalNodes, this._private_emissionNodes, this._private_scatterUniforms, this._private_shadowSensitivity);
|
|
45
|
-
}
|
|
46
|
-
prepare() {
|
|
47
|
-
let i = 0;
|
|
48
|
-
for (const node of this.albedoNodes) {
|
|
49
|
-
node.prepare?.(i);
|
|
50
|
-
i += 1;
|
|
51
|
-
}
|
|
52
|
-
for (const node of this._private_normalNodes) {
|
|
53
|
-
node.prepare?.(i);
|
|
54
|
-
i += 1;
|
|
55
|
-
}
|
|
56
|
-
for (const node of this._private_emissionNodes) {
|
|
57
|
-
node.prepare?.(i);
|
|
58
|
-
i += 1;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export { FXDiffuseMaterial };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { FXNodeBlending } from "../../nodes/blending/FXNodeBlending";
|
|
2
|
-
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
-
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
-
import { FXBlending } from "./FXMaterial";
|
|
5
|
-
export interface AlbedoBlendingCode {
|
|
6
|
-
/** Replacement for #include <map_fragment>. null means: leave the include as-is */
|
|
7
|
-
mapFragment: string | null;
|
|
8
|
-
/** Replacement for #include <premultiplied_alpha_fragment> */
|
|
9
|
-
premultChunk: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Processes albedoNodes in order to produce shader code for both the color assignment
|
|
13
|
-
* and the per-pixel blending mode.
|
|
14
|
-
*
|
|
15
|
-
* Nodes are composed sequentially: each node receives the current accumulated value via
|
|
16
|
-
* EXPRESSION_CURRENT_VALUE_PLACEHOLDER and returns a new value. Nodes that do not use
|
|
17
|
-
* the placeholder act as sources and replace the current value entirely.
|
|
18
|
-
*
|
|
19
|
-
* When a FXNodeBlending appears, it receives both the current mask (via
|
|
20
|
-
* EXPRESSION_CURRENT_VALUE_PLACEHOLDER) and the current color (via
|
|
21
|
-
* EXPRESSION_CURRENT_COLOR_PLACEHOLDER), and returns the new mask value. Color nodes
|
|
22
|
-
* that follow a blending node do not affect the mask.
|
|
23
|
-
*/
|
|
24
|
-
export declare function buildAlbedoAndBlendingCode(albedoNodes: readonly (FXNodeColor | FXNodeTexture | FXNodeBlending)[], blending: FXBlending, useAlphaHashing: boolean): AlbedoBlendingCode;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { CURRENT_EXPRESSION_VALUE_PLACEHOLDER, BLENDING_EXPRESSION_CURRENT_COLOR_PLACEHOLDER } from '../../nodes/FXNode.js';
|
|
2
|
-
import { FXNodeBlending } from '../../nodes/blending/FXNodeBlending.js';
|
|
3
|
-
import { FXBlending } from './FXMaterial.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Processes albedoNodes in order to produce shader code for both the color assignment
|
|
7
|
-
* and the per-pixel blending mode.
|
|
8
|
-
*
|
|
9
|
-
* Nodes are composed sequentially: each node receives the current accumulated value via
|
|
10
|
-
* EXPRESSION_CURRENT_VALUE_PLACEHOLDER and returns a new value. Nodes that do not use
|
|
11
|
-
* the placeholder act as sources and replace the current value entirely.
|
|
12
|
-
*
|
|
13
|
-
* When a FXNodeBlending appears, it receives both the current mask (via
|
|
14
|
-
* EXPRESSION_CURRENT_VALUE_PLACEHOLDER) and the current color (via
|
|
15
|
-
* EXPRESSION_CURRENT_COLOR_PLACEHOLDER), and returns the new mask value. Color nodes
|
|
16
|
-
* that follow a blending node do not affect the mask.
|
|
17
|
-
*/
|
|
18
|
-
function buildAlbedoAndBlendingCode(albedoNodes, blending, useAlphaHashing) {
|
|
19
|
-
if (albedoNodes.length === 0) {
|
|
20
|
-
return { mapFragment: null, premultChunk: buildPremultChunk(blending, false) };
|
|
21
|
-
}
|
|
22
|
-
const hasBlendingNodes = albedoNodes.some((node) => node instanceof FXNodeBlending);
|
|
23
|
-
const lines = [];
|
|
24
|
-
lines.push("vec4 fxAlbedo = vec4(1.0);");
|
|
25
|
-
if (hasBlendingNodes) {
|
|
26
|
-
lines.push("float fxBlendMask = 1.0;");
|
|
27
|
-
}
|
|
28
|
-
for (const node of albedoNodes) {
|
|
29
|
-
if (node instanceof FXNodeBlending) {
|
|
30
|
-
lines.push(`fxBlendMask = ${node.blendingExpression
|
|
31
|
-
.replace(CURRENT_EXPRESSION_VALUE_PLACEHOLDER, "fxBlendMask")
|
|
32
|
-
.replace(BLENDING_EXPRESSION_CURRENT_COLOR_PLACEHOLDER, "fxAlbedo")};`);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
lines.push(`fxAlbedo = ${node.colorExpression.replace(CURRENT_EXPRESSION_VALUE_PLACEHOLDER, "fxAlbedo")};`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const discardLine = useAlphaHashing ? "" : "if (diffuseColor.a < 0.0035) discard;";
|
|
39
|
-
lines.push(`diffuseColor = fxAlbedo; ${discardLine}`);
|
|
40
|
-
return {
|
|
41
|
-
mapFragment: lines.join("\n"),
|
|
42
|
-
premultChunk: buildPremultChunk(blending, hasBlendingNodes),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function buildPremultChunk(blending, hasBlendingNodes) {
|
|
46
|
-
if (!hasBlendingNodes) {
|
|
47
|
-
return `gl_FragColor.rgb *= gl_FragColor.a;`;
|
|
48
|
-
}
|
|
49
|
-
if (blending === FXBlending.MASKED_ADDITIVE) {
|
|
50
|
-
return `
|
|
51
|
-
gl_FragColor.rgb *= gl_FragColor.a;
|
|
52
|
-
gl_FragColor.a *= (1.0 - clamp(fxBlendMask, 0.0, 1.0));
|
|
53
|
-
`;
|
|
54
|
-
}
|
|
55
|
-
// MASKED_MULTIPLY: dark areas darken destination, bright areas normal-blend
|
|
56
|
-
return `
|
|
57
|
-
gl_FragColor.rgb *= gl_FragColor.a;
|
|
58
|
-
float fxLumPremult = dot(gl_FragColor.rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
59
|
-
vec4 fxMultiply = vec4(0.0, 0.0, 0.0, gl_FragColor.a - fxLumPremult);
|
|
60
|
-
gl_FragColor = mix(gl_FragColor, fxMultiply, clamp(fxBlendMask, 0.0, 1.0));
|
|
61
|
-
`;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export { buildAlbedoAndBlendingCode };
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { MeshDepthMaterial } from "three";
|
|
2
|
-
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
-
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
-
export declare function buildDepthMaterial(albedoNodes: readonly (FXNodeColor | FXNodeTexture)[], depthAlphaTest: number, useDepthAlphaHash: boolean, useSphericalDepth: boolean): MeshDepthMaterial;
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { MeshDepthMaterial, DoubleSide, RGBADepthPacking } from 'three';
|
|
2
|
-
import { PARTICLE_DEFINES } from '../../miscellaneous/miscellaneous.js';
|
|
3
|
-
import { CURRENT_EXPRESSION_VALUE_PLACEHOLDER } from '../../nodes/FXNode.js';
|
|
4
|
-
|
|
5
|
-
const DEPTH_VERTEX_SHADER = `
|
|
6
|
-
#define PARTICLE_POSITION_X a_builtin[0][0]
|
|
7
|
-
#define PARTICLE_POSITION_Y a_builtin[0][1]
|
|
8
|
-
#define PARTICLE_POSITION_Z a_builtin[0][2]
|
|
9
|
-
|
|
10
|
-
#define PARTICLE_SCALE_X a_builtin[1][2]
|
|
11
|
-
#define PARTICLE_SCALE_Y a_builtin[1][3]
|
|
12
|
-
|
|
13
|
-
#define PARTICLE_ROTATION a_builtin[2][1]
|
|
14
|
-
|
|
15
|
-
attribute mat4 a_builtin;
|
|
16
|
-
varying mat4 p_builtin;
|
|
17
|
-
varying vec2 p_uv;
|
|
18
|
-
varying vec2 vHighPrecisionZW;
|
|
19
|
-
varying float vCenterViewZ;
|
|
20
|
-
|
|
21
|
-
#ifdef USE_ALPHAHASH
|
|
22
|
-
varying vec3 vPosition;
|
|
23
|
-
#endif
|
|
24
|
-
|
|
25
|
-
void main() {
|
|
26
|
-
p_builtin = a_builtin;
|
|
27
|
-
p_uv = uv;
|
|
28
|
-
|
|
29
|
-
#ifdef USE_ALPHAHASH
|
|
30
|
-
vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);
|
|
31
|
-
#endif
|
|
32
|
-
|
|
33
|
-
vec2 billboardOffset = position.xy;
|
|
34
|
-
billboardOffset.x *= PARTICLE_SCALE_X;
|
|
35
|
-
billboardOffset.y *= PARTICLE_SCALE_Y;
|
|
36
|
-
|
|
37
|
-
float cosRotation = cos(PARTICLE_ROTATION);
|
|
38
|
-
float sinRotation = sin(PARTICLE_ROTATION);
|
|
39
|
-
billboardOffset = vec2(
|
|
40
|
-
billboardOffset.x * cosRotation - billboardOffset.y * sinRotation,
|
|
41
|
-
billboardOffset.x * sinRotation + billboardOffset.y * cosRotation
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
vec3 particleCenter = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
|
|
45
|
-
vec4 modelViewPosition = modelViewMatrix * vec4(particleCenter, 1.0);
|
|
46
|
-
vCenterViewZ = modelViewPosition.z;
|
|
47
|
-
modelViewPosition.xy += billboardOffset;
|
|
48
|
-
gl_Position = projectionMatrix * modelViewPosition;
|
|
49
|
-
vHighPrecisionZW = gl_Position.zw;
|
|
50
|
-
}
|
|
51
|
-
`;
|
|
52
|
-
/**
|
|
53
|
-
* GLSL snippet that replaces the flat `fragCoordZ` with a spherical depth
|
|
54
|
-
* approximation. Treats each billboard as the front hemisphere of a sphere
|
|
55
|
-
* whose radius equals half the smaller particle scale dimension. Fragments
|
|
56
|
-
* outside that radius are discarded, producing a circular silhouette.
|
|
57
|
-
*
|
|
58
|
-
* Expects `vCenterViewZ` (view-space Z of the particle center), `p_uv`,
|
|
59
|
-
* `PARTICLE_SCALE_X / Y`, and `projectionMatrix` to be available.
|
|
60
|
-
*/
|
|
61
|
-
const SPHERICAL_DEPTH_FRAG_COORD_Z = `
|
|
62
|
-
float sphereOffsetX = (p_uv.x - 0.5) * PARTICLE_SCALE_X;
|
|
63
|
-
float sphereOffsetY = (p_uv.y - 0.5) * PARTICLE_SCALE_Y;
|
|
64
|
-
float sphereRadius = min(PARTICLE_SCALE_X, PARTICLE_SCALE_Y) * 0.5;
|
|
65
|
-
float squaredDistanceFromCenter = sphereOffsetX * sphereOffsetX + sphereOffsetY * sphereOffsetY;
|
|
66
|
-
if (squaredDistanceFromCenter > sphereRadius * sphereRadius) discard;
|
|
67
|
-
|
|
68
|
-
float sphereViewZ = vCenterViewZ + sqrt(sphereRadius * sphereRadius - squaredDistanceFromCenter);
|
|
69
|
-
float projectedZ = projectionMatrix[2][2] * sphereViewZ + projectionMatrix[3][2];
|
|
70
|
-
float projectedW = projectionMatrix[2][3] * sphereViewZ + projectionMatrix[3][3];
|
|
71
|
-
float normalizedDeviceZ = projectedZ / projectedW;
|
|
72
|
-
|
|
73
|
-
#ifdef USE_REVERSEDEPTHBUF
|
|
74
|
-
float fragCoordZ = normalizedDeviceZ;
|
|
75
|
-
#else
|
|
76
|
-
float fragCoordZ = 0.5 * normalizedDeviceZ + 0.5;
|
|
77
|
-
#endif
|
|
78
|
-
`;
|
|
79
|
-
const FRAG_COORD_Z_PATTERN = /float fragCoordZ\b[^;]*;/;
|
|
80
|
-
function buildDepthMaterial(albedoNodes, depthAlphaTest, useDepthAlphaHash, useSphericalDepth) {
|
|
81
|
-
const depthNodes = albedoNodes.filter((node) => node.affectsDepth);
|
|
82
|
-
const needsFragmentPatch = depthNodes.length > 0 || useSphericalDepth;
|
|
83
|
-
const material = new MeshDepthMaterial({
|
|
84
|
-
name: "FXDepthMaterial",
|
|
85
|
-
depthPacking: RGBADepthPacking,
|
|
86
|
-
side: DoubleSide,
|
|
87
|
-
forceSinglePass: true,
|
|
88
|
-
alphaHash: useDepthAlphaHash,
|
|
89
|
-
});
|
|
90
|
-
material.onBeforeCompile = (shader) => {
|
|
91
|
-
shader.vertexShader = DEPTH_VERTEX_SHADER;
|
|
92
|
-
if (!needsFragmentPatch) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const seenCacheKeys = new Set();
|
|
96
|
-
const uniqueHelpers = depthNodes
|
|
97
|
-
.filter((node) => {
|
|
98
|
-
if (seenCacheKeys.has(node.cacheKey)) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
seenCacheKeys.add(node.cacheKey);
|
|
102
|
-
return true;
|
|
103
|
-
})
|
|
104
|
-
.map((node) => node.helperFunctions)
|
|
105
|
-
.join("\n");
|
|
106
|
-
const fragmentPreamble = [
|
|
107
|
-
PARTICLE_DEFINES,
|
|
108
|
-
"varying mat4 p_builtin;",
|
|
109
|
-
"varying vec2 p_uv;",
|
|
110
|
-
"varying float vCenterViewZ;",
|
|
111
|
-
useSphericalDepth ? "uniform mat4 projectionMatrix;" : "",
|
|
112
|
-
depthNodes.flatMap((node) => node.uniformDeclarations).join("\n"),
|
|
113
|
-
uniqueHelpers,
|
|
114
|
-
].join("\n");
|
|
115
|
-
for (const node of depthNodes) {
|
|
116
|
-
Object.assign(shader.uniforms, node.uniforms);
|
|
117
|
-
}
|
|
118
|
-
let fragmentShader = shader.fragmentShader;
|
|
119
|
-
if (depthNodes.length > 0) {
|
|
120
|
-
const albedoLines = ["vec4 fxDepthAlbedo = vec4(1.0);"];
|
|
121
|
-
for (const node of depthNodes) {
|
|
122
|
-
albedoLines.push(`fxDepthAlbedo = ${node.colorExpression.replace(CURRENT_EXPRESSION_VALUE_PLACEHOLDER, "fxDepthAlbedo")};`);
|
|
123
|
-
}
|
|
124
|
-
albedoLines.push(`diffuseColor.a = fxDepthAlbedo.a;`);
|
|
125
|
-
albedoLines.push(`if (diffuseColor.a < ${depthAlphaTest.toFixed(4)}) discard;`);
|
|
126
|
-
fragmentShader = fragmentShader.replace("#include <map_fragment>", albedoLines.join("\n"));
|
|
127
|
-
}
|
|
128
|
-
if (useSphericalDepth) {
|
|
129
|
-
if (!FRAG_COORD_Z_PATTERN.test(fragmentShader)) {
|
|
130
|
-
console.warn("FXDepthMaterial: could not find 'float fragCoordZ' in the depth fragment shader. " +
|
|
131
|
-
"Spherical depth will not be applied. " +
|
|
132
|
-
"This may indicate a Three.js version mismatch.");
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
fragmentShader = fragmentShader.replace(FRAG_COORD_Z_PATTERN, SPHERICAL_DEPTH_FRAG_COORD_Z);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
shader.fragmentShader = fragmentPreamble + "\n" + fragmentShader;
|
|
139
|
-
};
|
|
140
|
-
material.customProgramCacheKey = () => `fx-depth-${useDepthAlphaHash ? "alphaHash" : "alphaTest"}-${useSphericalDepth ? "spherical" : "flat"}-${depthNodes.map((node) => node.cacheKey).join("-") || "none"}`;
|
|
141
|
-
return material;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export { buildDepthMaterial };
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { MeshDistanceMaterial } from "three";
|
|
2
|
-
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
3
|
-
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
4
|
-
export declare function buildDistanceMaterial(albedoNodes: readonly (FXNodeColor | FXNodeTexture)[], distanceAlphaTest: number, useDistanceAlphaHash: boolean, useSphericalDepth: boolean): MeshDistanceMaterial;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { MeshDistanceMaterial, DoubleSide } from 'three';
|
|
2
|
-
import { PARTICLE_DEFINES } from '../../miscellaneous/miscellaneous.js';
|
|
3
|
-
import { CURRENT_EXPRESSION_VALUE_PLACEHOLDER } from '../../nodes/FXNode.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Custom vertex shader for point/spot light shadow maps.
|
|
7
|
-
*
|
|
8
|
-
* Unlike the depth material (which writes clip-space Z for directional light
|
|
9
|
-
* shadows), the distance material writes the world-space distance from each
|
|
10
|
-
* fragment to the light position. This means we need to reconstruct world
|
|
11
|
-
* position for each billboarded vertex.
|
|
12
|
-
*
|
|
13
|
-
* `vWorldPosition` is a Three.js convention consumed by the distance fragment
|
|
14
|
-
* shader. `viewMatrix` here is the shadow camera's view matrix, so the
|
|
15
|
-
* billboard faces the light - which is correct for shadow shape.
|
|
16
|
-
*/
|
|
17
|
-
const DISTANCE_VERTEX_SHADER = `
|
|
18
|
-
#define DISTANCE
|
|
19
|
-
|
|
20
|
-
#define PARTICLE_POSITION_X a_builtin[0][0]
|
|
21
|
-
#define PARTICLE_POSITION_Y a_builtin[0][1]
|
|
22
|
-
#define PARTICLE_POSITION_Z a_builtin[0][2]
|
|
23
|
-
|
|
24
|
-
#define PARTICLE_SCALE_X a_builtin[1][2]
|
|
25
|
-
#define PARTICLE_SCALE_Y a_builtin[1][3]
|
|
26
|
-
|
|
27
|
-
#define PARTICLE_ROTATION a_builtin[2][1]
|
|
28
|
-
|
|
29
|
-
attribute mat4 a_builtin;
|
|
30
|
-
varying mat4 p_builtin;
|
|
31
|
-
varying vec2 p_uv;
|
|
32
|
-
varying vec3 vWorldPosition;
|
|
33
|
-
|
|
34
|
-
#ifdef USE_ALPHAHASH
|
|
35
|
-
varying vec3 vPosition;
|
|
36
|
-
#endif
|
|
37
|
-
|
|
38
|
-
void main() {
|
|
39
|
-
p_builtin = a_builtin;
|
|
40
|
-
p_uv = uv;
|
|
41
|
-
|
|
42
|
-
#ifdef USE_ALPHAHASH
|
|
43
|
-
vPosition = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z) + vec3(position.xy, 0.0);
|
|
44
|
-
#endif
|
|
45
|
-
|
|
46
|
-
vec2 billboardOffset = position.xy;
|
|
47
|
-
billboardOffset.x *= PARTICLE_SCALE_X;
|
|
48
|
-
billboardOffset.y *= PARTICLE_SCALE_Y;
|
|
49
|
-
|
|
50
|
-
float cosRotation = cos(PARTICLE_ROTATION);
|
|
51
|
-
float sinRotation = sin(PARTICLE_ROTATION);
|
|
52
|
-
billboardOffset = vec2(
|
|
53
|
-
billboardOffset.x * cosRotation - billboardOffset.y * sinRotation,
|
|
54
|
-
billboardOffset.x * sinRotation + billboardOffset.y * cosRotation
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
vec3 particleCenter = vec3(PARTICLE_POSITION_X, PARTICLE_POSITION_Y, PARTICLE_POSITION_Z);
|
|
58
|
-
|
|
59
|
-
// Reconstruct world-space position for the billboarded vertex.
|
|
60
|
-
// Camera axes are extracted from the shadow camera's view matrix (transposed
|
|
61
|
-
// rotation part), then scaled by the billboard offset.
|
|
62
|
-
vec3 cameraRight = vec3(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
|
|
63
|
-
vec3 cameraUp = vec3(viewMatrix[0][1], viewMatrix[1][1], viewMatrix[2][1]);
|
|
64
|
-
vec3 worldCenter = (modelMatrix * vec4(particleCenter, 1.0)).xyz;
|
|
65
|
-
vWorldPosition = worldCenter + cameraRight * billboardOffset.x + cameraUp * billboardOffset.y;
|
|
66
|
-
|
|
67
|
-
// Standard clip-space projection via the shadow camera.
|
|
68
|
-
vec4 modelViewPosition = modelViewMatrix * vec4(particleCenter, 1.0);
|
|
69
|
-
modelViewPosition.xy += billboardOffset;
|
|
70
|
-
gl_Position = projectionMatrix * modelViewPosition;
|
|
71
|
-
}
|
|
72
|
-
`;
|
|
73
|
-
/**
|
|
74
|
-
* GLSL snippet for spherical distance adjustment.
|
|
75
|
-
*
|
|
76
|
-
* Instead of measuring distance from the flat billboard surface, this
|
|
77
|
-
* approximates the front hemisphere of a sphere. The sphere radius is half
|
|
78
|
-
* the smaller scale dimension. Fragments outside the sphere are discarded.
|
|
79
|
-
*
|
|
80
|
-
* The depth offset is subtracted from the flat distance, bringing the
|
|
81
|
-
* perceived surface closer to the light. This is an approximation - the
|
|
82
|
-
* true offset direction depends on the light-to-fragment vector, not the
|
|
83
|
-
* camera-to-fragment vector - but for smoke particles the error is
|
|
84
|
-
* negligible.
|
|
85
|
-
*/
|
|
86
|
-
const SPHERICAL_DISTANCE_SNIPPET = `
|
|
87
|
-
{
|
|
88
|
-
float sphereOffsetX = (p_uv.x - 0.5) * PARTICLE_SCALE_X;
|
|
89
|
-
float sphereOffsetY = (p_uv.y - 0.5) * PARTICLE_SCALE_Y;
|
|
90
|
-
float sphereRadius = min(PARTICLE_SCALE_X, PARTICLE_SCALE_Y) * 0.5;
|
|
91
|
-
float squaredDistanceFromCenter = sphereOffsetX * sphereOffsetX + sphereOffsetY * sphereOffsetY;
|
|
92
|
-
if (squaredDistanceFromCenter > sphereRadius * sphereRadius) discard;
|
|
93
|
-
float sphereDepthOffset = sqrt(sphereRadius * sphereRadius - squaredDistanceFromCenter);
|
|
94
|
-
dist = max(0.0, dist - sphereDepthOffset);
|
|
95
|
-
}
|
|
96
|
-
`;
|
|
97
|
-
const DISTANCE_CALCULATION_PATTERN = /float\s+dist\s*=\s*length\s*\(\s*vWorldPosition\s*-\s*referencePosition\s*\)\s*;/;
|
|
98
|
-
function buildDistanceMaterial(albedoNodes, distanceAlphaTest, useDistanceAlphaHash, useSphericalDepth) {
|
|
99
|
-
const distanceNodes = albedoNodes.filter((node) => node.affectsDepth);
|
|
100
|
-
const needsFragmentPatch = distanceNodes.length > 0 || useSphericalDepth;
|
|
101
|
-
const material = new MeshDistanceMaterial({
|
|
102
|
-
name: "FXDistanceMaterial",
|
|
103
|
-
side: DoubleSide,
|
|
104
|
-
forceSinglePass: true,
|
|
105
|
-
alphaHash: useDistanceAlphaHash,
|
|
106
|
-
});
|
|
107
|
-
material.onBeforeCompile = (shader) => {
|
|
108
|
-
shader.vertexShader = DISTANCE_VERTEX_SHADER;
|
|
109
|
-
if (!needsFragmentPatch) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const seenCacheKeys = new Set();
|
|
113
|
-
const uniqueHelpers = distanceNodes
|
|
114
|
-
.filter((node) => {
|
|
115
|
-
if (seenCacheKeys.has(node.cacheKey)) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
seenCacheKeys.add(node.cacheKey);
|
|
119
|
-
return true;
|
|
120
|
-
})
|
|
121
|
-
.map((node) => node.helperFunctions)
|
|
122
|
-
.join("\n");
|
|
123
|
-
const fragmentPreamble = [
|
|
124
|
-
PARTICLE_DEFINES,
|
|
125
|
-
"varying mat4 p_builtin;",
|
|
126
|
-
"varying vec2 p_uv;",
|
|
127
|
-
distanceNodes.flatMap((node) => node.uniformDeclarations).join("\n"),
|
|
128
|
-
uniqueHelpers,
|
|
129
|
-
].join("\n");
|
|
130
|
-
for (const node of distanceNodes) {
|
|
131
|
-
Object.assign(shader.uniforms, node.uniforms);
|
|
132
|
-
}
|
|
133
|
-
let fragmentShader = shader.fragmentShader;
|
|
134
|
-
// Alpha from nodes - MeshDistanceMaterial may or may not include
|
|
135
|
-
// <map_fragment> depending on the Three.js version. If the chunk is
|
|
136
|
-
// absent, insert the alpha discard before the distance calculation.
|
|
137
|
-
if (distanceNodes.length > 0) {
|
|
138
|
-
const albedoLines = ["vec4 fxDistAlbedo = vec4(1.0);"];
|
|
139
|
-
for (const node of distanceNodes) {
|
|
140
|
-
albedoLines.push(`fxDistAlbedo = ${node.colorExpression.replace(CURRENT_EXPRESSION_VALUE_PLACEHOLDER, "fxDistAlbedo")};`);
|
|
141
|
-
}
|
|
142
|
-
albedoLines.push(`float nodeAlpha = fxDistAlbedo.a;`);
|
|
143
|
-
const alphaDiscardCode = albedoLines.join("\n") + `\nif (nodeAlpha < ${distanceAlphaTest.toFixed(4)}) discard;`;
|
|
144
|
-
if (fragmentShader.includes("#include <map_fragment>")) {
|
|
145
|
-
fragmentShader = fragmentShader.replace("#include <map_fragment>", alphaDiscardCode);
|
|
146
|
-
}
|
|
147
|
-
else if (DISTANCE_CALCULATION_PATTERN.test(fragmentShader)) {
|
|
148
|
-
// Fallback: inject alpha discard just before the distance calculation.
|
|
149
|
-
fragmentShader = fragmentShader.replace(DISTANCE_CALCULATION_PATTERN, (match) => alphaDiscardCode + "\n" + match);
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
console.warn("FXDistanceMaterial: could not find a suitable injection point for alpha discard. " +
|
|
153
|
-
"This may indicate a Three.js version mismatch.");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
// Spherical distance adjustment - offset the flat-billboard distance by
|
|
157
|
-
// the sphere's front surface depth.
|
|
158
|
-
if (useSphericalDepth) {
|
|
159
|
-
if (!DISTANCE_CALCULATION_PATTERN.test(fragmentShader)) {
|
|
160
|
-
console.warn("FXDistanceMaterial: could not find the distance calculation line. " +
|
|
161
|
-
"Spherical depth will not be applied. " +
|
|
162
|
-
"This may indicate a Three.js version mismatch.");
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
// Inject the spherical adjustment right after the distance calculation.
|
|
166
|
-
fragmentShader = fragmentShader.replace(DISTANCE_CALCULATION_PATTERN, (match) => match + "\n" + SPHERICAL_DISTANCE_SNIPPET);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
shader.fragmentShader = fragmentPreamble + "\n" + fragmentShader;
|
|
170
|
-
};
|
|
171
|
-
material.customProgramCacheKey = () => `fx-distance-${useDistanceAlphaHash ? "alphaHash" : "alphaTest"}-${useSphericalDepth ? "spherical" : "flat"}-${distanceNodes.map((node) => node.cacheKey).join("-") || "none"}`;
|
|
172
|
-
return material;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export { buildDistanceMaterial };
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
2
|
-
import { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
3
|
-
/**
|
|
4
|
-
* Per-particle blend mode used when compositing particles into the scene
|
|
5
|
-
*/
|
|
6
|
-
export declare enum FXBlending {
|
|
7
|
-
/**
|
|
8
|
-
* Premultiplied additive blend - particle color is pre-multiplied by alpha and added to the
|
|
9
|
-
* destination with zero alpha contribution
|
|
10
|
-
*/
|
|
11
|
-
MASKED_ADDITIVE = 0,
|
|
12
|
-
/**
|
|
13
|
-
* Luminance-aware multiply blend - dark areas darken the destination while bright areas
|
|
14
|
-
* normal-blend through a mask
|
|
15
|
-
*/
|
|
16
|
-
MASKED_MULTIPLY = 1
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Configuration options shared by all {@link FXMaterial} subclasses
|
|
20
|
-
*/
|
|
21
|
-
export interface FXMaterialOptions {
|
|
22
|
-
/**
|
|
23
|
-
* Color and texture nodes composited for particle color
|
|
24
|
-
*
|
|
25
|
-
* @defaultValue `[]`
|
|
26
|
-
*/
|
|
27
|
-
albedoNodes: (FXNodeColor | FXNodeTexture)[];
|
|
28
|
-
blending: FXBlending;
|
|
29
|
-
/**
|
|
30
|
-
* Use alpha hashing instead of standard transparency
|
|
31
|
-
*
|
|
32
|
-
* @defaultValue `false`
|
|
33
|
-
*/
|
|
34
|
-
useAlphaHashing: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Alpha cutoff threshold for color passes
|
|
37
|
-
*
|
|
38
|
-
* @defaultValue `0.0075`
|
|
39
|
-
*/
|
|
40
|
-
alphaTest: number;
|
|
41
|
-
/**
|
|
42
|
-
* Alpha cutoff threshold for depth and shadow passes
|
|
43
|
-
*
|
|
44
|
-
* @defaultValue `0.5`
|
|
45
|
-
*/
|
|
46
|
-
depthAlphaTest: number;
|
|
47
|
-
/**
|
|
48
|
-
* Use alpha hashing in depth and shadow passes
|
|
49
|
-
*
|
|
50
|
-
* @defaultValue `false`
|
|
51
|
-
*/
|
|
52
|
-
useDepthAlphaHash: boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Approximate spherical depth for shadow maps
|
|
55
|
-
*
|
|
56
|
-
* @defaultValue `true`
|
|
57
|
-
*/
|
|
58
|
-
useSphericalDepth: boolean;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Abstract base class for particle materials
|
|
62
|
-
*/
|
|
63
|
-
export declare abstract class FXMaterial {
|
|
64
|
-
private readonly depthAlphaTest;
|
|
65
|
-
private readonly useDepthAlphaHash;
|
|
66
|
-
private readonly useSphericalDepth;
|
|
67
|
-
constructor(options?: Partial<FXMaterialOptions>);
|
|
68
|
-
/** Releases resources held by all albedo nodes */
|
|
69
|
-
destroy(): void;
|
|
70
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { FXNodeColor } from '../../nodes/color/FXNodeColor.js';
|
|
2
|
-
import { FXNodeTexture } from '../../nodes/texture/FXNodeTexture.js';
|
|
3
|
-
import { buildDepthMaterial } from './FXDepthMaterial.Internal.js';
|
|
4
|
-
import { buildDistanceMaterial } from './FXDistanceMaterial.Internal.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Per-particle blend mode used when compositing particles into the scene
|
|
8
|
-
*/
|
|
9
|
-
var FXBlending;
|
|
10
|
-
(function (FXBlending) {
|
|
11
|
-
/**
|
|
12
|
-
* Premultiplied additive blend - particle color is pre-multiplied by alpha and added to the
|
|
13
|
-
* destination with zero alpha contribution
|
|
14
|
-
*/
|
|
15
|
-
FXBlending[FXBlending["MASKED_ADDITIVE"] = 0] = "MASKED_ADDITIVE";
|
|
16
|
-
/**
|
|
17
|
-
* Luminance-aware multiply blend - dark areas darken the destination while bright areas
|
|
18
|
-
* normal-blend through a mask
|
|
19
|
-
*/
|
|
20
|
-
FXBlending[FXBlending["MASKED_MULTIPLY"] = 1] = "MASKED_MULTIPLY";
|
|
21
|
-
})(FXBlending || (FXBlending = {}));
|
|
22
|
-
/**
|
|
23
|
-
* Abstract base class for particle materials
|
|
24
|
-
*/
|
|
25
|
-
class FXMaterial {
|
|
26
|
-
constructor(options = {}) {
|
|
27
|
-
this.albedoNodes = options.albedoNodes ?? [];
|
|
28
|
-
this.blending = options.blending ?? FXBlending.MASKED_ADDITIVE;
|
|
29
|
-
this.useAlphaHashing = options.useAlphaHashing ?? false;
|
|
30
|
-
this.alphaTest = options.alphaTest ?? 0.0075;
|
|
31
|
-
this._private_depthAlphaTest = options.depthAlphaTest ?? 0.5;
|
|
32
|
-
this._private_useDepthAlphaHash = options.useDepthAlphaHash ?? false;
|
|
33
|
-
this._private_useSphericalDepth = options.useSphericalDepth ?? true;
|
|
34
|
-
}
|
|
35
|
-
/** Releases resources held by all albedo nodes */
|
|
36
|
-
destroy() {
|
|
37
|
-
for (const node of this.albedoNodes) {
|
|
38
|
-
node.destroy?.();
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/** @internal */
|
|
42
|
-
buildDepthMaterial() {
|
|
43
|
-
return buildDepthMaterial(this.albedoNodes.filter((node) => node instanceof FXNodeColor || node instanceof FXNodeTexture), this._private_depthAlphaTest, this._private_useDepthAlphaHash, this._private_useSphericalDepth);
|
|
44
|
-
}
|
|
45
|
-
/** @internal */
|
|
46
|
-
buildDistanceMaterial() {
|
|
47
|
-
return buildDistanceMaterial(this.albedoNodes.filter((node) => node instanceof FXNodeColor || node instanceof FXNodeTexture), this._private_depthAlphaTest, this._private_useDepthAlphaHash, this._private_useSphericalDepth);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export { FXBlending, FXMaterial };
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { MeshBasicMaterial } from "three";
|
|
2
|
-
import type { GLTypeInfo } from "../../instancedParticle/shared";
|
|
3
|
-
import type { FXNodeBlending } from "../../nodes/blending/FXNodeBlending";
|
|
4
|
-
import type { FXNodeColor } from "../../nodes/color/FXNodeColor";
|
|
5
|
-
import type { FXNodeTexture } from "../../nodes/texture/FXNodeTexture";
|
|
6
|
-
import { FXBlending } from "../FXMaterial/FXMaterial";
|
|
7
|
-
export declare function buildFXUnlitMaterial(varyings: Record<string, GLTypeInfo>, blending: FXBlending, useAlphaHashing: boolean, alphaTest: number, albedoNodes: readonly (FXNodeColor | FXNodeTexture | FXNodeBlending)[]): MeshBasicMaterial;
|