@woosh/meep-engine 2.149.0 → 2.151.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Pure JavaScript game engine. Fully featured and production ready.",
7
7
  "type": "module",
8
8
  "author": "Alexander Goldring",
9
- "version": "2.149.0",
9
+ "version": "2.151.0",
10
10
  "main": "build/meep.module.js",
11
11
  "module": "build/meep.module.js",
12
12
  "exports": {
@@ -1 +1 @@
1
- {"version":3,"file":"GraphicsEngine.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics/GraphicsEngine.js"],"names":[],"mappings":"AA2DA;IAOI;;;;;OAKG;IACH,+BAJW,MAAM,EAuKhB;IA7KD,gCAEC;IAgBG;;;;OAIG;IACH,2BAA+C;IAK/C;;;;;QAOI;;WAEG;;QAEH;;WAEG;;;;;MAMN;IAED;;OAEG;IACH,YAFU,OAAO,CAEe;IAEhC;;;OAGG;IACH,QAFU,kBAAkB,CAEU;IAWtC;;;OAGG;IACH,aAAkB;IAGlB;;;OAGG;IACH,cAFU,KAAK,CAEgB;IAK/B;;;OAGG;IACH,QAFU,MAAM,CAEI;IAEpB;;;OAGG;IACH,UAFU,aAAa,CAEH;IAGpB,+BAA0C;IAU1C;;OAEG;IACH,eAA+B;IAI/B;;;OAGG;IACH,uBAFU,kBAAkB,CAEgB;IAE5C;;;OAGG;IACH,oBAFU,iBAAiB,CAEsB;IAEjD;;;OAGG;IACH,gBAFU,iBAAiB,CAES;IAEpC;;;OAGG;IACH,sBAAoC;IAGpC;;;;OAIG;IACH,UAFU,OAAO,CAEG;IAEpB;;;OAGG;IACH,UAFU,OAAO,CAEG;IAEpB;;;OAGG;IACH,YAFU,MAAM,CAEG;IACnB,kKAcI;IAGR;;;OAGG;IACH,sBAFa,eAAe,CAI3B;IAED;;;OAGG;IACH,eAFa,aAAa,CAIzB;IAED,mBA0BC;IAED;;;OAGG;IACH,iCAOC;IAED;;;OAGG;IACH,0BAFa,MAAM,CAIlB;IAED,+BAcC;IAED,cAgEC;IAzBsB,8BAA0C;IA2BjE;;;OAGG;IACH,cAFa,MAAM,CAYlB;IAED;;OAEG;IACH,aAQC;IAED;;OAEG;IACH,yBAQC;IAED;;;;;;OAMG;IACH,yBALW,MAAM,KACN,MAAM,6CAMhB;IAED;;;;OAIG;IACH,8BAHW,iBAAe,UACf,iBAAe,QAczB;IAED;;;;;OAKG;IACH,8BAQC;IAED,0BAEC;IAED;;;OAGG;IACH,4BAFW,cAAc,QA8BxB;IAED;;OAEG;IACH,qBAqBC;IAED;;OAEG;IACH,0BAeC;IAED;;OAEG;IACH,eA8CC;;CACJ;mBAllBkB,oCAAoC;oBACnC,4BAA4B;mCAab,uCAAuC;sBAjBnE,OAAO;uBAYS,wBAAwB;8BAZxC,OAAO;4BAWc,+BAA+B;mCAKxB,uCAAuC;kCAKxC,gCAAgC;kCADhC,oCAAoC;gCAPtC,uCAAuC;+BAKxC,4BAA4B"}
1
+ {"version":3,"file":"GraphicsEngine.d.ts","sourceRoot":"","sources":["../../../../src/engine/graphics/GraphicsEngine.js"],"names":[],"mappings":"AA4DA;IAOI;;;;;OAKG;IACH,+BAJW,MAAM,EAgLhB;IAtLD,gCAEC;IAgBG;;;;OAIG;IACH,2BAA+C;IAK/C;;;;;QAOI;;WAEG;;QAEH;;WAEG;;;;;MAMN;IAED;;OAEG;IACH,YAFU,OAAO,CAEe;IAEhC;;;;;;OAMG;IACH,4BAFU,OAAO,CAEyB;IAE1C;;;OAGG;IACH,QAFU,kBAAkB,CAEU;IAWtC;;;OAGG;IACH,aAAkB;IAGlB;;;OAGG;IACH,cAFU,KAAK,CAEgB;IAK/B;;;OAGG;IACH,QAFU,MAAM,CAEI;IAEpB;;;OAGG;IACH,UAFU,aAAa,CAEH;IAGpB,+BAA0C;IAU1C;;OAEG;IACH,eAA+B;IAI/B;;;OAGG;IACH,uBAFU,kBAAkB,CAEgB;IAE5C;;;OAGG;IACH,oBAFU,iBAAiB,CAEsB;IAEjD;;;OAGG;IACH,gBAFU,iBAAiB,CAES;IAEpC;;;OAGG;IACH,sBAAoC;IAGpC;;;;OAIG;IACH,UAFU,OAAO,CAEG;IAEpB;;;OAGG;IACH,UAFU,OAAO,CAEG;IAEpB;;;OAGG;IACH,YAFU,MAAM,CAEG;IACnB,kKAcI;IAGR;;;OAGG;IACH,sBAFa,eAAe,CAI3B;IAED;;;OAGG;IACH,eAFa,aAAa,CAIzB;IAED,mBA8BC;IAED;;;;OAIG;IACH,iCAEC;IAED;;;OAGG;IACH,0BAFa,MAAM,CAIlB;IAED,+BAcC;IAED,cAgEC;IAzBsB,8BAA0C;IA2BjE;;;OAGG;IACH,cAFa,MAAM,CAYlB;IAED;;OAEG;IACH,aAQC;IAED;;OAEG;IACH,yBAQC;IAED;;;;;;OAMG;IACH,yBALW,MAAM,KACN,MAAM,6CAMhB;IAED;;;;OAIG;IACH,8BAHW,OAAO,UAAQ,UACf,OAAO,UAAQ,QAczB;IAED;;;;;OAKG;IACH,8BAQC;IAED,0BAEC;IAED;;;OAGG;IACH,4BAFW,cAAc,QA8BxB;IAED;;OAEG;IACH,qBAqBC;IAED;;OAEG;IACH,0BAeC;IAED;;OAEG;IACH,eA8CC;;CACJ;mBA5lBkB,oCAAoC;oBACnC,4BAA4B;wBACxB,4BAA4B;mCAajB,uCAAuC;sBAlBnE,OAAO;uBAaS,wBAAwB;8BAbxC,OAAO;4BAYc,+BAA+B;mCAKxB,uCAAuC;kCAKxC,gCAAgC;kCADhC,oCAAoC;gCAPtC,uCAAuC;+BAKxC,4BAA4B"}
@@ -12,6 +12,7 @@ import { assert } from "../../core/assert.js";
12
12
 
