@needle-tools/engine 4.6.1-next.f9f2e7d → 4.6.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/CHANGELOG.md +6 -0
- package/dist/{needle-engine.bundle-DoQP-VX2.min.js → needle-engine.bundle-D0XWaCQs.min.js} +173 -161
- package/dist/{needle-engine.bundle-ntX9QTqT.js → needle-engine.bundle-DGcStTA7.js} +7382 -7295
- package/dist/{needle-engine.bundle-CbE5i73R.umd.cjs → needle-engine.bundle-DmYMLdWP.umd.cjs} +177 -165
- package/dist/needle-engine.js +48 -48
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/engine_context.d.ts +2 -1
- package/lib/engine/engine_context.js +3 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_three_utils.d.ts +17 -14
- package/lib/engine/engine_three_utils.js +106 -53
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_tonemapping.d.ts +4 -0
- package/lib/engine/engine_tonemapping.js +21 -18
- package/lib/engine/engine_tonemapping.js.map +1 -1
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +4 -1
- package/lib/engine/webcomponents/needle-engine.extras.js +3 -3
- package/lib/engine/webcomponents/needle-engine.extras.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.js +11 -21
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/BloomEffect.d.ts +1 -1
- package/lib/engine-components/postprocessing/Effects/BloomEffect.js +2 -2
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.d.ts +8 -0
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +27 -8
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.js +1 -0
- package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Sharpening.d.ts +1 -0
- package/lib/engine-components/postprocessing/Effects/Sharpening.js +4 -0
- package/lib/engine-components/postprocessing/Effects/Sharpening.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +2 -9
- package/lib/engine-components/postprocessing/Effects/Tonemapping.js +23 -71
- package/lib/engine-components/postprocessing/Effects/Tonemapping.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +13 -0
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.js +52 -0
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.js.map +1 -0
- package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +7 -7
- package/lib/engine-components/postprocessing/PostProcessingEffect.js +9 -9
- package/lib/engine-components/postprocessing/PostProcessingEffect.js.map +1 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +10 -1
- package/lib/engine-components/postprocessing/PostProcessingHandler.js +130 -19
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/postprocessing/Volume.js +19 -24
- package/lib/engine-components/postprocessing/Volume.js.map +1 -1
- package/lib/engine-components/postprocessing/index.d.ts +1 -1
- package/lib/engine-components/postprocessing/index.js +1 -1
- package/lib/engine-components/postprocessing/index.js.map +1 -1
- package/lib/engine-components/postprocessing/utils.d.ts +12 -7
- package/lib/engine-components/postprocessing/utils.js +37 -53
- package/lib/engine-components/postprocessing/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/engine/engine_context.ts +5 -3
- package/src/engine/engine_three_utils.ts +134 -58
- package/src/engine/engine_tonemapping.ts +23 -24
- package/src/engine/engine_utils.ts +2 -2
- package/src/engine/webcomponents/needle-engine.extras.ts +3 -3
- package/src/engine/webcomponents/needle-engine.ts +14 -25
- package/src/engine-components/CameraUtils.ts +3 -3
- package/src/engine-components/postprocessing/Effects/BloomEffect.ts +2 -2
- package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +24 -13
- package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.ts +1 -0
- package/src/engine-components/postprocessing/Effects/Sharpening.ts +5 -0
- package/src/engine-components/postprocessing/Effects/Tonemapping.ts +26 -80
- package/src/engine-components/postprocessing/Effects/Tonemapping.utils.ts +60 -0
- package/src/engine-components/postprocessing/PostProcessingEffect.ts +9 -9
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +145 -23
- package/src/engine-components/postprocessing/Volume.ts +19 -26
- package/src/engine-components/postprocessing/index.ts +2 -2
- package/src/engine-components/postprocessing/utils.ts +40 -56
|
@@ -37,25 +37,27 @@ export function getPostProcessingManager(effect) {
|
|
|
37
37
|
return manager;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* Default
|
|
41
|
-
* E.g. in your custom effect, you can set `
|
|
42
|
-
* OR `
|
|
40
|
+
* Default order for post-processing effects. This can be used to sort effects by their rendering order when creating custom effects.
|
|
41
|
+
* E.g. in your custom effect, you can set `order: PostProcessingEffectOrder.Bloom + 1;` to ensure it gets rendered after the bloom effect.
|
|
42
|
+
* OR `order: PostProcessingEffectOrder.Bloom - 1;` to ensure it gets rendered before the bloom effect.
|
|
43
43
|
* @example
|
|
44
44
|
* ```typescript
|
|
45
|
-
* import {
|
|
45
|
+
* import { PostProcessingEffectOrder } from "@needle-tools/engine"
|
|
46
46
|
*
|
|
47
47
|
* export class MyCustomEffect extends PostProcessingEffect {
|
|
48
|
-
*
|
|
48
|
+
* order: PostProcessingEffectPriority.Bloom + 1; // render after bloom
|
|
49
49
|
*
|
|
50
50
|
* // ... your effect code
|
|
51
51
|
* }
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
|
-
export const
|
|
54
|
+
export const PostProcessingEffectOrder = {
|
|
55
|
+
/** Used to render effects at the start of the post-processing chain */
|
|
56
|
+
AT_START: -10_000,
|
|
55
57
|
NormalPass: 0,
|
|
56
58
|
DepthDownsamplingPass: 10,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
SSAO: 20,
|
|
60
|
+
SMAA: 30,
|
|
59
61
|
TiltShift: 40,
|
|
60
62
|
DepthOfField: 50,
|
|
61
63
|
ChromaticAberration: 60,
|
|
@@ -65,7 +67,9 @@ export const PostProcessingEffectPriority = {
|
|
|
65
67
|
ToneMapping: 100,
|
|
66
68
|
HueSaturation: 110,
|
|
67
69
|
BrightnessContrast: 120,
|
|
68
|
-
|
|
70
|
+
Sharpening: 130,
|
|
71
|
+
/** Used to render effects at the end of the post-processing chain, e.g. for final adjustments or overlays. */
|
|
72
|
+
AT_END: 10_000,
|
|
69
73
|
};
|
|
70
74
|
// let effectsOrder: Array<Constructor<Effect | Pass>> | null = null;
|
|
71
75
|
let builtinOrder = null;
|
|
@@ -74,62 +78,42 @@ export function orderEffects(effects) {
|
|
|
74
78
|
console.debug("Before ordering effects", [...effects]);
|
|
75
79
|
if (!builtinOrder) {
|
|
76
80
|
builtinOrder = new Map();
|
|
77
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.NormalPass,
|
|
78
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthDownsamplingPass,
|
|
79
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SMAAEffect,
|
|
80
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SSAOEffect,
|
|
81
|
-
builtinOrder.set(MODULES.
|
|
82
|
-
builtinOrder.set(MODULES.
|
|
83
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
84
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
85
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
86
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
87
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
88
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
89
|
-
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.
|
|
81
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.NormalPass, PostProcessingEffectOrder.NormalPass);
|
|
82
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthDownsamplingPass, PostProcessingEffectOrder.DepthDownsamplingPass);
|
|
83
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SMAAEffect, PostProcessingEffectOrder.SMAA);
|
|
84
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SSAOEffect, PostProcessingEffectOrder.SSAO);
|
|
85
|
+
builtinOrder.set(MODULES.POSTPROCESSING_AO.MODULE.N8AOPostPass, PostProcessingEffectOrder.SSAO);
|
|
86
|
+
builtinOrder.set(MODULES.POSTPROCESSING_AO.MODULE.N8AOPass, PostProcessingEffectOrder.SSAO);
|
|
87
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.TiltShiftEffect, PostProcessingEffectOrder.TiltShift);
|
|
88
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthOfFieldEffect, PostProcessingEffectOrder.DepthOfField);
|
|
89
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.ChromaticAberrationEffect, PostProcessingEffectOrder.ChromaticAberration);
|
|
90
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.BloomEffect, PostProcessingEffectOrder.Bloom);
|
|
91
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SelectiveBloomEffect, PostProcessingEffectOrder.Bloom);
|
|
92
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.VignetteEffect, PostProcessingEffectOrder.Vignette);
|
|
93
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.PixelationEffect, PostProcessingEffectOrder.Pixelation);
|
|
94
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.ToneMappingEffect, PostProcessingEffectOrder.ToneMapping);
|
|
95
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.HueSaturationEffect, PostProcessingEffectOrder.HueSaturation);
|
|
96
|
+
builtinOrder.set(MODULES.POSTPROCESSING.MODULE.BrightnessContrastEffect, PostProcessingEffectOrder.BrightnessContrast);
|
|
90
97
|
}
|
|
91
98
|
// enforce correct order of effects (e.g. DOF before Bloom)
|
|
92
99
|
effects.sort((a, b) => {
|
|
93
100
|
// we use find index here because sometimes constructor names are prefixed with `_`
|
|
94
101
|
// TODO: find a more robust solution that isnt name based (not sure if that exists tho... maybe we must give effect TYPES some priority/index)
|
|
95
|
-
const aidx = typeof a.priority === "number" ? a.priority : builtinOrder.get(a.effect.constructor)
|
|
96
|
-
const bidx = typeof b.priority === "number" ? b.priority : builtinOrder.get(b.effect.constructor)
|
|
102
|
+
const aidx = typeof a.priority === "number" ? a.priority : builtinOrder.get(a.effect.constructor) ?? Number.NEGATIVE_INFINITY;
|
|
103
|
+
const bidx = typeof b.priority === "number" ? b.priority : builtinOrder.get(b.effect.constructor) ?? Number.NEGATIVE_INFINITY;
|
|
97
104
|
// Unknown effects should be rendered first
|
|
98
|
-
if (aidx
|
|
105
|
+
if (aidx === Number.NEGATIVE_INFINITY) {
|
|
99
106
|
if (debug)
|
|
100
|
-
console.warn("Unknown effect found: ", a.constructor.name);
|
|
101
|
-
return
|
|
107
|
+
console.warn("Unknown effect found: ", a.constructor.name, a);
|
|
108
|
+
return 1;
|
|
102
109
|
}
|
|
103
|
-
else if (bidx
|
|
110
|
+
else if (bidx === Number.NEGATIVE_INFINITY) {
|
|
104
111
|
if (debug)
|
|
105
|
-
console.warn("Unknown effect found: ", b.constructor.name);
|
|
106
|
-
return 1;
|
|
112
|
+
console.warn("Unknown effect found: ", b.constructor.name, b);
|
|
113
|
+
return -1;
|
|
107
114
|
}
|
|
108
|
-
// if (aidx < 0) return 1;
|
|
109
|
-
// if (bidx < 0) return -1;
|
|
110
115
|
return aidx - bidx;
|
|
111
116
|
});
|
|
112
|
-
// effects.sort((a, b) => {
|
|
113
|
-
// if (a.beforeEffect) {
|
|
114
|
-
// const beforeA = effectsOrder!.findIndex(e => a.beforeEffect!.constructor.name.endsWith(e.name));
|
|
115
|
-
// if (beforeA >= 0) {
|
|
116
|
-
// return -1; // before effect should be rendered first
|
|
117
|
-
// }
|
|
118
|
-
// else {
|
|
119
|
-
// return 1; // no before effect, so we can keep the order
|
|
120
|
-
// }
|
|
121
|
-
// }
|
|
122
|
-
// else if (b.beforeEffect) {
|
|
123
|
-
// const beforeB = effectsOrder!.findIndex(e => b.beforeEffect!.constructor.name.endsWith(e.name));
|
|
124
|
-
// if (beforeB >= 0) {
|
|
125
|
-
// return 1; // before effect should be rendered first
|
|
126
|
-
// }
|
|
127
|
-
// else if (a.beforeEffect) {
|
|
128
|
-
// return -1; // no before effect, so we can keep the order
|
|
129
|
-
// }
|
|
130
|
-
// }
|
|
131
|
-
// return 0; // no before effect, so we can keep the order
|
|
132
|
-
// });
|
|
133
117
|
if (debug === "verbose")
|
|
134
118
|
console.debug("After ordering effects", [...effects]);
|
|
135
119
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/engine-components/postprocessing/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGxD,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;AAW3C,IAAI,yBAAyB,GAAuD,IAAI,CAAC;AAEzF,MAAM,UAAU,4BAA4B,CAAC,IAAiD;IAC1F,yBAAyB,GAAG,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAA4B;IAClE,IAAI,GAAG,GAAG,MAAM,CAAC,UAA6B,CAAC;IAC/C,OAAO,GAAG,EAAE;QACR,KAAK,MAAM,IAAI,IAAI,0BAA0B,CAAC,GAAG,CAAC,EAAE;YAChD,IAAK,IAA0C,CAAC,uBAAuB,KAAK,IAAI,EAAE;gBAC9E,OAAO,IAAyC,CAAC;aACpD;SACJ;QACD,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;KACpB;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAA4B;IACjE,IAAI,OAAO,GAAkC,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAC/E,IAAI,CAAC,OAAO,EAAE;QACV,IAAI,yBAAyB,EAAE;YAC3B,IAAI,KAAK;gBACL,OAAO,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;SAC5D;aACI;YACD,IAAI,gBAAgB,EAAE;gBAClB,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;SACxD;KACJ;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AASD;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/engine-components/postprocessing/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.2",
|
|
4
4
|
"description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.",
|
|
5
5
|
"main": "dist/needle-engine.min.js",
|
|
6
6
|
"exports": {
|
|
@@ -167,4 +167,4 @@
|
|
|
167
167
|
"module": "lib/needle-engine.js",
|
|
168
168
|
"typings": "lib/needle-engine.d.ts",
|
|
169
169
|
"types": "lib/needle-engine.d.ts"
|
|
170
|
-
}
|
|
170
|
+
}
|
|
@@ -40,6 +40,7 @@ import type { CoroutineData, ICamera, IComponent, IContext, ILight, LoadedModel,
|
|
|
40
40
|
import { deepClone, delay, DeviceUtilities, getParam } from './engine_utils.js';
|
|
41
41
|
import type { INeedleXRSessionEventReceiver, NeedleXRSession } from './engine_xr.js';
|
|
42
42
|
import { NeedleMenu } from './webcomponents/needle menu/needle-menu.js';
|
|
43
|
+
import type { NeedleEngineWebComponent } from './webcomponents/needle-engine.js';
|
|
43
44
|
|
|
44
45
|
const debug = getParam("debugcontext");
|
|
45
46
|
const stats = getParam("stats");
|
|
@@ -224,7 +225,7 @@ export class Context implements IContext {
|
|
|
224
225
|
hash?: string;
|
|
225
226
|
|
|
226
227
|
/** The `<needle-engine>` web component */
|
|
227
|
-
domElement: HTMLElement;
|
|
228
|
+
domElement: NeedleEngineWebComponent | HTMLElement;
|
|
228
229
|
|
|
229
230
|
appendHTMLElement(element: HTMLElement) {
|
|
230
231
|
if (this.domElement.shadowRoot)
|
|
@@ -1186,8 +1187,9 @@ export class Context implements IContext {
|
|
|
1186
1187
|
this._dispatchReadyAfterFrame = true;
|
|
1187
1188
|
const res = ContextRegistry.dispatchCallback(ContextEvent.ContextCreated, this, { files: loadedFiles });
|
|
1188
1189
|
if (res) {
|
|
1189
|
-
|
|
1190
|
-
|
|
1190
|
+
const domElement = this.domElement as HTMLElement;
|
|
1191
|
+
if ("internalSetLoadingMessage" in domElement && typeof domElement.internalSetLoadingMessage === "function")
|
|
1192
|
+
domElement?.internalSetLoadingMessage("finish loading");
|
|
1191
1193
|
await res;
|
|
1192
1194
|
}
|
|
1193
1195
|
if (opts?.abortSignal?.aborted) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnimationAction, Box3, Box3Helper, Camera, Color, Euler, GridHelper, Layers, Material, Mesh, MeshStandardMaterial, Object3D, PerspectiveCamera, PlaneGeometry, Quaternion, Scene, ShadowMaterial, Texture, Uniform, Vector2Like, Vector3 } from "three";
|
|
1
|
+
import { AnimationAction, Box3, Box3Helper, Camera, Color, DepthTexture, Euler, GridHelper, Layers, Material, Mesh, MeshStandardMaterial, Object3D, OrthographicCamera, PerspectiveCamera, PlaneGeometry, Quaternion, Scene, ShadowMaterial, Texture, Uniform, Vector2Like, Vector3, WebGLRenderTarget } from "three";
|
|
2
2
|
import { ShaderMaterial, WebGLRenderer } from "three";
|
|
3
3
|
import { GroundedSkybox } from "three/examples/jsm/objects/GroundedSkybox.js";
|
|
4
4
|
|
|
@@ -95,7 +95,7 @@ export function lookAtObject(object: Object3D, target: Object3D, keepUpDirection
|
|
|
95
95
|
* });
|
|
96
96
|
* ```
|
|
97
97
|
*/
|
|
98
|
-
export function lookAtScreenPoint(object: Object3D, target: Vector2Like, camera: Camera, factor
|
|
98
|
+
export function lookAtScreenPoint(object: Object3D, target: Vector2Like, camera: Camera, factor: number = 1): Vector3 | null {
|
|
99
99
|
|
|
100
100
|
if (camera) {
|
|
101
101
|
const pos = getTempVector(0, 0, 0);
|
|
@@ -426,42 +426,69 @@ export function isAnimationAction(obj: object) {
|
|
|
426
426
|
|
|
427
427
|
|
|
428
428
|
|
|
429
|
+
class BlitMaterial extends ShaderMaterial {
|
|
430
|
+
static vertex = `
|
|
431
|
+
varying vec2 vUv;
|
|
432
|
+
void main(){
|
|
433
|
+
vUv = uv;
|
|
434
|
+
gl_Position = vec4(position.xy, 0., 1.0);
|
|
435
|
+
}`;
|
|
436
|
+
|
|
437
|
+
constructor() {
|
|
438
|
+
super({
|
|
439
|
+
vertexShader: BlitMaterial.vertex,
|
|
440
|
+
uniforms: {
|
|
441
|
+
map: new Uniform(null),
|
|
442
|
+
flipY: new Uniform(true),
|
|
443
|
+
writeDepth: new Uniform(false),
|
|
444
|
+
depthTexture: new Uniform(null)
|
|
445
|
+
},
|
|
446
|
+
fragmentShader: `
|
|
447
|
+
uniform sampler2D map;
|
|
448
|
+
uniform bool flipY;
|
|
449
|
+
uniform bool writeDepth;
|
|
450
|
+
uniform sampler2D depthTexture;
|
|
451
|
+
|
|
452
|
+
varying vec2 vUv;
|
|
453
|
+
|
|
454
|
+
void main(){
|
|
455
|
+
vec2 uv = vUv;
|
|
456
|
+
if (flipY) uv.y = 1.0 - uv.y;
|
|
457
|
+
gl_FragColor = texture2D(map, uv);
|
|
458
|
+
|
|
459
|
+
if (writeDepth) {
|
|
460
|
+
float depth = texture2D(depthTexture, uv).r;
|
|
461
|
+
gl_FragDepth = depth;
|
|
462
|
+
|
|
463
|
+
// float linearDepth = (depth - 0.99) * 100.0; // Enhance near 1.0 values
|
|
464
|
+
// gl_FragColor = vec4(linearDepth, linearDepth, linearDepth, 1.0);
|
|
465
|
+
}
|
|
466
|
+
}`
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
reset() {
|
|
471
|
+
this.uniforms.map.value = null;
|
|
472
|
+
this.uniforms.flipY.value = true;
|
|
473
|
+
this.uniforms.writeDepth.value = false;
|
|
474
|
+
this.uniforms.depthTexture.value = null;
|
|
475
|
+
this.needsUpdate = true;
|
|
476
|
+
this.uniformsNeedUpdate = true;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
429
480
|
/**
|
|
430
481
|
* Utility class to perform various graphics operations like copying textures to canvas
|
|
431
482
|
*/
|
|
432
483
|
export class Graphics {
|
|
433
|
-
private static planeGeometry = new PlaneGeometry(2, 2, 1, 1);
|
|
434
|
-
private static renderer: WebGLRenderer
|
|
435
|
-
private static perspectiveCam = new PerspectiveCamera();
|
|
436
|
-
private static
|
|
437
|
-
private static readonly
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
vUv = uv;
|
|
441
|
-
gl_Position = vec4(position.xy * 1.0,0.,.999999);
|
|
442
|
-
}`;
|
|
443
|
-
private static readonly fragment = `
|
|
444
|
-
uniform sampler2D map;
|
|
445
|
-
varying vec2 vUv;
|
|
446
|
-
void main(){
|
|
447
|
-
vec2 uv = vUv;
|
|
448
|
-
uv.y = 1.0 - uv.y;
|
|
449
|
-
gl_FragColor = texture2D( map, uv);
|
|
450
|
-
// gl_FragColor = vec4(uv.xy, 0, 1);
|
|
451
|
-
}`;
|
|
452
|
-
private static blitMaterial: ShaderMaterial | undefined = undefined;
|
|
484
|
+
private static readonly planeGeometry = new PlaneGeometry(2, 2, 1, 1);
|
|
485
|
+
private static readonly renderer: WebGLRenderer = new WebGLRenderer({ antialias: false, alpha: true });
|
|
486
|
+
private static readonly perspectiveCam = new PerspectiveCamera();
|
|
487
|
+
private static readonly orthographicCam = new OrthographicCamera();
|
|
488
|
+
private static readonly scene = new Scene();
|
|
489
|
+
private static readonly blitMaterial: BlitMaterial = new BlitMaterial();
|
|
490
|
+
private static readonly mesh: Mesh = new Mesh(Graphics.planeGeometry, Graphics.blitMaterial);
|
|
453
491
|
|
|
454
|
-
/**
|
|
455
|
-
* Create a blit material for copying textures
|
|
456
|
-
*/
|
|
457
|
-
static createBlitMaterial(fragment: string): ShaderMaterial {
|
|
458
|
-
return new ShaderMaterial({
|
|
459
|
-
uniforms: { map: new Uniform(null) },
|
|
460
|
-
vertexShader: this.vertex,
|
|
461
|
-
fragmentShader: fragment
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
private static mesh: Mesh | undefined = undefined;
|
|
465
492
|
|
|
466
493
|
/**
|
|
467
494
|
* Copy a texture to a new texture
|
|
@@ -470,17 +497,16 @@ export class Graphics {
|
|
|
470
497
|
* @returns the newly created, copied texture
|
|
471
498
|
*/
|
|
472
499
|
static copyTexture(texture: Texture, blitMaterial?: ShaderMaterial): Texture {
|
|
500
|
+
|
|
473
501
|
// ensure that a blit material exists
|
|
474
|
-
if (!
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
fragmentShader: this.fragment
|
|
479
|
-
});
|
|
480
|
-
}
|
|
502
|
+
if (!blitMaterial) {
|
|
503
|
+
blitMaterial = this.blitMaterial;
|
|
504
|
+
};
|
|
505
|
+
this.blitMaterial.reset();
|
|
481
506
|
|
|
482
507
|
const material = blitMaterial || this.blitMaterial;
|
|
483
508
|
|
|
509
|
+
// TODO: reset the uniforms...
|
|
484
510
|
material.uniforms.map.value = texture;
|
|
485
511
|
material.needsUpdate = true;
|
|
486
512
|
material.uniformsNeedUpdate = true;
|
|
@@ -488,17 +514,13 @@ export class Graphics {
|
|
|
488
514
|
|
|
489
515
|
// ensure that the blit material has the correct vertex shader
|
|
490
516
|
const origVertexShader = material.vertexShader;
|
|
491
|
-
material.vertexShader =
|
|
517
|
+
material.vertexShader = BlitMaterial.vertex;
|
|
492
518
|
|
|
493
|
-
if (!this.mesh)
|
|
494
|
-
this.mesh = new Mesh(this.planeGeometry, this.blitMaterial);
|
|
495
519
|
const mesh = this.mesh;
|
|
496
520
|
mesh.material = material;
|
|
497
521
|
mesh.frustumCulled = false;
|
|
498
522
|
this.scene.children.length = 0;
|
|
499
523
|
this.scene.add(mesh);
|
|
500
|
-
if (!this.renderer)
|
|
501
|
-
this.renderer = new WebGLRenderer({ antialias: false });
|
|
502
524
|
this.renderer.setSize(texture.image.width, texture.image.height);
|
|
503
525
|
this.renderer.clear();
|
|
504
526
|
this.renderer.render(this.scene, this.perspectiveCam);
|
|
@@ -512,19 +534,73 @@ export class Graphics {
|
|
|
512
534
|
return tex;
|
|
513
535
|
}
|
|
514
536
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
537
|
+
static blit(src: Texture, target: WebGLRenderTarget, options?: {
|
|
538
|
+
renderer?: WebGLRenderer,
|
|
539
|
+
blitMaterial?: ShaderMaterial,
|
|
540
|
+
flipY?: boolean,
|
|
541
|
+
depthTexture?: DepthTexture | null,
|
|
542
|
+
depthTest?: boolean,
|
|
543
|
+
depthWrite?: boolean,
|
|
544
|
+
}) {
|
|
545
|
+
const {
|
|
546
|
+
renderer = this.renderer,
|
|
547
|
+
blitMaterial = this.blitMaterial,
|
|
548
|
+
flipY = false,
|
|
549
|
+
depthTexture = null,
|
|
550
|
+
depthTest = true,
|
|
551
|
+
depthWrite = true,
|
|
552
|
+
} = options || {};
|
|
553
|
+
|
|
554
|
+
this.blitMaterial.reset();
|
|
555
|
+
|
|
556
|
+
if (blitMaterial.uniforms.map) blitMaterial.uniforms.map.value = src;
|
|
557
|
+
if (blitMaterial.uniforms.flipY) blitMaterial.uniforms.flipY.value = flipY;
|
|
558
|
+
|
|
559
|
+
if (depthTexture) {
|
|
560
|
+
blitMaterial.uniforms.writeDepth = new Uniform(true);
|
|
561
|
+
blitMaterial.uniforms.depthTexture.value = depthTexture;
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
blitMaterial.uniforms.writeDepth = new Uniform(false);
|
|
565
|
+
blitMaterial.uniforms.depthTexture.value = null;
|
|
566
|
+
}
|
|
567
|
+
blitMaterial.needsUpdate = true;
|
|
568
|
+
blitMaterial.uniformsNeedUpdate = true;
|
|
569
|
+
|
|
570
|
+
const mesh = this.mesh;
|
|
571
|
+
mesh.material = blitMaterial;
|
|
572
|
+
mesh.frustumCulled = false;
|
|
573
|
+
this.scene.children.length = 0;
|
|
574
|
+
this.scene.add(mesh);
|
|
575
|
+
|
|
576
|
+
// Save state
|
|
577
|
+
const renderTarget = renderer.getRenderTarget();
|
|
578
|
+
const gl = renderer.getContext();
|
|
579
|
+
const depthTestEnabled = gl.getParameter(gl.DEPTH_TEST);
|
|
580
|
+
const depthWriteMask = gl.getParameter(gl.DEPTH_WRITEMASK);
|
|
581
|
+
const depthFunc = gl.getParameter(gl.DEPTH_FUNC);
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
// Set state
|
|
585
|
+
if (depthTest) renderer.getContext().enable(renderer.getContext().DEPTH_TEST);
|
|
586
|
+
else renderer.getContext().disable(renderer.getContext().DEPTH_TEST);
|
|
587
|
+
renderer.state.buffers.depth.setMask(depthWrite);
|
|
588
|
+
|
|
589
|
+
renderer.setClearColor(new Color(0, 0, 0), 0);
|
|
590
|
+
// renderer.setSize(target.width, target.height);
|
|
591
|
+
renderer.setPixelRatio(window.devicePixelRatio);
|
|
592
|
+
renderer.setRenderTarget(target);
|
|
593
|
+
renderer.clear();
|
|
594
|
+
renderer.render(this.scene, this.perspectiveCam);
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
// Restore state
|
|
598
|
+
renderer.setRenderTarget(renderTarget); // reset render target
|
|
599
|
+
const depthBuffer = renderer.state.buffers.depth;
|
|
600
|
+
depthBuffer.setTest(depthTestEnabled);
|
|
601
|
+
depthBuffer.setMask(depthWriteMask);
|
|
602
|
+
depthBuffer.setFunc(depthFunc);
|
|
603
|
+
}
|
|
528
604
|
|
|
529
605
|
/**
|
|
530
606
|
* Copy a texture to a HTMLCanvasElement
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ShaderChunk } from "three";
|
|
1
|
+
import { ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping, NoToneMapping, ShaderChunk, ToneMapping } from "three";
|
|
2
2
|
|
|
3
3
|
import { isDevEnvironment } from "./debug/index.js";
|
|
4
4
|
import type { Context } from "./engine_setup";
|
|
@@ -185,26 +185,25 @@ vec3 AgXToneMapping( vec3 color ) {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// }
|
|
188
|
+
type TonemappingName = "none" | "neutral" | "aces" | "agx" | "khronos_neutral";
|
|
189
|
+
|
|
190
|
+
export function nameToThreeTonemapping(str: null | undefined | TonemappingName | ({} & string)): undefined | ToneMapping {
|
|
191
|
+
if (typeof str !== "string")
|
|
192
|
+
return undefined;
|
|
193
|
+
str = str.toLowerCase();
|
|
194
|
+
switch (str) {
|
|
195
|
+
case "none":
|
|
196
|
+
return NoToneMapping;
|
|
197
|
+
case "neutral":
|
|
198
|
+
return NeutralToneMapping;
|
|
199
|
+
case "aces":
|
|
200
|
+
return ACESFilmicToneMapping;
|
|
201
|
+
case "agx":
|
|
202
|
+
return AgXToneMapping;
|
|
203
|
+
case "khronos_neutral":
|
|
204
|
+
return NeutralToneMapping;
|
|
205
|
+
default:
|
|
206
|
+
console.warn("[PostProcessing] Unknown tone mapping mode", str);
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -7,7 +7,7 @@ import { needleLogoOnlySVG } from "./assets/index.js";
|
|
|
7
7
|
import type { Context } from "./engine_context.js";
|
|
8
8
|
import { ContextRegistry } from "./engine_context_registry.js";
|
|
9
9
|
import { type SourceIdentifier } from "./engine_types.js";
|
|
10
|
-
import type {
|
|
10
|
+
import type { NeedleEngineWebComponent } from "./webcomponents/needle-engine.js";
|
|
11
11
|
|
|
12
12
|
// https://schneidenbach.gitbooks.io/typescript-cookbook/content/nameof-operator.html
|
|
13
13
|
/** @internal */
|
|
@@ -1008,7 +1008,7 @@ async function addOverlays(canvas: HTMLCanvasElement, args: { showLogo?: boolean
|
|
|
1008
1008
|
|
|
1009
1009
|
// Draw the website's icon in the center of the QR code
|
|
1010
1010
|
const faviconImage = new Image();
|
|
1011
|
-
const element = document.querySelector("needle-engine") as
|
|
1011
|
+
const element = document.querySelector("needle-engine") as NeedleEngineWebComponent;
|
|
1012
1012
|
const logoSrc = element?.getAttribute("loading-logo-src") || needleLogoOnlySVG;
|
|
1013
1013
|
if (!logoSrc) return;
|
|
1014
1014
|
|
|
@@ -10,7 +10,7 @@ DO NOT IMPORT ENGINE_ELEMENT FROM HERE
|
|
|
10
10
|
* Use the addAttributeChangeCallback utility methods to register callback events
|
|
11
11
|
*/
|
|
12
12
|
export async function registerObservableAttribute(name: string) {
|
|
13
|
-
const {
|
|
14
|
-
if (!
|
|
15
|
-
|
|
13
|
+
const { NeedleEngineWebComponent } = await import("./needle-engine.js");
|
|
14
|
+
if (!NeedleEngineWebComponent.observedAttributes.includes(name))
|
|
15
|
+
NeedleEngineWebComponent.observedAttributes.push(name);
|
|
16
16
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { AgXToneMapping, Color, LinearToneMapping, NeutralToneMapping, NoToneMapping } from "three";
|
|
2
|
-
|
|
3
1
|
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
4
2
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
5
3
|
import { registerLoader } from "../engine_gltf.js";
|
|
@@ -7,6 +5,7 @@ import { hasCommercialLicense } from "../engine_license.js";
|
|
|
7
5
|
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
|
|
8
6
|
import { NeedleLoader } from "../engine_loaders.js";
|
|
9
7
|
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
8
|
+
import { nameToThreeTonemapping } from "../engine_tonemapping.js";
|
|
10
9
|
import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
|
|
11
10
|
import { getParam } from "../engine_utils.js";
|
|
12
11
|
import { RGBAColor } from "../js-extensions/RGBAColor.js";
|
|
@@ -30,7 +29,7 @@ const desktopSessionActiveClassName = "desktop-session-active";
|
|
|
30
29
|
const observedAttributes = [
|
|
31
30
|
"public-key",
|
|
32
31
|
"version",
|
|
33
|
-
|
|
32
|
+
|
|
34
33
|
"hash",
|
|
35
34
|
"src",
|
|
36
35
|
"camera-controls",
|
|
@@ -60,7 +59,7 @@ const observedAttributes = [
|
|
|
60
59
|
* @example
|
|
61
60
|
* <needle-engine src="https://example.com/scene.glb" camera-controls="false"></needle-engine>
|
|
62
61
|
*/
|
|
63
|
-
export class
|
|
62
|
+
export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngineComponent {
|
|
64
63
|
|
|
65
64
|
static get observedAttributes() {
|
|
66
65
|
return observedAttributes
|
|
@@ -352,6 +351,12 @@ export class NeedleEngineHTMLElement extends HTMLElement implements INeedleEngin
|
|
|
352
351
|
}
|
|
353
352
|
}
|
|
354
353
|
|
|
354
|
+
/** The tonemapping setting configured as an attribute on the <needle-engine> component */
|
|
355
|
+
get toneMapping(): TonemappingAttributeOptions | null | undefined {
|
|
356
|
+
const attribute = (this.getAttribute("tonemapping") || this.getAttribute("tone-mapping")) as TonemappingAttributeOptions | null | undefined;
|
|
357
|
+
return attribute;
|
|
358
|
+
}
|
|
359
|
+
|
|
355
360
|
private _loadId: number = 0;
|
|
356
361
|
private _abortController: AbortController | null = null;
|
|
357
362
|
private _lastSourceFiles: Array<string> | null = null;
|
|
@@ -521,26 +526,10 @@ export class NeedleEngineHTMLElement extends HTMLElement implements INeedleEngin
|
|
|
521
526
|
private applyAttributes() {
|
|
522
527
|
// set tonemapping if configured
|
|
523
528
|
if (this._context?.renderer) {
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
this._context.renderer.toneMapping = NoToneMapping;
|
|
528
|
-
break;
|
|
529
|
-
case "linear":
|
|
530
|
-
this._context.renderer.toneMapping = LinearToneMapping;
|
|
531
|
-
break;
|
|
532
|
-
case "neutral":
|
|
533
|
-
this._context.renderer.toneMapping = NeutralToneMapping;
|
|
534
|
-
break;
|
|
535
|
-
case "agx":
|
|
536
|
-
this._context.renderer.toneMapping = AgXToneMapping;
|
|
537
|
-
break;
|
|
538
|
-
default:
|
|
539
|
-
if (attribute !== null && attribute !== undefined) {
|
|
540
|
-
console.warn("Invalid tone-mapping attribute: " + attribute);
|
|
541
|
-
}
|
|
529
|
+
const threeTonemapping = nameToThreeTonemapping(this.toneMapping);
|
|
530
|
+
if (threeTonemapping !== undefined) {
|
|
531
|
+
this._context.renderer.toneMapping = threeTonemapping;
|
|
542
532
|
}
|
|
543
|
-
|
|
544
533
|
const exposure = this.getAttribute("tone-mapping-exposure");
|
|
545
534
|
if (exposure !== null && exposure !== undefined) {
|
|
546
535
|
const value = parseFloat(exposure);
|
|
@@ -561,7 +550,7 @@ export class NeedleEngineHTMLElement extends HTMLElement implements INeedleEngin
|
|
|
561
550
|
if (this._context?.renderer) {
|
|
562
551
|
if (typeof backgroundColor === "string" && backgroundColor.length > 0) {
|
|
563
552
|
const rgbaColor = RGBAColor.fromColorRepresentation(backgroundColor);
|
|
564
|
-
if(debug) console.debug("<needle-engine> background-color changed, str:", backgroundColor, "→", rgbaColor)
|
|
553
|
+
if (debug) console.debug("<needle-engine> background-color changed, str:", backgroundColor, "→", rgbaColor)
|
|
565
554
|
this._context.renderer.setClearColor(rgbaColor, rgbaColor.alpha);
|
|
566
555
|
this.context.scene.background = null;
|
|
567
556
|
}
|
|
@@ -803,7 +792,7 @@ export class NeedleEngineHTMLElement extends HTMLElement implements INeedleEngin
|
|
|
803
792
|
}
|
|
804
793
|
|
|
805
794
|
if (typeof window !== "undefined" && !window.customElements.get(htmlTagName))
|
|
806
|
-
window.customElements.define(htmlTagName,
|
|
795
|
+
window.customElements.define(htmlTagName, NeedleEngineWebComponent);
|
|
807
796
|
|
|
808
797
|
|
|
809
798
|
|