@needle-tools/engine 4.6.1-next.f9f2e7d → 4.6.2-next.fb486b2

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/{needle-engine.bundle-DoQP-VX2.min.js → needle-engine.bundle-CJ4jhuta.min.js} +173 -161
  3. package/dist/{needle-engine.bundle-ntX9QTqT.js → needle-engine.bundle-CQzZighj.js} +7390 -7295
  4. package/dist/{needle-engine.bundle-CbE5i73R.umd.cjs → needle-engine.bundle-CdAK5p8o.umd.cjs} +177 -165
  5. package/dist/needle-engine.js +48 -48
  6. package/dist/needle-engine.min.js +1 -1
  7. package/dist/needle-engine.umd.cjs +1 -1
  8. package/lib/engine/engine_context.d.ts +2 -1
  9. package/lib/engine/engine_context.js +3 -2
  10. package/lib/engine/engine_context.js.map +1 -1
  11. package/lib/engine/engine_three_utils.d.ts +17 -14
  12. package/lib/engine/engine_three_utils.js +106 -53
  13. package/lib/engine/engine_three_utils.js.map +1 -1
  14. package/lib/engine/engine_tonemapping.d.ts +4 -0
  15. package/lib/engine/engine_tonemapping.js +21 -18
  16. package/lib/engine/engine_tonemapping.js.map +1 -1
  17. package/lib/engine/engine_utils.js.map +1 -1
  18. package/lib/engine/webcomponents/needle-engine.d.ts +4 -1
  19. package/lib/engine/webcomponents/needle-engine.extras.js +3 -3
  20. package/lib/engine/webcomponents/needle-engine.extras.js.map +1 -1
  21. package/lib/engine/webcomponents/needle-engine.js +11 -21
  22. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  23. package/lib/engine-components/CameraUtils.js.map +1 -1
  24. package/lib/engine-components/postprocessing/Effects/BloomEffect.d.ts +1 -1
  25. package/lib/engine-components/postprocessing/Effects/BloomEffect.js +2 -5
  26. package/lib/engine-components/postprocessing/Effects/BloomEffect.js.map +1 -1
  27. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.d.ts +8 -0
  28. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +27 -8
  29. package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js.map +1 -1
  30. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.js +1 -0
  31. package/lib/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.js.map +1 -1
  32. package/lib/engine-components/postprocessing/Effects/Sharpening.d.ts +1 -0
  33. package/lib/engine-components/postprocessing/Effects/Sharpening.js +4 -0
  34. package/lib/engine-components/postprocessing/Effects/Sharpening.js.map +1 -1
  35. package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +2 -9
  36. package/lib/engine-components/postprocessing/Effects/Tonemapping.js +23 -71
  37. package/lib/engine-components/postprocessing/Effects/Tonemapping.js.map +1 -1
  38. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +13 -0
  39. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.js +52 -0
  40. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.js.map +1 -0
  41. package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +7 -7
  42. package/lib/engine-components/postprocessing/PostProcessingEffect.js +9 -9
  43. package/lib/engine-components/postprocessing/PostProcessingEffect.js.map +1 -1
  44. package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +10 -1
  45. package/lib/engine-components/postprocessing/PostProcessingHandler.js +152 -23
  46. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
  47. package/lib/engine-components/postprocessing/Volume.js +19 -24
  48. package/lib/engine-components/postprocessing/Volume.js.map +1 -1
  49. package/lib/engine-components/postprocessing/index.d.ts +1 -1
  50. package/lib/engine-components/postprocessing/index.js +1 -1
  51. package/lib/engine-components/postprocessing/index.js.map +1 -1
  52. package/lib/engine-components/postprocessing/utils.d.ts +13 -7
  53. package/lib/engine-components/postprocessing/utils.js +37 -53
  54. package/lib/engine-components/postprocessing/utils.js.map +1 -1
  55. package/package.json +1 -1
  56. package/src/engine/engine_context.ts +5 -3
  57. package/src/engine/engine_three_utils.ts +134 -58
  58. package/src/engine/engine_tonemapping.ts +23 -24
  59. package/src/engine/engine_utils.ts +2 -2
  60. package/src/engine/webcomponents/needle-engine.extras.ts +3 -3
  61. package/src/engine/webcomponents/needle-engine.ts +14 -25
  62. package/src/engine-components/CameraUtils.ts +3 -3
  63. package/src/engine-components/postprocessing/Effects/BloomEffect.ts +2 -4
  64. package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +24 -13
  65. package/src/engine-components/postprocessing/Effects/ScreenspaceAmbientOcclusionN8.ts +1 -0
  66. package/src/engine-components/postprocessing/Effects/Sharpening.ts +5 -0
  67. package/src/engine-components/postprocessing/Effects/Tonemapping.ts +26 -80
  68. package/src/engine-components/postprocessing/Effects/Tonemapping.utils.ts +60 -0
  69. package/src/engine-components/postprocessing/PostProcessingEffect.ts +9 -9
  70. package/src/engine-components/postprocessing/PostProcessingHandler.ts +174 -27
  71. package/src/engine-components/postprocessing/Volume.ts +19 -26
  72. package/src/engine-components/postprocessing/index.ts +2 -2
  73. package/src/engine-components/postprocessing/utils.ts +41 -56
