@woosh/meep-engine 2.138.16 → 2.138.17

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 (54) hide show
  1. package/editor/Editor.d.ts.map +1 -1
  2. package/editor/SelectionVisualizer.d.ts.map +1 -1
  3. package/editor/actions/concrete/ComponentAddAction.d.ts.map +1 -1
  4. package/editor/actions/concrete/EntityCreateAction.d.ts.map +1 -1
  5. package/editor/actions/concrete/SelectionAddAction.d.ts.map +1 -1
  6. package/editor/enableEditor.d.ts.map +1 -1
  7. package/package.json +1 -1
  8. package/src/engine/ecs/grid/HeightMap2AOMap.d.ts +25 -0
  9. package/src/engine/ecs/grid/HeightMap2AOMap.d.ts.map +1 -0
  10. package/src/engine/ecs/grid/HeightMap2AOMap.js +95 -0
  11. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +15 -7
  12. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts.map +1 -1
  13. package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +44 -99
  14. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  15. package/src/engine/ecs/terrain/ecs/Terrain.js +36 -0
  16. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts +1 -1
  17. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
  18. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +3 -1
  19. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts +12 -1
  20. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  21. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +21 -0
  22. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.d.ts.map +1 -1
  23. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.js +2 -14
  24. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.d.ts.map +1 -1
  25. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.js +1 -7
  26. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.d.ts.map +1 -1
  27. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.js +1 -6
  28. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.d.ts.map +1 -1
  29. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.js +1 -6
  30. package/src/engine/graphics/material/TerrainDepthMaterial.d.ts +36 -0
  31. package/src/engine/graphics/material/TerrainDepthMaterial.d.ts.map +1 -0
  32. package/src/engine/graphics/material/TerrainDepthMaterial.js +65 -0
  33. package/src/engine/graphics/shaders/AmbientOcclusionShader.d.ts +69 -12
  34. package/src/engine/graphics/shaders/AmbientOcclusionShader.d.ts.map +1 -1
  35. package/src/engine/graphics/shaders/AmbientOcclusionShader.js +371 -128
  36. package/src/engine/graphics/util/build_max_height_pyramid.d.ts +25 -0
  37. package/src/engine/graphics/util/build_max_height_pyramid.d.ts.map +1 -0
  38. package/src/engine/graphics/util/build_max_height_pyramid.js +100 -0
  39. package/editor/ecs/component/FieldDescriptor.d.ts +0 -27
  40. package/editor/ecs/component/FieldDescriptor.d.ts.map +0 -1
  41. package/editor/ecs/component/FieldValueAdapter.d.ts +0 -7
  42. package/editor/ecs/component/FieldValueAdapter.d.ts.map +0 -1
  43. package/editor/ecs/component/createFieldEditor.d.ts +0 -9
  44. package/editor/ecs/component/createFieldEditor.d.ts.map +0 -1
  45. package/editor/ecs/component/createObjectEditor.d.ts +0 -14
  46. package/editor/ecs/component/createObjectEditor.d.ts.map +0 -1
  47. package/editor/ecs/component/findNearestRegisteredType.d.ts +0 -8
  48. package/editor/ecs/component/findNearestRegisteredType.d.ts.map +0 -1
  49. package/src/engine/ecs/grid/HeightMap2NormalMap.d.ts +0 -10
  50. package/src/engine/ecs/grid/HeightMap2NormalMap.d.ts.map +0 -1
  51. package/src/engine/ecs/grid/HeightMap2NormalMap.js +0 -72
  52. package/src/engine/ecs/grid/NormalMap2AOMap.d.ts +0 -15
  53. package/src/engine/ecs/grid/NormalMap2AOMap.d.ts.map +0 -1
  54. package/src/engine/ecs/grid/NormalMap2AOMap.js +0 -82