13
13
  import Signal from "../../core/events/signal/Signal.js";
14
14
  import Vector1 from "../../core/geom/Vector1.js";
15
+ import { Vector2 } from "../../core/geom/Vector2.js";
15
16
  import { max2 } from "../../core/math/max2.js";
16
17
  import EmptyView from "../../view/elements/EmptyView.js";
17
18
  import { globalMetrics } from "../metrics/GlobalMetrics.js";
@@ -114,6 +115,15 @@ export class GraphicsEngine {
114
115
  */
115
116
  this.pixelRatio = new Vector1(1);
116
117
 
118
+ /**
119
+ * Final render-target resolution, in device pixels: `viewport.size × pixelRatio × devicePixelRatio`.
120
+ * Kept in sync by {@link GraphicsEngine#updateSize}. Subscribe to `output_resolution.onChanged` to
121
+ * react to any change in the actual rendered resolution (viewport resize, supersample, or DPR change).
122
+ * @readonly
123
+ * @type {Vector2}
124
+ */
125
+ this.output_resolution = new Vector2(0, 0);
126
+
117
127
  /**
118
128
  *
119
129
  * @type {RenderLayerManager}
@@ -277,19 +287,19 @@ export class GraphicsEngine {
277
287
 
278
288
  this.layerComposer.setSize(_w, _h);
279
289
  this.frameBuffers.setSize(_w, _h);
290
+
291
+ // publish the final device-pixel render resolution; `_w/_h` already fold in the engine pixelRatio,
292
+ // so this matches the framebuffers/composit layers and what getResolution historically computed
293
+ this.output_resolution.set(_w * devicePixelRatio, _h * devicePixelRatio);
280
294
  }
281
295
 
282
296
  /**
283
- *
284
- * @param {Vector2|{set:function(x:number,y:number)}} target
297
+ * @deprecated Read {@link GraphicsEngine#output_resolution} directly (and subscribe to its
298
+ * `onChanged` signal) instead of polling through this method.
299
+ * @param {Vector2|{copy:function(v:Vector2)}} target
285
300
  */
286
301
  getResolution(target) {
287
- const ar = this.computeTotalPixelRatio();
288
-
289
- target.set(
290
- this.viewport.size.x * ar,
291
- this.viewport.size.y * ar
292
- );
302
+ target.copy(this.output_resolution);
293
303
  }
294
304
 
295
305
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AmbientOcclusionPostProcessEffect.d.ts","sourceRoot":"","sources":["../../../../../../../../src/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js"],"names":[],"mappings":"AAoBA;IAIQ,WAA0C;IAI1C,2BAQE;IAyBF;;;;OAIG;IACH,sBAA0B;IAE1B;;;;OAIG;IACH,2BAA6B;IAG7B;;;;OAIG;IACH,yBAA4B;IAE5B;;;;OAIG;IACH,wBAA2B;IAE3B,8CAUE;IAEF;;;;OAIG;IACH,uBAAwB;IAExB;;;;;OAKG;IACH,2BASE;IAKF;;;;OAIG;IACH,0BAAwD;IAK5D;;;OAGG;IACH,2BAEC;IAED;;;OAGG;IACH,wBAEC;IAED;;;;OAIG;IACH,oBAeC;IAED,iBAEC;IAED,2BAoCC;IAED,uBASC;IAED;;;OAGG;IACH,iBAwBC;IAED;;;OAGG;IACH,4BAFW,OAAO,QAiCjB;IAED;;;;OAIG;IACH,gCASC;IAED;;;;OAIG;IACH,mCAUC;IAGD,oCAcC;IAED,wBA2CC;IAED,yBAiBC;CAEJ;6BAjZ4B,uCAAuC;+BAD7D,OAAO;6CAAP,OAAO"}
1
+ {"version":3,"file":"AmbientOcclusionPostProcessEffect.d.ts","sourceRoot":"","sources":["../../../../../../../../src/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js"],"names":[],"mappings":"AAoBA;IAIQ,WAA0C;IAI1C,2BAQE;IAyBF;;;;OAIG;IACH,sBAA0B;IAE1B;;;;OAIG;IACH,2BAA6B;IAG7B;;;;OAIG;IACH,yBAA4B;IAE5B;;;;OAIG;IACH,wBAA2B;IAE3B,8CAUE;IAEF;;;;OAIG;IACH,uBAAwB;IAExB;;;;;OAKG;IACH,2BASE;IAKF;;;;OAIG;IACH,0BAAwD;IAK5D;;;OAGG;IACH,2BAEC;IAED;;;OAGG;IACH,wBAEC;IAED;;;;OAIG;IACH,oBAeC;IAED,iBAEC;IAED,2BAoCC;IAED,uBASC;IAED;;;OAGG;IACH,iBAwBC;IAED;;;OAGG;IACH,4BAFW,OAAO,QAiCjB;IAED;;;;OAIG;IACH,gCASC;IAED;;;;OAIG;IACH,mCAUC;IAGD,oCAiBC;IAED,wBA2CC;IAED,yBAiBC;CAEJ;6BApZ4B,uCAAuC;+BAD7D,OAAO;6CAAP,OAAO"}
@@ -187,8 +187,8 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
187
187
 
188
188
  const camera = this.__render_camera;
189
189
 
190
- // AO renders at half-res but samples the full-res depth buffer, so `size` is the full (depth)
191
- // resolution -- all texel math then lands on depth texel centres rather than texel boundaries
190
+ // AO renders at half-res but samples the full-res depth buffer, so `size` is the full (depth)
191
+ // resolution -- all texel math then lands on depth texel centres rather than texel boundaries
192
192
  uniforms.size.value.set(this.__composit_layer.renderTarget.width, this.__composit_layer.renderTarget.height);
193
193
 
194
194
  // setup camera
@@ -333,7 +333,10 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
333
333
  const engine = this.engine;
334
334
  const graphics = engine.graphics;
335
335
 
336
- const size = graphics.viewport.size;
336
+ // scale relative to the actual render resolution (device pixels), the same basis as the `size`
337
+ // uniform and the full-res depth buffer the AO samples -- so the half-res grid stays a clean
338
+ // fraction of the full-res grid at any devicePixelRatio / supersample factor
339
+ const size = graphics.output_resolution;
337
340
 
338
341
  // clamp to 1: a 0-sized attachment trips GL_INVALID_FRAMEBUFFER_OPERATION on clear/draw
339
342
  const target_resolution_x = Math.max(1, Math.ceil(size.x * this.__resolution_scale));
@@ -378,7 +381,7 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
378
381
  }