@@ -37,25 +37,27 @@ export function getPostProcessingManager(effect) {
37
37
  return manager;
38
38
  }
39
39
  /**
40
- * Default priority 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 `priority: PostProcessingEffectPriority.Bloom + 1;` to ensure it gets rendered after the bloom effect.
42
- * OR `priority: PostProcessingEffectPriority.Bloom - 1;` to ensure it gets rendered before the bloom effect.
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 { PostProcessingEffectPriority } from "@needle-tools/engine"
45
+ * import { PostProcessingEffectOrder } from "@needle-tools/engine"
46
46
  *
47
47
  * export class MyCustomEffect extends PostProcessingEffect {
48
- * priority: PostProcessingEffectPriority.Bloom + 1; // render after bloom
48
+ * order: PostProcessingEffectPriority.Bloom + 1; // render after bloom
49
49
  *
50
50
  * // ... your effect code
51
51
  * }
52
52
  * ```
53
53
  */
54
- export const PostProcessingEffectPriority = {
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
- SMAA: 20,
58
- SSAO: 30,
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
- // Sharpening: 130,
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, PostProcessingEffectPriority.NormalPass);
78
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthDownsamplingPass, PostProcessingEffectPriority.DepthDownsamplingPass);
79
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SMAAEffect, PostProcessingEffectPriority.SMAA);
80
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SSAOEffect, PostProcessingEffectPriority.SSAO);
81
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.TiltShiftEffect, PostProcessingEffectPriority.TiltShift);
82
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthOfFieldEffect, PostProcessingEffectPriority.DepthOfField);
83
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.ChromaticAberrationEffect, PostProcessingEffectPriority.ChromaticAberration);
84
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.BloomEffect, PostProcessingEffectPriority.Bloom);
85
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.VignetteEffect, PostProcessingEffectPriority.Vignette);
86
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.PixelationEffect, PostProcessingEffectPriority.Pixelation);
87
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.ToneMappingEffect, PostProcessingEffectPriority.ToneMapping);
88
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.HueSaturationEffect, PostProcessingEffectPriority.HueSaturation);
89
- builtinOrder.set(MODULES.POSTPROCESSING.MODULE.BrightnessContrastEffect, PostProcessingEffectPriority.BrightnessContrast);
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) || -1;
96
- const bidx = typeof b.priority === "number" ? b.priority : builtinOrder.get(b.effect.constructor) || -1;
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 < 0) {
105
+ if (aidx === Number.NEGATIVE_INFINITY) {
99
106
  if (debug)
100
- console.warn("Unknown effect found: ", a.constructor.name);
101
- return -1;
107
+ console.warn("Unknown effect found: ", a.constructor.name, a);
108
+ return 1;
102
109
  }
103
- else if (bidx < 0) {
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":"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"}
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.1-next.f9f2e7d",
3
+ "version": "4.6.2-next.fb486b2",
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": {
@@ -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
- if ("internalSetLoadingMessage" in this.domElement && typeof this.domElement.internalSetLoadingMessage === "function")
1190
- this.domElement?.internalSetLoadingMessage("finish loading");
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 : number = 1): Vector3 | null {
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 | undefined = undefined;
435
- private static perspectiveCam = new PerspectiveCamera();
436
- private static scene = new Scene();
437
- private static readonly vertex = `
438
- varying vec2 vUv;
439
- void main(){
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 (!this.blitMaterial) {
475
- this.blitMaterial = new ShaderMaterial({
476
- uniforms: { map: new Uniform(null) },
477
- vertexShader: this.vertex,
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 = this.vertex;
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
- // static blit(src: Texture, target: Texture, blitMaterial?: ShaderMaterial) {
516
- // let material = blitMaterial ?? this.blipMaterial;
517
- // material.uniforms.map.value = src;
518
- // this.mesh.material = material;
519
- // this.mesh.frustumCulled = false;
520
- // this.mesh.matrix.identity();
521
- // this.scene.children.length = 0;
522
- // this.scene.add(this.mesh);
523
- // this.renderer.setSize(src.image.width, src.image.height);
524
- // this.renderer.clear();
525
- // this.renderer.render(this.scene, this.perspectiveCam);
526
- // return new Texture(this.renderer.domElement);
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
- // function resetShaders(ctx: Context) {
195
- // const scene = ctx.scene;
196
- // const gl = ctx.renderer;
197
- // scene.traverse(object => {
198
- // if ((object as Mesh).isMesh) {
199
- // const mesh = object as Mesh;
200
- // if (Array.isArray(mesh.material)) {
201
- // mesh.material.forEach(mat => gl.properties.remove(mat));
202
- // }
203
- // else {
204
- // gl.properties.remove(mesh.material);
205
- // }
206
- // }
207
- // })
208
- // if (gl.info?.programs)
209
- // gl.info.programs.length = 0;
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 { NeedleEngineHTMLElement } from "./webcomponents/needle-engine.js";
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 NeedleEngineHTMLElement;
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 { NeedleEngineHTMLElement } = await import("./needle-engine.js");
14
- if (!NeedleEngineHTMLElement.observedAttributes.includes(name))
15
- NeedleEngineHTMLElement.observedAttributes.push(name);
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 NeedleEngineHTMLElement extends HTMLElement implements INeedleEngineComponent {
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 attribute = this.getAttribute("tonemapping") || this.getAttribute("tone-mapping") as TonemappingAttributeOptions | null | undefined;
525
- switch (attribute?.toLowerCase()) {
526
- case "none":
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, NeedleEngineHTMLElement);
795
+ window.customElements.define(htmlTagName, NeedleEngineWebComponent);
807
796
 
808
797
 
809
798
 
@@ -6,7 +6,7 @@ import { Context } from "../engine/engine_context.js";
6
6
  import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry.js";
7
7
  import type { ICamera, IContext } from "../engine/engine_types.js";
8
8
  import { getParam } from "../engine/engine_utils.js";
9
- import { NeedleEngineHTMLElement } from "../engine/webcomponents/needle-engine.js";
9
+ import { NeedleEngineWebComponent } from "../engine/webcomponents/needle-engine.js";
10
10
  import { Camera, ClearFlags } from "./Camera.js";
11
11
  import { OrbitControls } from "./OrbitControls.js";
12
12
  import { EnvironmentScene } from "./utils/EnvironmentScene.js";
@@ -69,7 +69,7 @@ ContextRegistry.registerCallback(ContextEvent.MissingCamera, (evt) => {
69
69
  cameraObject.position.y = 1;
70
70
  cameraObject.position.z = 2;
71
71
 
72
- const engineElement = evt.context.domElement as NeedleEngineHTMLElement
72
+ const engineElement = evt.context.domElement as NeedleEngineWebComponent
73
73
  // If the camera is missing and the <needle-engine controls> is not set to false, create default camera controls
74
74
  // That way we still create controls if the attribute is not added to <needle-engine> at all
75
75
  if (engineElement?.cameraControls != false) {
@@ -92,7 +92,7 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreated, (evt) => {
92
92
  }
93
93
 
94
94
  // check if <needle-engine camera-controls> attribute is present or enabled
95
- const engineElement = evt.context.domElement as NeedleEngineHTMLElement
95
+ const engineElement = evt.context.domElement as NeedleEngineWebComponent
96
96
  if (engineElement?.cameraControls == true) {
97
97
 
98
98
  // Check if something else already acts as a camera controller