@needle-tools/engine 5.1.0-alpha → 5.1.0-alpha.2
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/.needle/generated/needle-bindings.gen.d.ts +5 -0
- package/CHANGELOG.md +27 -1
- package/SKILL.md +39 -21
- package/components.needle.json +1 -1
- package/dist/{gltf-progressive-DJBMx-zB.umd.cjs → gltf-progressive-BmblPzFj.umd.cjs} +4 -4
- package/dist/{gltf-progressive-BryRjllq.min.js → gltf-progressive-CN_mbb66.min.js} +2 -2
- package/dist/{gltf-progressive-Cl167Vjx.js → gltf-progressive-DUlhxdv4.js} +5 -2
- package/dist/{needle-engine.bundle-qDahLTqW.min.js → needle-engine.bundle-B-5Q2CpC.min.js} +249 -173
- package/dist/{needle-engine.bundle-CwhCzjep.js → needle-engine.bundle-dit3f1l5.js} +13238 -12724
- package/dist/{needle-engine.bundle-wM-BWPX9.umd.cjs → needle-engine.bundle-qZfVf_v-.umd.cjs} +250 -174
- package/dist/needle-engine.d.ts +295 -31
- package/dist/needle-engine.js +569 -563
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/dist/{postprocessing-B_9sKVU7.min.js → postprocessing-B571qGWR.min.js} +34 -34
- package/dist/{postprocessing-WDc9WwI3.js → postprocessing-CfrLAbLX.js} +0 -1
- package/dist/{postprocessing-B2wb6pzI.umd.cjs → postprocessing-CiGkAeM9.umd.cjs} +17 -17
- package/dist/{vendor-CAcsI0eU.js → vendor-BFrMaK9q.js} +8983 -9136
- package/dist/vendor-CJmyOrCq.min.js +1116 -0
- package/dist/vendor-DkMW3WY4.umd.cjs +1116 -0
- package/lib/engine/api.d.ts +12 -0
- package/lib/engine/api.js +2 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/debug/debug_environment.js +1 -1
- package/lib/engine/debug/debug_environment.js.map +1 -1
- package/lib/engine/engine_application.js +8 -6
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_components.js +5 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_constants.js +6 -0
- package/lib/engine/engine_constants.js.map +1 -1
- package/lib/engine/engine_context.d.ts +33 -7
- package/lib/engine/engine_context.js +40 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.js +1 -1
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_init.js +7 -0
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +3 -2
- package/lib/engine/engine_input.js +3 -2
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_license.d.ts +2 -0
- package/lib/engine/engine_license.js +25 -15
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_lifecycle_functions_internal.js +5 -0
- package/lib/engine/engine_lifecycle_functions_internal.js.map +1 -1
- package/lib/engine/engine_networking_blob.d.ts +1 -1
- package/lib/engine/engine_networking_blob.js +5 -11
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +3 -0
- package/lib/engine/engine_physics_rapier.js +13 -10
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_pmrem.js +2 -2
- package/lib/engine/engine_pmrem.js.map +1 -1
- package/lib/engine/engine_scenedata.d.ts +30 -0
- package/lib/engine/engine_scenedata.js +136 -0
- package/lib/engine/engine_scenedata.js.map +1 -0
- package/lib/engine/engine_ssr.d.ts +18 -0
- package/lib/engine/engine_ssr.js +40 -0
- package/lib/engine/engine_ssr.js.map +1 -0
- package/lib/engine/engine_three_utils.d.ts +14 -7
- package/lib/engine/engine_three_utils.js +14 -7
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_types.d.ts +2 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.js +4 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/engine_utils_hash.d.ts +9 -0
- package/lib/engine/engine_utils_hash.js +112 -0
- package/lib/engine/engine_utils_hash.js.map +1 -0
- package/lib/engine/webcomponents/jsx.d.ts +51 -0
- package/lib/engine/webcomponents/logo-element.d.ts +2 -1
- package/lib/engine/webcomponents/logo-element.js +2 -1
- package/lib/engine/webcomponents/logo-element.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +4 -4
- package/lib/engine/webcomponents/needle menu/needle-menu.js +2 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-button.d.ts +2 -1
- package/lib/engine/webcomponents/needle-button.js +2 -1
- package/lib/engine/webcomponents/needle-button.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +2 -1
- package/lib/engine/webcomponents/needle-engine.js +2 -1
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.d.ts +1 -0
- package/lib/engine/xr/NeedleXRSession.js +5 -5
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine/xr/events.d.ts +30 -3
- package/lib/engine/xr/events.js +38 -0
- package/lib/engine/xr/events.js.map +1 -1
- package/lib/engine/xr/init.js +1 -7
- package/lib/engine/xr/init.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +135 -2
- package/lib/engine-components/AnimatorController.js +218 -2
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/GroundProjection.d.ts +1 -0
- package/lib/engine-components/GroundProjection.js +184 -48
- package/lib/engine-components/GroundProjection.js.map +1 -1
- package/lib/engine-components/Light.d.ts +6 -8
- package/lib/engine-components/Light.js +40 -27
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/RigidBody.js +3 -3
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +2 -0
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -0
- package/lib/engine-components/api.js +1 -0
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/BloomEffect.d.ts +1 -1
- package/lib/engine-components/postprocessing/Effects/Sharpening.js +1 -2
- package/lib/engine-components/postprocessing/Effects/Sharpening.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +5 -6
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/web/ScrollFollow.d.ts +0 -1
- package/lib/engine-components/web/ScrollFollow.js +3 -2
- package/lib/engine-components/web/ScrollFollow.js.map +1 -1
- package/lib/needle-engine.d.ts +2 -0
- package/lib/needle-engine.js +2 -0
- package/lib/needle-engine.js.map +1 -1
- package/package.json +6 -4
- package/plugins/common/logger.js +42 -19
- package/plugins/dts-generator/dts.codegen.js +334 -0
- package/plugins/dts-generator/dts.scan.js +99 -0
- package/plugins/dts-generator/dts.writer.js +59 -0
- package/plugins/dts-generator/glb.discovery.js +279 -0
- package/plugins/dts-generator/glb.extractor.js +215 -0
- package/plugins/dts-generator/glb.reader.js +167 -0
- package/plugins/dts-generator/index.js +36 -0
- package/plugins/dts-generator/manifest.types.js +174 -0
- package/plugins/types/index.d.ts +2 -1
- package/plugins/types/needle-bindings.d.ts +30 -0
- package/plugins/types/userconfig.d.ts +21 -2
- package/plugins/vite/asap.js +1 -1
- package/plugins/vite/dependency-watcher.d.ts +2 -2
- package/plugins/vite/dependency-watcher.js +3 -4
- package/plugins/vite/drop.d.ts +2 -2
- package/plugins/vite/drop.js +3 -4
- package/plugins/vite/dts-generator.d.ts +7 -0
- package/plugins/vite/dts-generator.js +191 -0
- package/plugins/vite/index.d.ts +10 -3
- package/plugins/vite/index.js +27 -10
- package/plugins/vite/logger.client.js +4 -3
- package/plugins/vite/logging.js +2 -2
- package/plugins/vite/meta.js +4 -2
- package/plugins/vite/poster.d.ts +2 -2
- package/plugins/vite/poster.js +3 -5
- package/plugins/vite/reload.d.ts +2 -2
- package/plugins/vite/reload.js +23 -22
- package/src/engine/api.ts +15 -1
- package/src/engine/debug/debug_environment.ts +1 -1
- package/src/engine/engine_application.ts +8 -6
- package/src/engine/engine_components.ts +7 -4
- package/src/engine/engine_constants.ts +11 -6
- package/src/engine/engine_context.ts +50 -7
- package/src/engine/engine_context_registry.ts +1 -1
- package/src/engine/engine_init.ts +6 -0
- package/src/engine/engine_input.ts +3 -2
- package/src/engine/engine_license.ts +23 -19
- package/src/engine/engine_lifecycle_functions_internal.ts +7 -0
- package/src/engine/engine_networking_blob.ts +5 -11
- package/src/engine/engine_physics_rapier.ts +14 -12
- package/src/engine/engine_pmrem.ts +3 -3
- package/src/engine/engine_scenedata.ts +134 -0
- package/src/engine/engine_ssr.ts +48 -0
- package/src/engine/engine_three_utils.ts +15 -7
- package/src/engine/engine_types.ts +2 -0
- package/src/engine/engine_utils.ts +3 -2
- package/src/engine/engine_utils_hash.ts +65 -0
- package/src/engine/webcomponents/jsx.d.ts +51 -0
- package/src/engine/webcomponents/logo-element.ts +3 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +4 -2
- package/src/engine/webcomponents/needle-button.ts +3 -1
- package/src/engine/webcomponents/needle-engine.ts +3 -1
- package/src/engine/xr/NeedleXRSession.ts +6 -6
- package/src/engine/xr/events.ts +44 -1
- package/src/engine/xr/init.ts +0 -7
- package/src/engine-components/AnimatorController.ts +286 -4
- package/src/engine-components/GroundProjection.ts +226 -52
- package/src/engine-components/Light.ts +40 -26
- package/src/engine-components/RigidBody.ts +3 -3
- package/src/engine-components/SceneSwitcher.ts +1 -0
- package/src/engine-components/api.ts +1 -0
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +1 -1
- package/src/engine-components/postprocessing/Effects/Sharpening.ts +1 -2
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +4 -8
- package/src/engine-components/web/ScrollFollow.ts +2 -2
- package/src/needle-engine.ts +3 -0
- package/src/vite-env.d.ts +16 -0
- package/dist/vendor-CEM38hLE.umd.cjs +0 -1116
- package/dist/vendor-HRlxIBga.min.js +0 -1116
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ShaderMaterial, Texture } from "three";
|
|
1
|
+
import { CubeUVReflectionMapping, ShaderMaterial, Texture } from "three";
|
|
2
2
|
import { GroundedSkybox as GroundProjection } from 'three/examples/jsm/objects/GroundedSkybox.js';
|
|
3
3
|
|
|
4
4
|
import { Gizmos } from "../engine/engine_gizmos.js";
|
|
@@ -12,6 +12,174 @@ import type { ContactShadows } from "./ContactShadows.js";
|
|
|
12
12
|
|
|
13
13
|
const debug = getParam("debuggroundprojection");
|
|
14
14
|
|
|
15
|
+
type GroundProjectionMaterial = GroundProjection["material"] & {
|
|
16
|
+
defines?: Record<string, string | number>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type GroundProjectionShaderUniforms = {
|
|
20
|
+
needleGroundProjectionBlurriness: { value: number };
|
|
21
|
+
needleGroundProjectionBlending: { value: number };
|
|
22
|
+
needleGroundProjectionAlphaFactor: { value: number };
|
|
23
|
+
needleGroundProjectionBackgroundIntensity: { value: number };
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const needleCubeUvMapVarying = /* glsl */`
|
|
27
|
+
#ifdef NEEDLE_USE_CUBE_UV_MAP
|
|
28
|
+
varying vec3 vNeedleGroundProjectionWorldDirection;
|
|
29
|
+
#endif
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
const needleGroundProjectionFragmentPars = /* glsl */`
|
|
33
|
+
${needleCubeUvMapVarying}
|
|
34
|
+
uniform float needleGroundProjectionBlurriness;
|
|
35
|
+
uniform float needleGroundProjectionBlending;
|
|
36
|
+
uniform float needleGroundProjectionAlphaFactor;
|
|
37
|
+
uniform float needleGroundProjectionBackgroundIntensity;
|
|
38
|
+
|
|
39
|
+
float needleGroundProjectionSmoothstep(float edge0, float edge1, float x) {
|
|
40
|
+
float t = clamp((x - edge0) / max(edge1 - edge0, 0.000001), 0.0, 1.0);
|
|
41
|
+
return t * t * (3.0 - 2.0 * t);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
float needleGroundProjectionDistance() {
|
|
45
|
+
return length(vec2(0.0, vMapUv.y));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
float needleGroundProjectionBlurFactor(float needleGroundProjectionDistanceValue) {
|
|
49
|
+
return clamp(needleGroundProjectionSmoothstep(0.5, 1.0, needleGroundProjectionDistanceValue * 2.0), 0.0, 1.0);
|
|
50
|
+
}
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const needleCubeUvMapFragment = /* glsl */`
|
|
54
|
+
#ifdef USE_MAP
|
|
55
|
+
|
|
56
|
+
float needleGroundProjectionDistanceValue = needleGroundProjectionDistance();
|
|
57
|
+
float needleGroundProjectionBlurFactorValue = needleGroundProjectionBlurFactor(needleGroundProjectionDistanceValue);
|
|
58
|
+
vec4 sampledDiffuseColor;
|
|
59
|
+
|
|
60
|
+
#ifdef NEEDLE_USE_CUBE_UV_MAP
|
|
61
|
+
sampledDiffuseColor = textureCubeUV(
|
|
62
|
+
map,
|
|
63
|
+
normalize( vNeedleGroundProjectionWorldDirection ),
|
|
64
|
+
needleGroundProjectionBlurriness * needleGroundProjectionBlurFactorValue
|
|
65
|
+
);
|
|
66
|
+
#else
|
|
67
|
+
#ifdef USE_MIPMAP_BIAS
|
|
68
|
+
sampledDiffuseColor = texture2D( map, vMapUv, mipmapBias );
|
|
69
|
+
#else
|
|
70
|
+
sampledDiffuseColor = texture2D( map, vMapUv );
|
|
71
|
+
#endif
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
#ifdef DECODE_VIDEO_TEXTURE
|
|
75
|
+
|
|
76
|
+
// use inline sRGB decode until browsers properly support SRGB8_ALPHA8 with video textures (#26516)
|
|
77
|
+
|
|
78
|
+
sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );
|
|
79
|
+
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
sampledDiffuseColor.rgb *= mix(1.0, needleGroundProjectionBackgroundIntensity, needleGroundProjectionBlurFactorValue);
|
|
83
|
+
diffuseColor *= sampledDiffuseColor;
|
|
84
|
+
|
|
85
|
+
#endif
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
const needleGroundProjectionAlphaFragment = /* glsl */`
|
|
89
|
+
#ifdef USE_MAP
|
|
90
|
+
if (needleGroundProjectionBlending > 0.000001) {
|
|
91
|
+
float needleGroundProjectionBrightness = dot(diffuseColor.rgb, vec3(0.299, 0.587, 0.114));
|
|
92
|
+
float needleGroundProjectionStepFactor = needleGroundProjectionBlending - needleGroundProjectionBrightness * 0.1;
|
|
93
|
+
diffuseColor.a *= pow(
|
|
94
|
+
1.0 - needleGroundProjectionBlending * needleGroundProjectionSmoothstep(
|
|
95
|
+
0.35 * needleGroundProjectionStepFactor,
|
|
96
|
+
0.45 * needleGroundProjectionStepFactor,
|
|
97
|
+
needleGroundProjectionDistanceValue
|
|
98
|
+
),
|
|
99
|
+
5.0
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
#endif
|
|
103
|
+
diffuseColor.a *= needleGroundProjectionAlphaFactor;
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
function getCubeUvSize(texture: Texture) {
|
|
107
|
+
const imageHeight = texture.image?.height;
|
|
108
|
+
if (!imageHeight) return null;
|
|
109
|
+
|
|
110
|
+
const maxMip = Math.log2(imageHeight) - 2;
|
|
111
|
+
const texelHeight = 1 / imageHeight;
|
|
112
|
+
const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16));
|
|
113
|
+
return { texelWidth, texelHeight, maxMip };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function getGroundProjectionShaderUniforms(material: GroundProjectionMaterial): GroundProjectionShaderUniforms {
|
|
117
|
+
const userData = material.userData as GroundProjectionMaterial["userData"] & {
|
|
118
|
+
needleGroundProjectionUniforms?: GroundProjectionShaderUniforms;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
return userData.needleGroundProjectionUniforms ??= {
|
|
122
|
+
needleGroundProjectionBlurriness: { value: 0 },
|
|
123
|
+
needleGroundProjectionBlending: { value: 0 },
|
|
124
|
+
needleGroundProjectionAlphaFactor: { value: 1 },
|
|
125
|
+
needleGroundProjectionBackgroundIntensity: { value: 1 }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function configureGroundProjectionMaterial(material: GroundProjectionMaterial, texture: Texture) {
|
|
130
|
+
const projectionUniforms = getGroundProjectionShaderUniforms(material);
|
|
131
|
+
material.onBeforeCompile = shader => {
|
|
132
|
+
shader.uniforms.needleGroundProjectionBlurriness = projectionUniforms.needleGroundProjectionBlurriness;
|
|
133
|
+
shader.uniforms.needleGroundProjectionBlending = projectionUniforms.needleGroundProjectionBlending;
|
|
134
|
+
shader.uniforms.needleGroundProjectionAlphaFactor = projectionUniforms.needleGroundProjectionAlphaFactor;
|
|
135
|
+
shader.uniforms.needleGroundProjectionBackgroundIntensity = projectionUniforms.needleGroundProjectionBackgroundIntensity;
|
|
136
|
+
|
|
137
|
+
shader.vertexShader = shader.vertexShader
|
|
138
|
+
.replace("#include <uv_pars_vertex>", `#include <uv_pars_vertex>\n${needleCubeUvMapVarying}`)
|
|
139
|
+
.replace(
|
|
140
|
+
"#include <worldpos_vertex>",
|
|
141
|
+
`#include <worldpos_vertex>
|
|
142
|
+
#ifdef NEEDLE_USE_CUBE_UV_MAP
|
|
143
|
+
// GroundedSkybox mirrors geometry on Z, so undo that before deriving the sampling direction.
|
|
144
|
+
vNeedleGroundProjectionWorldDirection = transformDirection( vec3( position.x, position.y, -position.z ), modelMatrix );
|
|
145
|
+
#endif`
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
shader.fragmentShader = shader.fragmentShader
|
|
149
|
+
.replace(
|
|
150
|
+
"#include <map_pars_fragment>",
|
|
151
|
+
`#include <map_pars_fragment>
|
|
152
|
+
${needleGroundProjectionFragmentPars}
|
|
153
|
+
#include <cube_uv_reflection_fragment>`
|
|
154
|
+
)
|
|
155
|
+
.replace("#include <map_fragment>", needleCubeUvMapFragment)
|
|
156
|
+
.replace("#include <opaque_fragment>", `${needleGroundProjectionAlphaFragment}\n#include <opaque_fragment>`);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const defines = material.defines ??= {};
|
|
160
|
+
const prevDefineState = JSON.stringify(defines);
|
|
161
|
+
const cubeUvSize = texture.mapping === CubeUVReflectionMapping ? getCubeUvSize(texture) : null;
|
|
162
|
+
|
|
163
|
+
if (cubeUvSize) {
|
|
164
|
+
defines.NEEDLE_USE_CUBE_UV_MAP = 1;
|
|
165
|
+
defines.ENVMAP_TYPE_CUBE_UV = 1;
|
|
166
|
+
defines.CUBEUV_TEXEL_WIDTH = cubeUvSize.texelWidth;
|
|
167
|
+
defines.CUBEUV_TEXEL_HEIGHT = cubeUvSize.texelHeight;
|
|
168
|
+
defines.CUBEUV_MAX_MIP = `${cubeUvSize.maxMip}.0`;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
delete defines.NEEDLE_USE_CUBE_UV_MAP;
|
|
172
|
+
delete defines.ENVMAP_TYPE_CUBE_UV;
|
|
173
|
+
delete defines.CUBEUV_TEXEL_WIDTH;
|
|
174
|
+
delete defines.CUBEUV_TEXEL_HEIGHT;
|
|
175
|
+
delete defines.CUBEUV_MAX_MIP;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (prevDefineState !== JSON.stringify(defines)) {
|
|
179
|
+
material.needsUpdate = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
15
183
|
/**
|
|
16
184
|
* The [GroundProjectedEnv](https://engine.needle.tools/docs/api/GroundProjectedEnv) projects the environment map onto a virtual ground plane.
|
|
17
185
|
* Creates a realistic floor from 360° panoramas/HDRIs by deforming the skybox
|
|
@@ -147,12 +315,10 @@ export class GroundProjectedEnv extends Behaviour {
|
|
|
147
315
|
this._projection.rotation.copy(this.scene.backgroundRotation);
|
|
148
316
|
}
|
|
149
317
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.
|
|
153
|
-
|
|
154
|
-
else if (this._needsTextureUpdate && this.context.scene.background instanceof Texture) {
|
|
155
|
-
this.updateBlurriness(this.context.scene.background, this.context.scene.backgroundBlurriness);
|
|
318
|
+
if (this._projection && this.context.scene.background instanceof Texture) {
|
|
319
|
+
const blurriness = this.context.scene.backgroundBlurriness ?? 0;
|
|
320
|
+
const blurrinessChanged = this._lastBlurriness !== blurriness;
|
|
321
|
+
this.updateProjectionMaterial(this.context.scene.background, blurrinessChanged || this._needsTextureUpdate);
|
|
156
322
|
}
|
|
157
323
|
}
|
|
158
324
|
|
|
@@ -202,6 +368,7 @@ export class GroundProjectedEnv extends Behaviour {
|
|
|
202
368
|
|
|
203
369
|
try {
|
|
204
370
|
this._projection = new GroundProjection(backgroundTexture, this._height, this._radius, 64);
|
|
371
|
+
configureGroundProjectionMaterial(this._projection.material, backgroundTexture);
|
|
205
372
|
}
|
|
206
373
|
catch (e) {
|
|
207
374
|
console.error("Error creating three GroundProjection", e);
|
|
@@ -242,9 +409,7 @@ export class GroundProjectedEnv extends Behaviour {
|
|
|
242
409
|
this.env.height = this._height;
|
|
243
410
|
*/
|
|
244
411
|
|
|
245
|
-
|
|
246
|
-
this.updateBlurriness(backgroundTexture, this.context.scene.backgroundBlurriness);
|
|
247
|
-
}
|
|
412
|
+
this.updateProjectionMaterial(backgroundTexture, true);
|
|
248
413
|
|
|
249
414
|
this._lastBackground = backgroundTexture;
|
|
250
415
|
this._lastHeight = this._height;
|
|
@@ -254,24 +419,60 @@ export class GroundProjectedEnv extends Behaviour {
|
|
|
254
419
|
|
|
255
420
|
private _blurrynessShader: ShaderMaterial | null = null;
|
|
256
421
|
private _lastBlurriness: number = -1;
|
|
257
|
-
|
|
258
|
-
private
|
|
422
|
+
|
|
423
|
+
private updateProjectionMaterial(texture: Texture, forceTextureUpdate = false) {
|
|
259
424
|
if (!this._projection) {
|
|
260
425
|
return;
|
|
261
426
|
}
|
|
262
|
-
|
|
263
|
-
|
|
427
|
+
|
|
428
|
+
const blurriness = this.context.scene.backgroundBlurriness ?? 0;
|
|
429
|
+
const useCubeUvBlur = texture.mapping === CubeUVReflectionMapping;
|
|
430
|
+
|
|
431
|
+
let targetTexture = texture;
|
|
432
|
+
if (!useCubeUvBlur && blurriness > 0.001) {
|
|
433
|
+
const hasBlurredTextureAssigned = !!this._projection.material.map && this._projection.material.map !== texture;
|
|
434
|
+
if (forceTextureUpdate || !hasBlurredTextureAssigned) {
|
|
435
|
+
targetTexture = this.updateBlurriness(texture, blurriness);
|
|
436
|
+
}
|
|
437
|
+
else if (this._projection.material.map) {
|
|
438
|
+
targetTexture = this._projection.material.map;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (this._projection.material.map !== targetTexture) {
|
|
443
|
+
this._projection.material.map = targetTexture;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const appliedTexture = this._projection.material.map ?? texture;
|
|
447
|
+
appliedTexture.mapping = texture.mapping;
|
|
448
|
+
configureGroundProjectionMaterial(this._projection.material, appliedTexture);
|
|
449
|
+
|
|
450
|
+
const shaderUniforms = getGroundProjectionShaderUniforms(this._projection.material);
|
|
451
|
+
shaderUniforms.needleGroundProjectionBlurriness.value = useCubeUvBlur ? blurriness : 0;
|
|
452
|
+
shaderUniforms.needleGroundProjectionBackgroundIntensity.value = this.context.scene.backgroundIntensity ?? 1;
|
|
453
|
+
|
|
454
|
+
const wasTransparent = this._projection.material.transparent;
|
|
455
|
+
this._projection.material.transparent = (this.context.xr?.isAR === true && this.arBlending > 0.000001) ?? false;
|
|
456
|
+
shaderUniforms.needleGroundProjectionBlending.value = this._projection.material.transparent ? this.arBlending : 0;
|
|
457
|
+
shaderUniforms.needleGroundProjectionAlphaFactor.value = this.context.isInPassThrough ? 0.95 : 1;
|
|
458
|
+
|
|
459
|
+
if (wasTransparent !== this._projection.material.transparent) {
|
|
460
|
+
this._projection.material.needsUpdate = true;
|
|
264
461
|
}
|
|
265
462
|
|
|
463
|
+
this._projection.material.depthTest = true;
|
|
464
|
+
this._projection.material.depthWrite = false;
|
|
465
|
+
this._lastBlurriness = blurriness;
|
|
266
466
|
this._needsTextureUpdate = false;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
private updateBlurriness(texture: Texture, blurriness: number): Texture {
|
|
267
470
|
if (debug) console.log("Update Blurriness", blurriness);
|
|
268
471
|
this._blurrynessShader ??= new ShaderMaterial({
|
|
269
472
|
name: "GroundProjectionBlurriness",
|
|
270
473
|
uniforms: {
|
|
271
474
|
map: { value: texture },
|
|
272
|
-
blurriness: { value: blurriness }
|
|
273
|
-
blending: { value: 0 },
|
|
274
|
-
alphaFactor: { value: 1 }
|
|
475
|
+
blurriness: { value: blurriness }
|
|
275
476
|
},
|
|
276
477
|
vertexShader: blurVertexShader,
|
|
277
478
|
fragmentShader: blurFragmentShader
|
|
@@ -279,33 +480,10 @@ export class GroundProjectedEnv extends Behaviour {
|
|
|
279
480
|
this._blurrynessShader.depthWrite = false;
|
|
280
481
|
this._blurrynessShader.uniforms.map.value = texture;
|
|
281
482
|
this._blurrynessShader.uniforms.blurriness.value = blurriness;
|
|
282
|
-
this._lastBlurriness = blurriness;
|
|
283
483
|
texture.needsUpdate = true;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (this._projection.material.transparent) {
|
|
288
|
-
this._blurrynessShader.uniforms.blending.value = this.arBlending;
|
|
289
|
-
}
|
|
290
|
-
else { this._blurrynessShader.uniforms.blending.value = 0; }
|
|
291
|
-
|
|
292
|
-
if (this.context.isInPassThrough) {
|
|
293
|
-
// Make the ground slightly transparent in passthrough mode
|
|
294
|
-
this._blurrynessShader.uniforms.alphaFactor.value = 0.95;
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
this._blurrynessShader.uniforms.alphaFactor.value = 1;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Make sure the material is updated if the transparency changed
|
|
301
|
-
if (wasTransparent !== this._projection.material.transparent) {
|
|
302
|
-
this._projection.material.needsUpdate = true;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Update the texture
|
|
306
|
-
this._projection.material.map = Graphics.copyTexture(texture, this._blurrynessShader);
|
|
307
|
-
this._projection.material.depthTest = true;
|
|
308
|
-
this._projection.material.depthWrite = false;
|
|
484
|
+
const blurredTexture = Graphics.copyTexture(texture, this._blurrynessShader);
|
|
485
|
+
blurredTexture.mapping = texture.mapping;
|
|
486
|
+
return blurredTexture;
|
|
309
487
|
}
|
|
310
488
|
|
|
311
489
|
}
|
|
@@ -324,8 +502,6 @@ const blurVertexShader = `
|
|
|
324
502
|
const blurFragmentShader = `
|
|
325
503
|
uniform sampler2D map;
|
|
326
504
|
uniform float blurriness;
|
|
327
|
-
uniform float alphaFactor;
|
|
328
|
-
uniform float blending;
|
|
329
505
|
varying vec2 vUv;
|
|
330
506
|
|
|
331
507
|
const float PI = 3.14159265359;
|
|
@@ -356,6 +532,10 @@ const blurFragmentShader = `
|
|
|
356
532
|
vec4 color = vec4(0.0);
|
|
357
533
|
float totalWeight = 0.0;
|
|
358
534
|
int blurSize = int(60.0 * min(1.0, blurriness) * blurAmount); // Adjust blur size based on distance and blurriness
|
|
535
|
+
if (blurSize <= 0) {
|
|
536
|
+
gl_FragColor = texture2D(map, vUv);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
359
539
|
float lodLevel = log2(float(blurSize)) * 0.5; // Compute LOD level
|
|
360
540
|
|
|
361
541
|
for (int x = -blurSize; x <= blurSize; x++) {
|
|
@@ -371,16 +551,10 @@ const blurFragmentShader = `
|
|
|
371
551
|
|
|
372
552
|
gl_FragColor = color;
|
|
373
553
|
|
|
374
|
-
float brightness = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));
|
|
375
|
-
float stepFactor = blending - brightness * .1;
|
|
376
|
-
gl_FragColor.a = pow(1.0 - blending * customSmoothstep(0.35 * stepFactor, 0.45 * stepFactor, distance), 5.);
|
|
377
|
-
gl_FragColor.a *= alphaFactor;
|
|
378
|
-
// gl_FragColor.rgb = vec3(1.0);
|
|
379
|
-
|
|
380
554
|
// #include <tonemapping_fragment>
|
|
381
555
|
// #include <colorspace_fragment>
|
|
382
556
|
|
|
383
557
|
// Uncomment to visualize blur amount
|
|
384
558
|
// gl_FragColor = vec4(blurAmount, 0.0, 0.0, 1.0);
|
|
385
559
|
}
|
|
386
|
-
`;
|
|
560
|
+
`;
|
|
@@ -106,11 +106,40 @@ enum LightShadows {
|
|
|
106
106
|
export class Light extends Behaviour implements ILight {
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
|
-
* The type of light
|
|
110
|
-
* Can not be changed at runtime.
|
|
109
|
+
* The type of light as a lowercase string: `"directional"`, `"point"`, `"spot"`.
|
|
110
|
+
* Implements {@link ILight.type}. Can not be changed at runtime.
|
|
111
111
|
*/
|
|
112
|
+
get type(): ILight["type"] {
|
|
113
|
+
return this._type;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Numeric LightType serialized from Unity/Blender — converts to string on write */
|
|
112
117
|
@serializable()
|
|
113
|
-
|
|
118
|
+
set type(value: LightType | ILight["type"]) {
|
|
119
|
+
if (this.light && this.__didAwake) {
|
|
120
|
+
throw new Error("Changing the light type at runtime is not supported");
|
|
121
|
+
}
|
|
122
|
+
switch (value) {
|
|
123
|
+
case LightType.Directional:
|
|
124
|
+
this._type = "directional";
|
|
125
|
+
break;
|
|
126
|
+
case LightType.Point:
|
|
127
|
+
this._type = "point";
|
|
128
|
+
break;
|
|
129
|
+
case LightType.Spot:
|
|
130
|
+
this._type = "spot";
|
|
131
|
+
break;
|
|
132
|
+
case "directional":
|
|
133
|
+
case "point":
|
|
134
|
+
case "spot":
|
|
135
|
+
this._type = value;
|
|
136
|
+
break;
|
|
137
|
+
default:
|
|
138
|
+
throw new Error("Invalid light type: " + value);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
private _type: ILight["type"] = "point";
|
|
142
|
+
|
|
114
143
|
|
|
115
144
|
/**
|
|
116
145
|
* The maximum distance the light affects.
|
|
@@ -345,7 +374,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
345
374
|
*/
|
|
346
375
|
public getWorldPosition(vec: Vector3): Vector3 {
|
|
347
376
|
if (this.light) {
|
|
348
|
-
if (this.type ===
|
|
377
|
+
if (this.type === "directional") {
|
|
349
378
|
return this.light.getWorldPosition(vec).multiplyScalar(1);
|
|
350
379
|
}
|
|
351
380
|
return this.light.getWorldPosition(vec);
|
|
@@ -372,12 +401,13 @@ export class Light extends Behaviour implements ILight {
|
|
|
372
401
|
else if (this.light.parent !== this.gameObject)
|
|
373
402
|
this.gameObject.add(this.light);
|
|
374
403
|
}
|
|
375
|
-
|
|
376
|
-
this.startCoroutine(this.updateMainLightRoutine(), FrameEvent.LateUpdate);
|
|
404
|
+
this.context.lights.push(this);
|
|
377
405
|
}
|
|
378
406
|
|
|
379
407
|
onDisable() {
|
|
380
408
|
if (debug) console.log("DISABLE LIGHT", this.name);
|
|
409
|
+
const index = this.context.lights.indexOf(this);
|
|
410
|
+
if (index !== -1) this.context.lights.splice(index, 1);
|
|
381
411
|
if (this.light) {
|
|
382
412
|
if (this.selfIsLight)
|
|
383
413
|
this.light.intensity = 0;
|
|
@@ -399,14 +429,14 @@ export class Light extends Behaviour implements ILight {
|
|
|
399
429
|
this._intensity = this.light.intensity;
|
|
400
430
|
|
|
401
431
|
switch (this.type) {
|
|
402
|
-
case
|
|
432
|
+
case "directional":
|
|
403
433
|
this.setDirectionalLight(this.light as DirectionalLight);
|
|
404
434
|
break;
|
|
405
435
|
}
|
|
406
436
|
}
|
|
407
437
|
else if (!this.light) {
|
|
408
438
|
switch (this.type) {
|
|
409
|
-
case
|
|
439
|
+
case "directional":
|
|
410
440
|
// console.log(this);
|
|
411
441
|
const dirLight = new DirectionalLight(this.color, this.intensity * Math.PI);
|
|
412
442
|
// directional light target is at 0 0 0 by default
|
|
@@ -425,7 +455,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
425
455
|
}
|
|
426
456
|
break;
|
|
427
457
|
|
|
428
|
-
case
|
|
458
|
+
case "spot":
|
|
429
459
|
const spotLight = new SpotLight(this.color, this.intensity * Math.PI, this.range, toRadians(this.spotAngle / 2), 1 - toRadians(this.innerSpotAngle / 2) / toRadians(this.spotAngle / 2), 2);
|
|
430
460
|
spotLight.position.set(0, 0, 0);
|
|
431
461
|
spotLight.rotation.set(0, 0, 0);
|
|
@@ -437,7 +467,7 @@ export class Light extends Behaviour implements ILight {
|
|
|
437
467
|
spotLightTarget.rotation.set(0, 0, 0);
|
|
438
468
|
break;
|
|
439
469
|
|
|
440
|
-
case
|
|
470
|
+
case "point":
|
|
441
471
|
const pointLight = new PointLight(this.color, this.intensity * Math.PI, this.range);
|
|
442
472
|
this.light = pointLight;
|
|
443
473
|
|
|
@@ -526,22 +556,6 @@ export class Light extends Behaviour implements ILight {
|
|
|
526
556
|
|
|
527
557
|
}
|
|
528
558
|
|
|
529
|
-
/**
|
|
530
|
-
* Coroutine that updates the main light reference in the context
|
|
531
|
-
* if this directional light should be the main light
|
|
532
|
-
*/
|
|
533
|
-
*updateMainLightRoutine() {
|
|
534
|
-
while (true) {
|
|
535
|
-
if (this.type === LightType.Directional) {
|
|
536
|
-
if (!this.context.mainLight || this.intensity > this.context.mainLight.intensity) {
|
|
537
|
-
this.context.mainLight = this;
|
|
538
|
-
}
|
|
539
|
-
yield;
|
|
540
|
-
}
|
|
541
|
-
break;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
559
|
/**
|
|
546
560
|
* Controls whether the renderer's shadow map type can be changed when soft shadows are used
|
|
547
561
|
*/
|
|
@@ -382,12 +382,12 @@ export class Rigidbody extends Behaviour implements IRigidbody {
|
|
|
382
382
|
this._watch.start(true, true);
|
|
383
383
|
this.startCoroutine(this.beforePhysics(), FrameEvent.LateUpdate);
|
|
384
384
|
if (isDevEnvironment()) {
|
|
385
|
-
if (
|
|
386
|
-
console.warn(`
|
|
385
|
+
if (globalThis["NEEDLE_USE_RAPIER"] === false)
|
|
386
|
+
console.warn(`RAPIER physics are disabled in your build. Enable them by setting NEEDLE_USE_RAPIER to true in your build config: Rigidbody could not be created.`);
|
|
387
387
|
else {
|
|
388
388
|
MODULES.RAPIER_PHYSICS.ready().then(async () => {
|
|
389
389
|
await delayForFrames(3);
|
|
390
|
-
if (!this.context.physics.engine?.getBody(this))
|
|
390
|
+
if (this.activeAndEnabled && !this.context.physics.engine?.getBody(this))
|
|
391
391
|
console.warn(`Rigidbody could not be created. Ensure \"${this.name}\" has a Collider component.`);
|
|
392
392
|
})
|
|
393
393
|
}
|
|
@@ -723,6 +723,7 @@ export class SceneSwitcher extends Behaviour {
|
|
|
723
723
|
// unless the user defines that he wants to use the scene name
|
|
724
724
|
if (this.useSceneName) {
|
|
725
725
|
if (scene instanceof Object3D) queryParameterValue = scene.name;
|
|
726
|
+
else if (scene instanceof AssetReference && scene.asset?.name) queryParameterValue = scene.asset.name;
|
|
726
727
|
else if (scene.url) queryParameterValue = sceneUriToName(scene.url);
|
|
727
728
|
}
|
|
728
729
|
// save the loaded scene as an url parameter
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
37
|
export * from "./codegen/components.js";
|
|
38
|
+
export { AnimatorControllerBuilder, type ConditionMode, type StateOptions, type TransitionOptions } from "./AnimatorController.js";
|
|
38
39
|
export { Collider } from "./Collider.js"; // export abstract type
|
|
39
40
|
export { Behaviour, Component, GameObject } from "./Component.js";
|
|
40
41
|
|
|
@@ -6,6 +6,7 @@ export { Animation } from "../Animation.js";
|
|
|
6
6
|
export { Keyframe } from "../AnimationCurve.js";
|
|
7
7
|
export { AnimationCurve } from "../AnimationCurve.js";
|
|
8
8
|
export { Animator } from "../Animator.js";
|
|
9
|
+
export { AnimatorControllerBuilder } from "../AnimatorController.js";
|
|
9
10
|
export { AnimatorController } from "../AnimatorController.js";
|
|
10
11
|
export { AudioListener } from "../AudioListener.js";
|
|
11
12
|
export { AudioSource } from "../AudioSource.js";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { EffectAttribute } from "postprocessing";
|
|
2
1
|
import { Uniform } from "three";
|
|
3
2
|
|
|
4
3
|
import { MODULES } from "../../../engine/engine_modules.js";
|
|
@@ -138,7 +137,7 @@ function createSharpeningEffectType() {
|
|
|
138
137
|
["radius", new Uniform(1)],
|
|
139
138
|
// ["threshold", new Uniform(0)],
|
|
140
139
|
]),
|
|
141
|
-
attributes: EffectAttribute.CONVOLUTION
|
|
140
|
+
attributes: MODULES.POSTPROCESSING.MODULE.EffectAttribute.CONVOLUTION
|
|
142
141
|
});
|
|
143
142
|
}
|
|
144
143
|
}
|
|
@@ -14,10 +14,6 @@ import { threeToneMappingToEffectMode } from "./Effects/Tonemapping.utils.js";
|
|
|
14
14
|
import { PostProcessingEffect, PostProcessingEffectContext } from "./PostProcessingEffect.js";
|
|
15
15
|
import { orderEffects, PostprocessingEffectData, PostProcessingEffectOrder } from "./utils.js";
|
|
16
16
|
|
|
17
|
-
declare const NEEDLE_USE_POSTPROCESSING: boolean;
|
|
18
|
-
globalThis["NEEDLE_USE_POSTPROCESSING"] = globalThis["NEEDLE_USE_POSTPROCESSING"] !== undefined ? globalThis["NEEDLE_USE_POSTPROCESSING"] : true;
|
|
19
|
-
|
|
20
|
-
|
|
21
17
|
const debug = getParam("debugpost");
|
|
22
18
|
|
|
23
19
|
const activeKey = Symbol("needle:postprocessing-handler");
|
|
@@ -58,13 +54,13 @@ export class PostProcessingHandler implements IPostProcessingHandler {
|
|
|
58
54
|
|
|
59
55
|
apply(components: PostProcessingEffect[]): Promise<void> {
|
|
60
56
|
if ("env" in import.meta && (import.meta as any /* webpack support */ ).env.VITE_NEEDLE_USE_POSTPROCESSING === "false") {
|
|
61
|
-
if (debug) console.warn("
|
|
62
|
-
else console.debug("
|
|
57
|
+
if (debug) console.warn("POSTPROCESSING is disabled via vite env setting");
|
|
58
|
+
else console.debug("POSTPROCESSING is disabled via vite env setting");
|
|
63
59
|
return Promise.resolve();
|
|
64
60
|
}
|
|
65
61
|
if (!NEEDLE_USE_POSTPROCESSING) {
|
|
66
|
-
if (debug) console.warn("
|
|
67
|
-
else console.debug("
|
|
62
|
+
if (debug || isDevEnvironment()) console.warn("POSTPROCESSING is disabled via global vite define setting");
|
|
63
|
+
else console.debug("POSTPROCESSING is disabled via vite define");
|
|
68
64
|
return Promise.resolve();
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// For firefox ViewTimeline support
|
|
2
|
-
|
|
1
|
+
// For firefox ViewTimeline support — dynamic import to avoid SSR crashes (polyfill accesses window at module level)
|
|
2
|
+
if (typeof window !== "undefined") import("scroll-timeline-polyfill/dist/scroll-timeline.js");
|
|
3
3
|
|
|
4
4
|
import { Box3, Object3D } from "three";
|
|
5
5
|
|
package/src/needle-engine.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Vite global defines — see plugins/vite/defines.js
|
|
2
|
+
// declare const entries here are picked up globally (ambient, no import/export).
|
|
3
|
+
// Vite sets these as globals in dev and statically replaces them at build time.
|
|
4
|
+
// Webpack DefinePlugin replaces them at build time too.
|
|
5
|
+
// The globalThis fallbacks for vanilla JS are in engine_constants.ts.
|
|
6
|
+
|
|
7
|
+
declare const NEEDLE_ENGINE_VERSION: string;
|
|
8
|
+
declare const NEEDLE_ENGINE_GENERATOR: string;
|
|
9
|
+
declare const NEEDLE_PROJECT_BUILD_TIME: string;
|
|
10
|
+
declare const NEEDLE_PUBLIC_KEY: string;
|
|
11
|
+
|
|
12
|
+
// #region treeshake flags
|
|
13
|
+
// declare var (not const) so globalThis["NEEDLE_USE_*"] access is also type-safe
|
|
14
|
+
declare var NEEDLE_USE_RAPIER: boolean;
|
|
15
|
+
declare var NEEDLE_USE_POSTPROCESSING: boolean;
|
|
16
|
+
// #endregion treeshake flags
|