@@ -1 +1 @@
1
- {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["Editor.js"],"names":[],"mappings":";AAwYA;;;;;GAKG;AACH,gCA+MC;;IA9MG,6BAAwC;IACxC,uBAAkC;IAClC,qBAA2B;IAC3B,oCAAwC;IACxC,0CAAyD;IACzD,yBAAoC;IAEpC;;;OAGG;IACH,sBAFU,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAEO;IAIrC,qBAAuC;IAEvC,uCAAkD;IAElD,iBAAgB;IAEhB,kBAAoB;IAsLpB;yBAvBW,aAAa;MAyBvB;IAGL,mBAaC;IANG,uBAAyB;IAEzB,cAAmC;IAGnC,oBAAsB;IAG1B;;;OAGG;IACH,oBAFW,GAAG,QA6Bb;IAED;;;OAGG;IACH,eAFW,MAAM,iBAkDhB;IA3CG,eAAoB;IA6CxB;;;OAGG;IACH,2BAFW,KAAK,QAqBf;IAED,6BAMC;IAED,eA+BC;IAED;;;;OAIG;IACH,uBAHW,GAAG,GACD,OAAO,CAInB;;8BA5sB6B,4BAA4B;uBAEnC,8BAA8B;iBA5DpC,qCAAqC;gCAatB,6CAA6C;oCA8CzC,0BAA0B;4BAFlC,0BAA0B;mBA1CnC,6BAA6B;+BAyCjB,6BAA6B;uBAMrC,sBAAsB"}
1
+ {"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["Editor.js"],"names":[],"mappings":";AAwYA;;;;;GAKG;AACH,gCA+MC;;IA9MG,6BAAwC;IACxC,uBAAkC;IAClC,qBAA2B;IAC3B,oCAAwC;IACxC,0CAAyD;IACzD,yBAAoC;IAEpC;;;OAGG;IACH,sBAFU,IAAI,GAAG,aAAa,CAEO;IAIrC,qBAAuC;IAEvC,uCAAkD;IAElD,iBAAgB;IAEhB,kBAAoB;IAsLpB;yBAvBW,aAAa;MAyBvB;IAGL,mBAaC;IANG,uBAAyB;IAEzB,cAAmC;IAGnC,oBAAsB;IAG1B;;;OAGG;IACH,+BA2BC;IAED;;;OAGG;IACH,sCAgDC;IA3CG,eAAoB;IA6CxB;;;OAGG;IACH,wCAmBC;IAED,6BAMC;IAED,eA+BC;IAED;;;;OAIG;IACH,6BAFa,OAAO,CAInB;;8BA5sB6B,4BAA4B;uBAEnC,8BAA8B;iBA5DpC,qCAAqC;gCAatB,6CAA6C;oCA8CzC,0BAA0B;4BAFlC,0BAA0B;mBA1CnC,6BAA6B;+BAyCjB,6BAA6B;uBAMrC,sBAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionVisualizer.d.ts","sourceRoot":"","sources":["SelectionVisualizer.js"],"names":[],"mappings":"AA8EA;IACI;;;;OAIG;IACH,oBAHW,MAAM,EAoDhB;IAhDG,eAAoB;IAWN,aAAwB;IA4BtC;;;MAGC;IAED,0BAGC;IAGL,gBAQC;IAED,iBASC;CACJ;sBA3JgC,OAAO;8BAEV,4CAA4C"}
1
+ {"version":3,"file":"SelectionVisualizer.d.ts","sourceRoot":"","sources":["SelectionVisualizer.js"],"names":[],"mappings":"AA8EA;IACI;;;;OAIG;IACH,4BAiDC;IAhDG,eAAoB;IAWN,aAAwB;IA4BtC;;;MAGC;IAED,0BAGC;IAGL,gBAQC;IAED,iBASC;CACJ;sBA3JgC,OAAO;8BAEV,4CAA4C"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentAddAction.d.ts","sourceRoot":"","sources":["ComponentAddAction.js"],"names":[],"mappings":";AAEA;IACI,yCASC;IAPG,YAAoB;IACpB,eAA0B;IAC1B;;;OAGG;IACH,SAFU,sBAAsB,CAEb;IAGvB,kCAqBC;IAED,mCAGC;CACJ;uBAzCsB,0CAA0C"}
1
+ {"version":3,"file":"ComponentAddAction.d.ts","sourceRoot":"","sources":["ComponentAddAction.js"],"names":[],"mappings":";AAEA;IACI,yCASC;IAPG,YAAoB;IACpB,eAA0B;IAC1B;;;OAGG;IACH,gCAAmB;IAGvB,kCAqBC;IAED,mCAGC;CACJ;uBAzCsB,0CAA0C"}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityCreateAction.d.ts","sourceRoot":"","sources":["EntityCreateAction.js"],"names":[],"mappings":";AAEA;IACI,cAaC;IAXG;;;OAGG;IACH,QAFU,MAAM,GAAC,IAAI,CAEH;IAElB;;;OAGG;IACH,KAFU,sBAAsB,CAEjB;IAGnB,kCAkBC;IAED,mCAEC;CACJ;uBAzCsB,0CAA0C"}
1
+ {"version":3,"file":"EntityCreateAction.d.ts","sourceRoot":"","sources":["EntityCreateAction.js"],"names":[],"mappings":";AAEA;IACI,cAaC;IAXG;;;OAGG;IACH,QAFU,MAAM,GAAC,IAAI,CAEH;IAElB;;;OAGG;IACH,4BAAe;IAGnB,kCAkBC;IAED,mCAEC;CACJ;uBAzCsB,0CAA0C"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionAddAction.d.ts","sourceRoot":"","sources":["SelectionAddAction.js"],"names":[],"mappings":";AAGA;IACI;;;;OAIG;IACH,sBAHW,GAAG,EAAE,EAWf;IANG,cAAoB;IACpB;;;OAGG;IACH,UAFU,GAAG,EAAE,CAES;IAG5B,kCAMC;IAED,mCAEC;CACJ;uBA9BsB,0CAA0C"}
1
+ {"version":3,"file":"SelectionAddAction.d.ts","sourceRoot":"","sources":["SelectionAddAction.js"],"names":[],"mappings":";AAGA;IACI;;;;OAIG;IACH,sBAHW,KAAK,EAWf;IANG,cAAoB;IACpB;;;OAGG;IACH,UAFU,KAAK,CAES;IAG5B,kCAMC;IAED,mCAEC;CACJ;uBA9BsB,0CAA0C"}
@@ -1 +1 @@
1
- {"version":3,"file":"enableEditor.d.ts","sourceRoot":"","sources":["enableEditor.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,qCAJW,MAAM,mBACN,CAAS,IAAM,EAAN,MAAM,KAAE,GAAC,GAChB;IAAC,MAAM,WAAU;IAAC,OAAO,WAAW;IAAC,MAAM,WAAW;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAsElF;mBA5EkB,aAAa"}
1
+ {"version":3,"file":"enableEditor.d.ts","sourceRoot":"","sources":["enableEditor.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,qEAHoB,MAAM;;;;YACkD,MAAM;EAsEjF;mBA5EkB,aAAa"}
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Pure JavaScript game engine. Fully featured and production ready.",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.138.16",
8
+ "version": "2.138.17",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -0,0 +1,25 @@
1
+ export default heightMap2AOMap;
2
+ /**
3
+ * Bake an ambient occlusion / visibility map for a heightfield terrain.
4
+ *
5
+ * Pipeline:
6
+ * 1. Build a max-reduction Hi-Z pyramid from the heightmap (pre-pass).
7
+ * 2. Run {@link AmbientOcclusionShader} which traces `rayCount`
8
+ * cosine-weighted rays per output texel against the pyramid.
9
+ * 3. Bilateral denoise to clean up Monte Carlo speckle.
10
+ *
11
+ * The output is a single-channel visibility map (1 = fully lit, 0 = fully
12
+ * occluded) packed into a {@link Sampler2D}.
13
+ *
14
+ * @param {WebGLRenderer} renderer
15
+ * @param {Sampler2D} heightMap single-channel Float32 heightmap
16
+ * @param {Vector2} resultSize output AO resolution in texels
17
+ * @param {Vector2} [worldSize] terrain XZ extent in world units;
18
+ * defaults to heightmap pixel dimensions (= 1 world unit per heightmap texel)
19
+ * @param {number} [rayCount=64] Monte Carlo samples per output texel
20
+ * @returns {Sampler2D} single-channel Uint8 visibility map
21
+ */
22
+ declare function heightMap2AOMap(renderer: WebGLRenderer, heightMap: Sampler2D, resultSize: Vector2, worldSize?: Vector2, rayCount?: number): Sampler2D;
23
+ import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
24
+ import { Vector2 } from 'three';
25
+ //# sourceMappingURL=HeightMap2AOMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeightMap2AOMap.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/grid/HeightMap2AOMap.js"],"names":[],"mappings":";AA6BA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qEAPW,SAAS,cACT,OAAO,cACP,OAAO,aAEP,MAAM,GACJ,SAAS,CA6CrB;0BAxFyB,6CAA6C;wBAJiB,OAAO"}
@@ -0,0 +1,95 @@
1
+ import { ClampToEdgeWrapping, DataTexture, RGBAFormat, UnsignedByteType, Vector2 } from 'three';
2
+ import ImageFilter from '../../graphics/filter/ImageFilter.js';
3
+ import AmbientOcclusionShader from '../../graphics/shaders/AmbientOcclusionShader.js';
4
+ import { DenoiseShader } from "../../graphics/shaders/DenoiseShader.js";
5
+ import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
6
+ import { build_max_height_pyramid } from "../../graphics/util/build_max_height_pyramid.js";
7
+
8
+ /**
9
+ * Wrap a Uint8 buffer as an RGBA8 texture suitable for the denoise pass.
10
+ *
11
+ * @param {Uint8Array|Uint8ClampedArray} data
12
+ * @param {number} width
13
+ * @param {number} height
14
+ * @returns {DataTexture}
15
+ */
16
+ function filter_result_to_texture(data, width, height) {
17
+ const result = new DataTexture();
18
+ result.format = RGBAFormat;
19
+ result.type = UnsignedByteType;
20
+ result.flipY = false;
21
+ result.image = { data, width, height };
22
+ result.wrapS = ClampToEdgeWrapping;
23
+ result.wrapT = ClampToEdgeWrapping;
24
+ result.repeat.set(1, 1);
25
+ result.needsUpdate = true;
26
+ result.anisotropy = 4;
27
+ return result;
28
+ }
29
+
30
+ /**
31
+ * Bake an ambient occlusion / visibility map for a heightfield terrain.
32
+ *
33
+ * Pipeline:
34
+ * 1. Build a max-reduction Hi-Z pyramid from the heightmap (pre-pass).
35
+ * 2. Run {@link AmbientOcclusionShader} which traces `rayCount`
36
+ * cosine-weighted rays per output texel against the pyramid.
37
+ * 3. Bilateral denoise to clean up Monte Carlo speckle.
38
+ *
39
+ * The output is a single-channel visibility map (1 = fully lit, 0 = fully
40
+ * occluded) packed into a {@link Sampler2D}.
41
+ *
42
+ * @param {WebGLRenderer} renderer
43
+ * @param {Sampler2D} heightMap single-channel Float32 heightmap
44
+ * @param {Vector2} resultSize output AO resolution in texels
45
+ * @param {Vector2} [worldSize] terrain XZ extent in world units;
46
+ * defaults to heightmap pixel dimensions (= 1 world unit per heightmap texel)
47
+ * @param {number} [rayCount=64] Monte Carlo samples per output texel
48
+ * @returns {Sampler2D} single-channel Uint8 visibility map
49
+ */
50
+ function heightMap2AOMap(
51
+ renderer,
52
+ heightMap,
53
+ resultSize,
54
+ worldSize = new Vector2(heightMap.width, heightMap.height),
55
+ rayCount = 64
56
+ ) {
57
+ const width = resultSize.x;
58
+ const height = resultSize.y;
59
+
60
+ // Pre-pass: max-height pyramid for Hi-Z ray traversal
61
+ const pyramid_texture = build_max_height_pyramid(heightMap);
62
+ const max_mip_level = pyramid_texture.mipmaps.length - 1;
63
+
64
+ // AO bake
65
+ const shader_ao = AmbientOcclusionShader({ numRays: rayCount });
66
+ shader_ao.uniforms.heightMap.value = pyramid_texture;
67
+ shader_ao.uniforms.worldSize.value.set(worldSize.x, worldSize.y);
68
+ shader_ao.uniforms.heightMapSize.value.set(heightMap.width, heightMap.height);
69
+ shader_ao.uniforms.maxMipLevel.value = max_mip_level;
70
+
71
+ const raw_ao = ImageFilter(renderer, width, height, shader_ao);
72
+
73
+ // Denoise: bilateral filter smooths Monte Carlo noise while preserving
74
+ // visibility edges (cliff bases, ridges)
75
+ const shader_denoise = new DenoiseShader(2);
76
+ shader_denoise.uniforms.source.value = filter_result_to_texture(raw_ao.array, width, height);
77
+ shader_denoise.uniforms.pixelOffset.value.set(1 / width, 1 / height);
78
+
79
+ const smooth_ao = ImageFilter(renderer, width, height, shader_denoise);
80
+
81
+ // Pack red channel back into a single-channel Uint8 sampler — that's what
82
+ // the terrain material consumes as aoMap
83
+ const result = new Sampler2D(new Uint8ClampedArray(width * height), 1, width, height);
84
+ const size = width * height;
85
+ for (let i = 0; i < size; i++) {
86
+ result.data[i] = smooth_ao.array[i * 4];
87
+ }
88
+
89
+ // Free the upload-only pyramid texture
90
+ pyramid_texture.dispose();
91
+
92
+ return result;
93
+ }
94
+
95
+ export default heightMap2AOMap;
@@ -1,11 +1,19 @@
1
1
  /**
2
+ * Bake a terrain ambient-occlusion / visibility lightmap into `texture`.
2
3
  *
3
- * @param {THREE.DataTexture} texture
4
- * @param {Vector2} [resolution]
5
- * @param {Sampler2D} heightSampler
6
- * @param {number} [rayLength]
7
- * @param {Vector2} [worldSize]
8
- * @returns {Promise}
4
+ * Uses {@link heightMap2AOMap} which traces `rayCount` cosine-weighted rays
5
+ * per output texel against a Hi-Z height pyramid of the heightmap. See
6
+ * {@link AmbientOcclusionShader} for the tracer details and trade-offs.
7
+ *
8
+ * @param {THREE.DataTexture} texture target lightmap (red channel written)
9
+ * @param {Sampler2D} heightSampler single-channel Float32 heightmap
10
+ * @param {Vector2} [resolution] output AO resolution; defaults to
11
+ * texture dimensions
12
+ * @param {Vector2} [worldSize] terrain XZ extent in world units;
13
+ * defaults to the AO resolution (= 1 world unit per output texel)
14
+ * @param {number} [rayCount=64] Monte Carlo samples per output texel.
15
+ * Higher = less noise, longer bake. Noise falls as 1 / sqrt(rayCount).
16
+ * @returns {Promise<void>}
9
17
  */
10
- export function buildLightTexture({ texture, heightSampler, resolution, rayLength, worldSize }: THREE.DataTexture): Promise<any>;
18
+ export function buildLightTexture({ texture, heightSampler, resolution, worldSize, rayCount }: THREE.DataTexture): Promise<void>;
11
19
  //# sourceMappingURL=BuildLightTexture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuildLightTexture.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/BuildLightTexture.js"],"names":[],"mappings":"AAmEA;;;;;;;;GAQG;AACH,gGAPW,MAAM,WAAW,gBA6B3B"}
1
+ {"version":3,"file":"BuildLightTexture.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/BuildLightTexture.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AACH,+FAVW,MAAM,WAAW,GAQf,QAAQ,IAAI,CAAC,CAuBzB"}
@@ -1,99 +1,44 @@
1
- import Vector2 from "../../../../core/geom/Vector2.js";
2
- import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
3
- import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
4
- import heightMap2NormalMap from "../../grid/HeightMap2NormalMap.js";
5
- import normalMap2AOMap from "../../grid/NormalMap2AOMap.js";
6
-
7
- /**
8
- *
9
- * @param {WebGLRenderer} renderer
10
- * @param {Sampler2D} sampler
11
- * @returns {Promise<Sampler2D>}
12
- */
13
- function promiseSamplerNormal(renderer, sampler) {
14
-
15
- console.time("generating normal map");
16
- const normalSampler = heightMap2NormalMap(renderer, sampler);
17
- console.timeEnd("generating normal map");
18
-
19
-
20
- return Promise.resolve(normalSampler);
21
- }
22
-
23
- /**
24
- *
25
- * @param {WebGLRenderer} renderer
26
- * @param {Promise<Sampler2D>} pSamplerNormal
27
- * @param {Sampler2D} samplerHeight
28
- * @param {Vector2} resolution
29
- * @param {Vector2} [wordSize]
30
- * @param {number} rayLength
31
- * @returns {Promise<unknown>}
32
- */
33
- function promiseSamplerAO(
34
- {
35
- renderer,
36
- pSamplerNormal,
37
- samplerHeight,
38
- resolution,
39
- wordSize = resolution,
40
- rayLength
41
- }
42
- ) {
43
- return new Promise(function (resolve, reject) {
44
- Promise.all([pSamplerNormal]).then(function (values) {
45
- const samplerNormal = values[0];
46
- console.time("generating AO map");
47
- const occlusionSampler = normalMap2AOMap(
48
- renderer,
49
- samplerHeight,
50
- samplerNormal,
51
- wordSize,
52
- resolution,
53
- rayLength
54
- );
55
- console.timeEnd("generating AO map");
56
- //console.info(occlusionSampler);
57
- //
58
- // paintSamplerOnHTML(samplerHeight, 0, 0, 40, 3);
59
- // paintSamplerOnHTML(samplerNormal, 1, 0, 128, 1);
60
- // paintSamplerOnHTML(occlusionSampler, 2, 0, 1, 0);
61
- //
62
- //
63
- resolve(occlusionSampler);
64
- }, reject);
65
- });
66
- }
67
-
68
- /**
69
- *
70
- * @param {THREE.DataTexture} texture
71
- * @param {Vector2} [resolution]
72
- * @param {Sampler2D} heightSampler
73
- * @param {number} [rayLength]
74
- * @param {Vector2} [worldSize]
75
- * @returns {Promise}
76
- */
77
- export function buildLightTexture({
78
- texture,
79
- heightSampler,
80
- resolution = new Vector2(texture.image.width, texture.image.height),
81
- rayLength = 11,
82
- worldSize = resolution
83
- }) {
84
-
85
- return WebGLRendererPool.global.useAsync(async renderer => {
86
- const normal = promiseSamplerNormal(renderer, heightSampler);
87
-
88
- const ao = await promiseSamplerAO({
89
- renderer: renderer,
90
- pSamplerNormal: normal,
91
- samplerHeight: heightSampler,
92
- resolution: resolution,
93
- rayLength: rayLength,
94
- worldSize
95
- });
96
-
97
- writeSample2DDataToDataTexture(ao, texture);
98
- });
99
- }
1
+ import Vector2 from "../../../../core/geom/Vector2.js";
2
+ import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
3
+ import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
4
+ import heightMap2AOMap from "../../grid/HeightMap2AOMap.js";
5
+
6
+ /**
7
+ * Bake a terrain ambient-occlusion / visibility lightmap into `texture`.
8
+ *
9
+ * Uses {@link heightMap2AOMap} which traces `rayCount` cosine-weighted rays
10
+ * per output texel against a Hi-Z height pyramid of the heightmap. See
11
+ * {@link AmbientOcclusionShader} for the tracer details and trade-offs.
12
+ *
13
+ * @param {THREE.DataTexture} texture target lightmap (red channel written)
14
+ * @param {Sampler2D} heightSampler single-channel Float32 heightmap
15
+ * @param {Vector2} [resolution] output AO resolution; defaults to
16
+ * texture dimensions
17
+ * @param {Vector2} [worldSize] terrain XZ extent in world units;
18
+ * defaults to the AO resolution (= 1 world unit per output texel)
19
+ * @param {number} [rayCount=64] Monte Carlo samples per output texel.
20
+ * Higher = less noise, longer bake. Noise falls as 1 / sqrt(rayCount).
21
+ * @returns {Promise<void>}
22
+ */
23
+ export function buildLightTexture({
24
+ texture,
25
+ heightSampler,
26
+ resolution = new Vector2(texture.image.width, texture.image.height),
27
+ worldSize = resolution,
28
+ rayCount = 64
29
+ }) {
30
+
31
+ return WebGLRendererPool.global.useAsync(async renderer => {
32
+ console.time("generating AO map");
33
+ const ao = heightMap2AOMap(
34
+ renderer,
35
+ heightSampler,
36
+ resolution,
37
+ worldSize,
38
+ rayCount
39
+ );
40
+ console.timeEnd("generating AO map");
41
+
42
+ writeSample2DDataToDataTexture(ao, texture);
43
+ });
44
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Terrain.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/Terrain.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Terrain.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/ecs/Terrain.js"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import Vector2 from '../../../../core/geom/Vector2.js';
16
16
  import { clamp } from "../../../../core/math/clamp.js";
17
17
  import { GameAssetType } from "../../../asset/GameAssetType.js";
18
18
  import { SplatMaterial } from "../../../graphics/material/SplatMaterial.js";
19
+ import { makeTerrainDepthMaterial } from "../../../graphics/material/TerrainDepthMaterial.js";
19
20
  import { Sampler2D } from '../../../graphics/texture/sampler/Sampler2D.js';
20
21
  import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
21
22
  import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
@@ -160,6 +161,18 @@ class Terrain {
160
161
  */
161
162
  this.material = new SplatMaterial({});
162
163
 
164
+ /**
165
+ * Custom depth material attached to each terrain tile mesh as
166
+ * `mesh.customDepthMaterial`. Sinks recorded depth into the surface
167
+ * so the terrain does not self-shadow at creases. See
168
+ * {@link makeTerrainDepthMaterial} for the trade-off this makes.
169
+ * The bias strength is exposed via {@link Terrain#shadowBias}.
170
+ *
171
+ * @readonly
172
+ * @type {MeshDepthMaterial}
173
+ */
174
+ this.depthMaterial = makeTerrainDepthMaterial();
175
+
163
176
  /**
164
177
  * whether or not frustum culling is enabled
165
178
  * @type {boolean}
@@ -187,6 +200,7 @@ class Terrain {
187
200
  */
188
201
  this.__tiles = new TerrainTileManager({
189
202
  material: this.material,
203
+ depthMaterial: this.depthMaterial,
190
204
  buildWorker: this.__buildWorker
191
205
  });
192
206
 
@@ -257,6 +271,28 @@ class Terrain {
257
271
  return (this.flags & flag) === flag;
258
272
  }
259
273
 
274
+ /**
275
+ * Object-space distance the terrain is pushed along its negative
276
+ * geometric normal when it renders into a shadow map. See
277
+ * {@link makeTerrainDepthMaterial} for the mechanism and trade-off.
278
+ *
279
+ * Default ({@link makeTerrainDepthMaterial}) is conservative. Increase
280
+ * if hairline self-shadow faults are still visible at creases; decrease
281
+ * if other objects' contact shadows on the terrain look too shrunken.
282
+ *
283
+ * The value is in object space, so it scales with the terrain's
284
+ * transform. With a default 1:1 terrain transform it is also world units.
285
+ *
286
+ * @returns {number}
287
+ */
288
+ get shadowBias() {
289
+ return this.depthMaterial.userData.shadowBias.value;
290
+ }
291
+
292
+ set shadowBias(v) {
293
+ this.depthMaterial.userData.shadowBias.value = v;
294
+ }
295
+
260
296
  /**
261
297
  *
262
298
  * @param {GraphicsEngine} graphics
@@ -8,7 +8,7 @@ export class SplatMapping {
8
8
  */
9
9
  size: Vector2;
10
10
  /**
11
- *
11
+ * number of layers
12
12
  * @type {number}
13
13
  */
14
14
  depth: number;
@@ -1 +1 @@
1
- {"version":3,"file":"SplatMapping.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/splat/SplatMapping.js"],"names":[],"mappings":"AAaA;;GAEG;AACH;IAEQ;;;OAGG;IACH,MAFU,OAAO,CAEY;IAE7B;;;OAGG;IACH,OAFU,MAAM,CAEF;IAOd;;;OAGG;IACH,eAFU,kBAAkB,CAEiE;IAUjG;;;;;;;MAQC;IAED;;;;;;;aA6BC;IAED;;;;;OAKG;IACH,8BAJW,SAAS,SACT,MAAM,YACN,MAAM,QAiDhB;IAED;;;;;OAKG;IACH,gCAJW,SAAS,SACT,MAAM,YACN,MAAM,QA2BhB;IAED;;;;;;;OAOG;IACH,wBANW,UAAU,gBACV,MAAM,gBACN,MAAM,eACN,MAAM,gBACN,MAAM,QA2ChB;IAED;;;;;;;OAOG;IACH,4BANW,UAAU,WACV,MAAM,WACN,MAAM,SACN,MAAM,UACN,MAAM,QAuChB;IAED;;;;;;OAMG;IACH,gBALW,MAAM,KACN,MAAM,iBACN,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,SAAS,CAcrB;IAED;;OAEG;IACH,iDAEC;IAED;;;OAGG;IACH,mDAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;;OAIG;IACH,gCAHW,UAAU,QAoDpB;IAED,gBAEC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAuCnB;IAED;;;;OAIG;IACH,8BAHW,MAAM,SACN,MAAM,QAqBhB;IAED,uBAiBC;IAED;;;;;;OAMG;IACH,cALW,MAAM,UACN,MAAM,SACN,MAAM,cACN,OAAO,QA6DjB;CACJ;oBA7hBmB,qCAAqC;mCALoC,OAAO;0BAU1E,mDAAmD"}
1
+ {"version":3,"file":"SplatMapping.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/ecs/terrain/ecs/splat/SplatMapping.js"],"names":[],"mappings":"AAaA;;GAEG;AACH;IAEQ;;;OAGG;IACH,MAFU,OAAO,CAEY;IAE7B;;;OAGG;IACH,OAFU,MAAM,CAEF;IAOd;;;OAGG;IACH,eAFU,kBAAkB,CAEiE;IAUjG;;;;;;;MAQC;IAED;;;;;;;aA6BC;IAED;;;;;OAKG;IACH,8BAJW,SAAS,SACT,MAAM,YACN,MAAM,QAmDhB;IAED;;;;;OAKG;IACH,gCAJW,SAAS,SACT,MAAM,YACN,MAAM,QA2BhB;IAED;;;;;;;OAOG;IACH,wBANW,UAAU,gBACV,MAAM,gBACN,MAAM,eACN,MAAM,gBACN,MAAM,QA2ChB;IAED;;;;;;;OAOG;IACH,4BANW,UAAU,WACV,MAAM,WACN,MAAM,SACN,MAAM,UACN,MAAM,QAuChB;IAED;;;;;;OAMG;IACH,gBALW,MAAM,KACN,MAAM,iBACN,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,SAAS,CAcrB;IAED;;OAEG;IACH,iDAEC;IAED;;;OAGG;IACH,mDAEC;IAED;;;OAGG;IACH,iCAEC;IAED;;;;OAIG;IACH,gCAHW,UAAU,QAoDpB;IAED,gBAEC;IAED;;;;OAIG;IACH,yBAHW,MAAM,GACJ,OAAO,CAuCnB;IAED;;;;OAIG;IACH,8BAHW,MAAM,SACN,MAAM,QAqBhB;IAED,uBAiBC;IAED;;;;;;OAMG;IACH,cALW,MAAM,UACN,MAAM,SACN,MAAM,cACN,OAAO,QA6DjB;CACJ;oBA/hBmB,qCAAqC;mCALoC,OAAO;0BAU1E,mDAAmD"}
@@ -23,7 +23,7 @@ export class SplatMapping {
23
23
  this.size = new Vector2(1, 1);
24
24
 
25
25
  /**
26
- *
26
+ * number of layers
27
27
  * @type {number}
28
28
  */
29
29
  this.depth = 1;
@@ -141,6 +141,8 @@ export class SplatMapping {
141
141
 
142
142
  }
143
143
 
144
+ // mark for update
145
+ this.weightTexture.needsUpdate = true;
144
146
  }
145
147
 
146
148
  /**
@@ -4,9 +4,12 @@ declare class TerrainTileManager {
4
4
  *
5
5
  * @param {Vector2} [tileSize]
6
6
  * @param {Material} [material]
7
+ * @param {Material} [depthMaterial] applied to each tile mesh as
8
+ * `customDepthMaterial` so the shadow caster pass picks it up.
9
+ * Omit (null) to let three.js fall back to its default depth material.
7
10
  * @param {WorkerProxy} buildWorker
8
11
  */
9
- constructor({ material, buildWorker }?: Vector2);
12
+ constructor({ material, depthMaterial, buildWorker }?: Vector2);
10
13
  /**
11
14
  *
12
15
  * @type {TerrainTile[]}
@@ -58,6 +61,14 @@ declare class TerrainTileManager {
58
61
  */
59
62
  debugTileMaterialRandom: boolean;
60
63
  material: ObservedValue;
64
+ /**
65
+ * Optional custom depth material for the shadow caster pass. When
66
+ * non-null it is assigned to each tile mesh's `customDepthMaterial`
67
+ * field. See {@link TerrainTileManager#assignTileMaterial}.
68
+ *
69
+ * @type {Material|null}
70
+ */
71
+ depthMaterial: Material | null;
61
72
  /**
62
73
  *
63
74
  * @type {WorkerProxy}
@@ -1 +1 @@
1
- {"version":3,"file":"TerrainTileManager.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/tiles/TerrainTileManager.js"],"names":[],"mappings":";AA4BA;IA6DI;;;;;OAKG;IACH,wCAJW,OAAO,EA8BjB;IA5FD;;;OAGG;IACH,OAFU,WAAW,EAAE,CAEZ;IAEX;;;MAGE;IAEF;;;OAGG;IACH,UAFU,OAAO,CAEc;IAE/B;;;OAGG;IACH,WAFU,OAAO,CAEa;IAC9B;;;OAGG;IACH,YAFU,eAAe,CAEW;IAEpC;;;OAGG;IACH,OAFU,OAAO,CAES;IAG1B;;;;OAIG;IACH,oBAAmC;IAEnC;;;OAGG;IACH,cAFU,GAAG,CAEG;IAEhB;;;OAGG;IACH,aAFU,eAAe,CAEe;IAExC;;;OAGG;IACH,yBAFU,OAAO,CAEe;IAqB5B,wBAA2C;IAG3C;;;OAGG;IACH,yBAA8B;IAQlC,iCAWC;IAED,8BAEC;IAED;;;;OAIG;IACH,2BAHW,MAAM,cACN,MAAM,QAiChB;IAED,mBAIC;IAED;;;OAGG;IACH,yBAFW,WAAW,QAerB;IAED;;;;OAIG;IACH,6CASC;IAED,qBAqBC;IAED;;OAEG;IACH,gBAIC;IAED;;;;;;OAMG;IACH,qBALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAuBhB;IAGD;;;;;;;OAOG;IACH,oCANW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,WAAW,EAAE,CAgCzB;IAED,wBAgDC;IAED;;;;;OAKG;IACH,oBAJW,MAAM,KACN,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;OAKG;IACH,UAJW,MAAM,KACN,MAAM,GACJ,WAAW,GAAC,SAAS,CAiBjC;IAED;;;;;OAKG;IACH,wBAJW,MAAM,KACN,MAAM,GACJ,WAAW,CAavB;IAED;;;;;OAKG;IACH,4BAJW,MAAM,KACN,MAAM,GACL,WAAW,GAAC,SAAS,CAahC;IAED;;;;;OAKG;IACH,+BAJW,MAAM,KACN,MAAM,GACJ,QAAQ,WAAW,CAAC,CAYhC;IAED;;;;;;OAMG;IACH,UALW,MAAM,KACN,MAAM,GACJ,QAAQ,WAAW,CAAC,CA4BhC;IAED;;;OAGG;IACH,cAFW,WAAW,QAcrB;IAED,gBASC;IAED;;;;;;OAMG;IACH,cAJW,MAAM,KACN,MAAM,QACN,WAAW,QAsCrB;IAED;;;;;;;;;;OAUG;IACH,yBATW,aAAa,WACb,MAAM,WACN,MAAM,WACN,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,OAAO,CAuDnB;IAED;;;;;;OAMG;IACH,kCALW,aAAa,KACb,MAAM,KACN,MAAM,GACL,OAAO,CAOlB;IAED;;;;;;OAMG;IACH,SALW,MAAM,KACN,MAAM,mCAuFhB;CACJ;wBAztBuB,kBAAkB;mBAVvB,0CAA0C;oBAGzC,kCAAkC;4BAG1B,2CAA2C;oBAVnD,mCAAmC;gCAQvB,mDAAmD;0BAGzD,yCAAyC;8BALrC,2CAA2C"}
1
+ {"version":3,"file":"TerrainTileManager.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/ecs/terrain/tiles/TerrainTileManager.js"],"names":[],"mappings":";AA4BA;IA6DI;;;;;;;;OAQG;IACH,uDAPW,OAAO,EA2CjB;IAzGD;;;OAGG;IACH,OAFU,WAAW,EAAE,CAEZ;IAEX;;;MAGE;IAEF;;;OAGG;IACH,UAFU,OAAO,CAEc;IAE/B;;;OAGG;IACH,WAFU,OAAO,CAEa;IAC9B;;;OAGG;IACH,YAFU,eAAe,CAEW;IAEpC;;;OAGG;IACH,OAFU,OAAO,CAES;IAG1B;;;;OAIG;IACH,oBAAmC;IAEnC;;;OAGG;IACH,cAFU,GAAG,CAEG;IAEhB;;;OAGG;IACH,aAFU,eAAe,CAEe;IAExC;;;OAGG;IACH,yBAFU,OAAO,CAEe;IAyB5B,wBAA2C;IAE3C;;;;;;OAMG;IACH,eAFU,WAAS,IAAI,CAEW;IAGlC;;;OAGG;IACH,yBAA8B;IAQlC,iCAWC;IAED,8BAEC;IAED;;;;OAIG;IACH,2BAHW,MAAM,cACN,MAAM,QAiChB;IAED,mBAIC;IAED;;;OAGG;IACH,yBAFW,WAAW,QAuBrB;IAED;;;;OAIG;IACH,6CASC;IAED,qBAqBC;IAED;;OAEG;IACH,gBAIC;IAED;;;;;;OAMG;IACH,qBALW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAuBhB;IAGD;;;;;;;OAOG;IACH,oCANW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,WAAW,EAAE,CAgCzB;IAED,wBAgDC;IAED;;;;;OAKG;IACH,oBAJW,MAAM,KACN,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;OAKG;IACH,UAJW,MAAM,KACN,MAAM,GACJ,WAAW,GAAC,SAAS,CAiBjC;IAED;;;;;OAKG;IACH,wBAJW,MAAM,KACN,MAAM,GACJ,WAAW,CAavB;IAED;;;;;OAKG;IACH,4BAJW,MAAM,KACN,MAAM,GACL,WAAW,GAAC,SAAS,CAahC;IAED;;;;;OAKG;IACH,+BAJW,MAAM,KACN,MAAM,GACJ,QAAQ,WAAW,CAAC,CAYhC;IAED;;;;;;OAMG;IACH,UALW,MAAM,KACN,MAAM,GACJ,QAAQ,WAAW,CAAC,CA4BhC;IAED;;;OAGG;IACH,cAFW,WAAW,QAcrB;IAED,gBASC;IAED;;;;;;OAMG;IACH,cAJW,MAAM,KACN,MAAM,QACN,WAAW,QAsCrB;IAED;;;;;;;;;;OAUG;IACH,yBATW,aAAa,WACb,MAAM,WACN,MAAM,WACN,MAAM,cACN,MAAM,cACN,MAAM,cACN,MAAM,GACJ,OAAO,CAuDnB;IAED;;;;;;OAMG;IACH,kCALW,aAAa,KACb,MAAM,KACN,MAAM,GACL,OAAO,CAOlB;IAED;;;;;;OAMG;IACH,SALW,MAAM,KACN,MAAM,mCAuFhB;CACJ;wBA9uBuB,kBAAkB;mBAVvB,0CAA0C;oBAGzC,kCAAkC;4BAG1B,2CAA2C;oBAVnD,mCAAmC;gCAQvB,mDAAmD;0BAGzD,yCAAyC;8BALrC,2CAA2C"}
@@ -91,11 +91,15 @@ class TerrainTileManager {
91
91
  *
92
92
  * @param {Vector2} [tileSize]
93
93
  * @param {Material} [material]
94
+ * @param {Material} [depthMaterial] applied to each tile mesh as
95
+ * `customDepthMaterial` so the shadow caster pass picks it up.
96
+ * Omit (null) to let three.js fall back to its default depth material.
94
97
  * @param {WorkerProxy} buildWorker
95
98
  */
96
99
  constructor(
97
100
  {
98
101
  material,
102
+ depthMaterial = null,
99
103
  buildWorker
100
104
  }
101
105
  ) {
@@ -108,6 +112,15 @@ class TerrainTileManager {
108
112
 
109
113
  this.material = new ObservedValue(material);
110
114
 
115
+ /**
116
+ * Optional custom depth material for the shadow caster pass. When
117
+ * non-null it is assigned to each tile mesh's `customDepthMaterial`
118
+ * field. See {@link TerrainTileManager#assignTileMaterial}.
119
+ *
120
+ * @type {Material|null}
121
+ */
122
+ this.depthMaterial = depthMaterial;
123
+
111
124
 
112
125
  /**
113
126
  *
@@ -198,6 +211,14 @@ class TerrainTileManager {
198
211
  tile.material = material;
199
212
  if (tile.mesh !== null) {
200
213
  tile.mesh.material = material;
214
+
215
+ // route shadow-caster rendering through the terrain-specific
216
+ // depth material so the recorded depth is inset into the surface
217
+ // (see TerrainDepthMaterial). Leaving as undefined when none was
218
+ // supplied falls back to three.js's default depth material.
219
+ if (this.depthMaterial !== null) {
220
+ tile.mesh.customDepthMaterial = this.depthMaterial;
221
+ }
201
222
  }
202
223
  }
203
224
 
@@ -1 +1 @@
1
- {"version":3,"file":"ImpostorShaderDepthV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.js"],"names":[],"mappings":"AAsXA;;;;GAIG;AACH;IACI,cAoCC;CACJ;kCA5ZM,OAAO"}
1
+ {"version":3,"file":"ImpostorShaderDepthV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.js"],"names":[],"mappings":"AA0WA;;;;GAIG;AACH;IACI,cAoCC;CACJ;kCArZ6D,OAAO"}
@@ -1,9 +1,4 @@
1
- import {
2
- GLSL3,
3
- NoBlending,
4
- RawShaderMaterial,
5
- Vector3
6
- } from "three";
1
+ import { GLSL3, NoBlending, RawShaderMaterial, Vector3 } from "three";
7
2
 
8
3
  // Shadow-pass depth material that matches ImpostorShaderV0's surface so the
9
4
  // shadow caster silhouette agrees with what the colour pass draws. We need
@@ -172,14 +167,7 @@ const shader_vx = `
172
167
  // — i.e. the direction OPPOSITE the way the light travels, which
173
168
  // is what we want for atlas indexing (the bake's D_frame =
174
169
  // direction-from-centre-to-bake-camera = -look-direction).
175
- //
176
- // NOTE: signs verified by empirical comparison with the receiver
177
- // side, since the conventions interlock through three.js's
178
- // matrix-to-uniform pipeline in ways that are easy to get wrong
179
- // on paper. The negation below comes from the observation that
180
- // the un-negated formula produced a shadow in the exact-opposite
181
- // direction of what the truth mesh casts.
182
- vec3 pivotToCameraRay = -normalize(vec3(
170
+ vec3 pivotToCameraRay = normalize(vec3(
183
171
  modelViewMatrix[0][2],
184
172
  modelViewMatrix[1][2],
185
173
  modelViewMatrix[2][2]
@@ -1 +1 @@
1
- {"version":3,"file":"ImpostorShaderLitV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.js"],"names":[],"mappings":"AA4sBA;;;;;;;;GAQG;AACH;IACI,cA6BC;CACJ;+BA9uBM,OAAO"}
1
+ {"version":3,"file":"ImpostorShaderLitV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.js"],"names":[],"mappings":"AAssBA;;;;;;;;GAQG;AACH;IACI,cA6BC;CACJ;+BA9uB0E,OAAO"}
@@ -1,10 +1,4 @@
1
- import {
2
- Color,
3
- ShaderMaterial,
4
- UniformsLib,
5
- UniformsUtils,
6
- Vector3
7
- } from "three";
1
+ import { Color, ShaderMaterial, UniformsLib, UniformsUtils, Vector3 } from "three";
8
2
 
9
3
  // Lit variant of ImpostorShaderV0 — runs three.js's STANDARD (physical) shading
10
4
  // model so the impostor responds to scene lights and shadow maps.
@@ -1 +1 @@
1
- {"version":3,"file":"ImpostorShaderNormalsV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.js"],"names":[],"mappings":"AA+VA;;;;;;;GAOG;AACH;IACI,cAkBC;CACJ;kCAtXM,OAAO"}
1
+ {"version":3,"file":"ImpostorShaderNormalsV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.js"],"names":[],"mappings":"AA0VA;;;;;;;GAOG;AACH;IACI,cAkBC;CACJ;kCAtX6D,OAAO"}
@@ -1,9 +1,4 @@
1
- import {
2
- GLSL3,
3
- NoBlending,
4
- RawShaderMaterial,
5
- Vector3
6
- } from "three";
1
+ import { GLSL3, NoBlending, RawShaderMaterial, Vector3 } from "three";
7
2
 
8
3
  // Debug-viz variant: outputs the parallax-corrected world-space surface
9
4
  // normal as RGB, mapped (-1..+1) -> (0..1). Use this side-by-side with
@@ -1 +1 @@
1
- {"version":3,"file":"ImpostorShaderViewportDepthV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.js"],"names":[],"mappings":"AAsUA;;;;;;;;GAQG;AACH;IACI,cAkBC;CACJ;kCA9VM,OAAO"}
1
+ {"version":3,"file":"ImpostorShaderViewportDepthV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.js"],"names":[],"mappings":"AAiUA;;;;;;;;GAQG;AACH;IACI,cAkBC;CACJ;kCA9V6D,OAAO"}
@@ -1,9 +1,4 @@
1
- import {
2
- GLSL3,
3
- NoBlending,
4
- RawShaderMaterial,
5
- Vector3
6
- } from "three";
1
+ import { GLSL3, NoBlending, RawShaderMaterial, Vector3 } from "three";
7
2
 
8
3
  // Debug-viz variant: shows the parallax-corrected surface's VIEWPORT
9
4
  // depth as grayscale. This is the same value ImpostorShaderDepthV0