379
382
 
380
383
  this.__composit_layer.on.preRender.add(this.__render, this);
381
- graphics.viewport.size.onChanged.add(this.__update_render_target_size, this);
384
+ graphics.output_resolution.onChanged.add(this.__update_render_target_size, this);
382
385
 
383
386
  this.__update_render_target_size();
384
387
 
@@ -399,7 +402,7 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
399
402
  graphics.layerComposer.remove(this.__composit_layer);
400
403
 
401
404
  this.__composit_layer.on.preRender.remove(this.__render, this);
402
- graphics.viewport.size.onChanged.add(this.__update_render_target_size, this);
405
+ graphics.output_resolution.onChanged.remove(this.__update_render_target_size, this);
403
406
 
404
407
  // release memory
405
408
  this.__upscale_material.dispose();
@@ -42,7 +42,9 @@ const SAOShader = {
42
42
  // which a tapped surface counts as an occluder
43
43
  'kernelRadius': { value: 0.5 }
44
44
  },
45
- vertexShader: /* glsl */`
45
+
46
+ //language=GLSL
47
+ vertexShader:`
46
48
 
47
49
  varying vec2 vUv;
48
50
 
@@ -51,7 +53,8 @@ const SAOShader = {
51
53
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
52
54
  }`,
53
55
 
54
- fragmentShader: /* glsl */`
56
+ //language=GLSL
57
+ fragmentShader: `
55
58
 
56
59
  #include <common>
57
60
 
@@ -298,19 +301,24 @@ const SAOShader = {
298
301
 
299
302
  float sceneViewZ = getViewZ( sampleDepth );
300
303
 
301
- // the tapped surface must lie in front of (closer than) the probe to occlude it; if the
302
- // probe is in front of the surface it sits in open space and nothing is occluded
303
- // (view Z grows more negative away from the camera)
304
- if ( samplePositionVS.z >= sceneViewZ ) {
305
- continue;
306
- }
307
-
308
304
  // ...and the tapped surface must actually be within the sampling radius, otherwise we
309
305
  // have hit distant geometry through the depth buffer that does not occlude this point
310
306
  vec3 occluderVS = getViewPosition( sampleUv, sampleDepth, sceneViewZ );
311
- if ( distance( centerViewPosition, occluderVS ) > kernelRadius ) {
307
+ vec3 to_hit = occluderVS - centerViewPosition;
308
+
309
+ float distance_to_hit = length( to_hit );
310
+
311
+ if ( distance_to_hit > kernelRadius ) {
312
312
  continue;
313
313
  }
314
+
315
+ vec3 direction_to_hit = normalize(occluderVS - sampleOrigin);
316
+
317
+ if( dot( direction_to_hit, centerViewNormal) < 0.06 ){ // ~sqrt( 1/255 )
318
+ // unable to occlude
319
+ continue;
320
+ }
321
+
314
322
 
315
323
  // occluded: add this sample's weight to the numerator
316
324
  occlusion += weight;