@woosh/meep-engine 2.41.0 → 2.42.1

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 (98) hide show
  1. package/core/assert.js +2 -2
  2. package/core/collection/array/array_swap.js +3 -3
  3. package/core/collection/map/AsyncLoadingCache.js +47 -0
  4. package/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js +1 -1
  5. package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
  6. package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
  7. package/core/geom/Quaternion.js +14 -0
  8. package/core/math/statistics/computeSampleSize_Cochran.js +3 -3
  9. package/editor/ecs/component/editors/geom/QuaternionEditor.js +12 -5
  10. package/engine/Engine.js +6 -1
  11. package/engine/EngineBootstrapper.js +2 -1
  12. package/engine/EngineHarness.js +13 -3
  13. package/engine/asset/AssetManager.js +97 -7
  14. package/engine/development/performance/AbstractMetric.js +1 -0
  15. package/engine/development/performance/RingBufferMetric.js +25 -4
  16. package/engine/ecs/EntityBuilder.js +29 -4
  17. package/engine/ecs/transform/Transform.js +23 -3
  18. package/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +17 -1
  19. package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
  20. package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
  21. package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
  22. package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +201 -0
  23. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +278 -0
  24. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
  25. package/engine/graphics/ecs/mesh-v2/allocate_v3.js +37 -0
  26. package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
  27. package/engine/graphics/geometry/MikkT/AddTriToGroup.js +10 -0
  28. package/engine/graphics/geometry/MikkT/AssignRecur.js +84 -0
  29. package/engine/graphics/geometry/MikkT/AvgTSpace.js +38 -0
  30. package/engine/graphics/geometry/MikkT/Build4RuleGroups.js +96 -0
  31. package/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +137 -0
  32. package/engine/graphics/geometry/MikkT/CalcTexArea.js +31 -0
  33. package/engine/graphics/geometry/MikkT/CompareSubGroups.js +26 -0
  34. package/engine/graphics/geometry/MikkT/DegenEpilogue.js +220 -0
  35. package/engine/graphics/geometry/MikkT/DegenPrologue.js +115 -0
  36. package/engine/graphics/geometry/MikkT/EvalTspace.js +128 -0
  37. package/engine/graphics/geometry/MikkT/GenerateInitialVerticesIndexList.js +48 -0
  38. package/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +184 -0
  39. package/engine/graphics/geometry/MikkT/GenerateTSpaces.js +226 -0
  40. package/engine/graphics/geometry/MikkT/GetEdge.js +45 -0
  41. package/engine/graphics/geometry/MikkT/GetNormal.js +16 -0
  42. package/engine/graphics/geometry/MikkT/GetPosition.js +25 -0
  43. package/engine/graphics/geometry/MikkT/GetTexCoord.js +18 -0
  44. package/engine/graphics/geometry/MikkT/InitTriInfo.js +180 -0
  45. package/engine/graphics/geometry/MikkT/Length.js +10 -0
  46. package/engine/graphics/geometry/MikkT/MakeIndex.js +18 -0
  47. package/engine/graphics/geometry/MikkT/MikkTSpace.js +197 -2068
  48. package/engine/graphics/geometry/MikkT/NormalizeSafe.js +21 -0
  49. package/engine/graphics/geometry/MikkT/NotZero.js +10 -0
  50. package/engine/graphics/geometry/MikkT/QuickSort.js +54 -0
  51. package/engine/graphics/geometry/MikkT/QuickSortEdges.js +71 -0
  52. package/engine/graphics/geometry/MikkT/SSubGroup.js +15 -0
  53. package/engine/graphics/geometry/MikkT/STSpace.js +36 -0
  54. package/engine/graphics/geometry/MikkT/constants/GROUP_WITH_ANY.js +1 -0
  55. package/engine/graphics/geometry/MikkT/constants/INTERNAL_RND_SORT_SEED.js +1 -0
  56. package/engine/graphics/geometry/MikkT/constants/MARK_DEGENERATE.js +1 -0
  57. package/engine/graphics/geometry/MikkT/constants/ORIENT_PRESERVING.js +1 -0
  58. package/engine/graphics/geometry/MikkT/constants/QUAD_ONE_DEGEN_TRI.js +1 -0
  59. package/engine/graphics/geometry/MikkT/m_getNormal.js +16 -0
  60. package/engine/graphics/geometry/MikkT/m_getNumFaces.js +8 -0
  61. package/engine/graphics/geometry/MikkT/m_getNumVerticesOfFace.js +11 -0
  62. package/engine/graphics/geometry/MikkT/m_getPosition.js +20 -0
  63. package/engine/graphics/geometry/MikkT/m_getTexCoord.js +16 -0
  64. package/engine/graphics/geometry/MikkT/m_setTSpace.js +35 -0
  65. package/engine/graphics/geometry/MikkT/m_setTSpaceBasic.js +22 -0
  66. package/engine/graphics/geometry/MikkT/malloc.js +16 -0
  67. package/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.js +52 -0
  68. package/engine/graphics/geometry/buffered/computeGeometryEquality.js +1 -1
  69. package/engine/graphics/geometry/buffered/computeGeometryHash.js +1 -1
  70. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +28 -14
  71. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +6 -0
  72. package/engine/graphics/impostors/octahedral/README.md +1 -0
  73. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +25 -22
  74. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
  75. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +30 -1
  76. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +1 -1
  77. package/engine/graphics/impostors/octahedral/prototypeBaker.js +121 -22
  78. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +46 -7
  79. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
  80. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
  81. package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
  82. package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
  83. package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
  84. package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
  85. package/engine/graphics/render/forward_plus/LightManager.js +17 -7
  86. package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +7 -1
  87. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +13 -5
  88. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +3 -1
  89. package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
  90. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +14 -2
  91. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
  92. package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
  93. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
  94. package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
  95. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
  96. package/engine/intelligence/behavior/util/RotationBehavior.js +69 -0
  97. package/generation/example/filters/SampleGroundMoistureFilter.js +5 -5
  98. package/package.json +1 -1
@@ -0,0 +1,21 @@
1
+ import { Length } from "./Length.js";
2
+ import { vec3 } from "gl-matrix";
3
+
4
+ /**
5
+ *
6
+ * @param {vec3} out
7
+ * @param {vec3} input
8
+ */
9
+ export function NormalizeSafe(out, input) {
10
+
11
+ const len = Length(input);
12
+
13
+ if (len !== 0) {
14
+ const m = 1 / len;
15
+
16
+ vec3.scale(out, input, m)
17
+
18
+ } else {
19
+ vec3.copy(out, input);
20
+ }
21
+ }
@@ -0,0 +1,10 @@
1
+ import { EPSILON } from "../../../../core/math/MathUtils.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number} v
6
+ * @returns {boolean}
7
+ */
8
+ export function NotZero(v) {
9
+ return Math.abs(v) > EPSILON;
10
+ }
@@ -0,0 +1,54 @@
1
+ import { assert } from "../../../../core/assert.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number[]|ArrayLike<number>|Uint32Array|Int32Array} pSortBuffer
6
+ * @param {number} iLeft
7
+ * @param {number} iRight
8
+ * @param {number} uSeed
9
+ * @returns {void}
10
+ */
11
+ export function QuickSort(pSortBuffer, iLeft, iRight, uSeed) {
12
+ let iL, iR, n, index, iMid, iTmp;
13
+
14
+ // Random
15
+ let t = uSeed & 31;
16
+ t = (uSeed << t) | (uSeed >> (32 - t));
17
+ uSeed = uSeed + t + 3;
18
+ uSeed = uSeed >>> 0; // make unsigned
19
+ // Random end
20
+
21
+ iL = iLeft;
22
+ iR = iRight;
23
+ n = (iR - iL) + 1;
24
+
25
+ assert.greaterThanOrEqual(n , 0);
26
+
27
+ index = (uSeed % n);
28
+
29
+ iMid = pSortBuffer[index + iL];
30
+
31
+
32
+ do {
33
+ while (pSortBuffer[iL] < iMid)
34
+ ++iL;
35
+ while (pSortBuffer[iR] > iMid)
36
+ --iR;
37
+
38
+ if (iL <= iR) {
39
+
40
+ iTmp = pSortBuffer[iL];
41
+ pSortBuffer[iL] = pSortBuffer[iR];
42
+ pSortBuffer[iR] = iTmp;
43
+
44
+ ++iL;
45
+ --iR;
46
+ }
47
+ }
48
+ while (iL <= iR);
49
+
50
+ if (iLeft < iR)
51
+ QuickSort(pSortBuffer, iLeft, iR, uSeed);
52
+ if (iL < iRight)
53
+ QuickSort(pSortBuffer, iL, iRight, uSeed);
54
+ }
@@ -0,0 +1,71 @@
1
+ import { array_swap } from "../../../../core/collection/array/array_swap.js";
2
+ import { assert } from "../../../../core/assert.js";
3
+
4
+ /**
5
+ *
6
+ * @param {number[]} pSortBuffer
7
+ * @param {number} iLeft
8
+ * @param {number} iRight
9
+ * @param {number} channel
10
+ * @param {number} uSeed
11
+ * @returns {void}
12
+ */
13
+ export function QuickSortEdges(pSortBuffer, iLeft, iRight, channel, uSeed) {
14
+ let t;
15
+ let iL, iR, n, index, iMid;
16
+
17
+ // early out
18
+ const iElems = iRight - iLeft + 1;
19
+
20
+ if (iElems < 2) {
21
+ return;
22
+ } else if (iElems === 2) {
23
+
24
+ if (pSortBuffer[iLeft * 3 + channel] > pSortBuffer[iRight * 3 + channel]) {
25
+
26
+ array_swap(pSortBuffer, iLeft * 3, pSortBuffer, iRight * 3, 3); // swap elements
27
+
28
+ }
29
+
30
+ return;
31
+ }
32
+
33
+ // Random
34
+ t = uSeed & 31;
35
+ t = (uSeed << t) | (uSeed >> (32 - t));
36
+ uSeed = uSeed + t + 3;
37
+
38
+ uSeed = uSeed >>> 0; // make unsigned
39
+ // Random end
40
+
41
+ iL = iLeft;
42
+ iR = iRight;
43
+ n = (iR - iL) + 1;
44
+
45
+ assert.greaterThanOrEqual(n, 0);
46
+
47
+ index = (uSeed % n);
48
+
49
+ iMid = pSortBuffer[(index + iL) * 3 + channel];
50
+
51
+ do {
52
+ while (pSortBuffer[iL * 3 + channel] < iMid)
53
+ ++iL;
54
+ while (pSortBuffer[iR * 3 + channel] > iMid)
55
+ --iR;
56
+
57
+ if (iL <= iR) {
58
+
59
+ array_swap(pSortBuffer, iL * 3, pSortBuffer, iR * 3, 3); // do swap
60
+
61
+ ++iL;
62
+ --iR;
63
+ }
64
+ }
65
+ while (iL <= iR);
66
+
67
+ if (iLeft < iR)
68
+ QuickSortEdges(pSortBuffer, iLeft, iR, channel, uSeed);
69
+ if (iL < iRight)
70
+ QuickSortEdges(pSortBuffer, iL, iRight, channel, uSeed);
71
+ }
@@ -0,0 +1,15 @@
1
+ export class SSubGroup {
2
+ constructor() {
3
+ /**
4
+ *
5
+ * @type {number}
6
+ */
7
+ this.iNrFaces = 0;
8
+
9
+ /**
10
+ * *int
11
+ * @type {Int32Array|null}
12
+ */
13
+ this.pTriMembers = null;
14
+ }
15
+ }
@@ -0,0 +1,36 @@
1
+ import { vec3 } from "gl-matrix";
2
+ import { allocate_v3 } from "../../ecs/mesh-v2/allocate_v3.js";
3
+
4
+ export class STSpace {
5
+ constructor() {
6
+ /**
7
+ *
8
+ * @type {vec3|Float32Array}
9
+ */
10
+ this.vOs = allocate_v3();
11
+ /**
12
+ *
13
+ * @type {vec3|Float32Array}
14
+ */
15
+ this.vOt = allocate_v3();
16
+
17
+ this.fMagS = 0;
18
+ this.fMagT = 0;
19
+
20
+ this.iCounter = 0; // this is to average back into quads.
21
+ this.bOrient = false;
22
+ }
23
+
24
+ /**
25
+ *
26
+ * @param {STSpace} other
27
+ */
28
+ copy(other) {
29
+ vec3.copy(this.vOs, other.vOs);
30
+ this.fMagS = other.fMagS;
31
+ vec3.copy(this.vOt, other.vOt);
32
+ this.fMagT = other.fMagT;
33
+ this.iCounter = other.iCounter;
34
+ this.bOrient = other.bOrient;
35
+ }
36
+ }
@@ -0,0 +1 @@
1
+ export const GROUP_WITH_ANY = 4;
@@ -0,0 +1 @@
1
+ export const INTERNAL_RND_SORT_SEED = 39871946;
@@ -0,0 +1 @@
1
+ export const MARK_DEGENERATE = 1;
@@ -0,0 +1 @@
1
+ export const ORIENT_PRESERVING = 8;
@@ -0,0 +1 @@
1
+ export const QUAD_ONE_DEGEN_TRI = 2;
@@ -0,0 +1,16 @@
1
+ import { array_copy } from "../../../../core/collection/array/copyArray.js";
2
+
3
+ /**
4
+ *
5
+ * @param {SMikkTSpaceContext} pContext
6
+ * @param {number[]|{0:number,1:number,2:number}} fvNormOut
7
+ * @param {number} iFace
8
+ * @param {number} iVert
9
+ * @returns {void}
10
+ */
11
+ export function m_getNormal(pContext, fvNormOut, iFace, iVert) {
12
+ // figure out which vertex it is
13
+ const vertex_index = pContext.geometry_buffer_index[iFace * 3 + iVert];
14
+
15
+ array_copy(pContext.geometry_buffer_vertex_normal, vertex_index * 3, fvNormOut, 0, 3);
16
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns the number of faces (triangles/quads) on the mesh to be processed.
3
+ * @param {SMikkTSpaceContext} pContext
4
+ * @returns {number}
5
+ */
6
+ export function m_getNumFaces(pContext) {
7
+ return pContext.geometry_buffer_index.length / 3;
8
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns the number of vertices on face number iFace
3
+ * iFace is a number in the range {0, 1, ..., getNumFaces()-1}
4
+ * @param {SMikkTSpaceContext} pContext
5
+ * @param {number} iFace
6
+ * @returns {number}
7
+ */
8
+ function m_getNumVerticesOfFace(pContext, iFace) {
9
+ // only support triangles
10
+ return 3;
11
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ *
3
+ * @param {SMikkTSpaceContext} pContext
4
+ * @param {number[]|{0:number,1:number,2:number}} fvPosOut
5
+ * @param {number} iFace
6
+ * @param {number} iVert
7
+ * @returns {void}
8
+ */
9
+ export function m_getPosition(pContext, fvPosOut, iFace, iVert) {
10
+ // figure out which vertex it is
11
+ const vertex_index = pContext.geometry_buffer_index[iFace * 3 + iVert];
12
+
13
+ const position = pContext.geometry_buffer_vertex_position;
14
+
15
+ const position_offset = vertex_index * 3;
16
+
17
+ fvPosOut[0] = position[position_offset];
18
+ fvPosOut[1] = position[position_offset + 1];
19
+ fvPosOut[2] = position[position_offset + 2];
20
+ }
@@ -0,0 +1,16 @@
1
+ import { array_copy } from "../../../../core/collection/array/copyArray.js";
2
+
3
+ /**
4
+ *
5
+ * @param {SMikkTSpaceContext} pContext
6
+ * @param {number[]|{0:number,1:number}} fvTexcOut
7
+ * @param {number} iFace
8
+ * @param {number} iVert
9
+ * @returns {void}
10
+ */
11
+ export function m_getTexCoord(pContext, fvTexcOut, iFace, iVert) {
12
+ // figure out which vertex it is
13
+ const vertex_index = pContext.geometry_buffer_index[iFace * 3 + iVert];
14
+
15
+ array_copy(pContext.geometry_buffer_vertex_uv, vertex_index * 2, fvTexcOut, 0, 3);
16
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ *
3
+ * @param {SMikkTSpaceContext} pContext
4
+ * @param {number[]} tangent
5
+ * @param {number[]} bi_tangent
6
+ * @param {number} fMagS
7
+ * @param {number} fMagT
8
+ * @param {boolean} bi_tangent_preserves_orientation
9
+ * @param {number} iFace
10
+ * @param {number} iVert
11
+ * @returns {void}
12
+ */
13
+ export function m_setTSpace(
14
+ pContext,
15
+ tangent,
16
+ bi_tangent,
17
+ fMagS,
18
+ fMagT,
19
+ bi_tangent_preserves_orientation,
20
+ iFace,
21
+ iVert
22
+ ) {
23
+
24
+ // figure out which vertex it is
25
+ const vertex_index = pContext.geometry_buffer_index[iFace * 3 + iVert];
26
+
27
+ const tangent_destination = pContext.geometry_buffer_vertex_tangent;
28
+ const tangent_address = vertex_index * 4;
29
+
30
+ // for logic explanation, see https://github.com/gltf-rs/mikktspace/blob/6275cc4f15cff8be29819fb34ae8be3b9129dae1/src/lib.rs#L33
31
+ tangent_destination[tangent_address] = tangent[0];
32
+ tangent_destination[tangent_address + 1] = tangent[1];
33
+ tangent_destination[tangent_address + 2] = tangent[2];
34
+ tangent_destination[tangent_address + 3] = bi_tangent_preserves_orientation ? 1 : -1;
35
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * either (or both) of the two setTSpace callbacks can be set.
3
+ * The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
4
+ *
5
+ * This function is used to return the tangent and fSign to the application.
6
+ * fvTangent is a unit length vector.
7
+ * For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
8
+ * bitangent = fSign * cross(vN, tangent);
9
+ * Note that the results are returned unindexed. It is possible to generate a new index list
10
+ * But averaging/overwriting tangent spaces by using an already existing index list WILL produce INCRORRECT results.
11
+ * DO NOT! use an already existing index list.
12
+ *
13
+ * @param {SMikkTSpaceContext} pContext
14
+ * @param {number[]} fvTangent
15
+ * @param {number} fSign
16
+ * @param {number} iFace
17
+ * @param {number} iVert
18
+ * @returns {void}
19
+ */
20
+ function m_setTSpaceBasic(pContext, fvTangent, fSign, iFace, iVert) {
21
+ throw new Error('Not supported');
22
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Mimics C malloc somewhat, allocates an array of class instances of fixed size
3
+ * @template T
4
+ * @param {constructor<T>} Klass
5
+ * @param {number} count
6
+ * @returns {T[]}
7
+ */
8
+ export function malloc(Klass, count) {
9
+ const r = new Array(count);
10
+
11
+ for (let i = 0; i < count; i++) {
12
+ r[i] = new Klass();
13
+ }
14
+
15
+ return r;
16
+ }
@@ -0,0 +1,52 @@
1
+ import { vec3 } from "gl-matrix";
2
+ import { v3_length } from "../../../../core/geom/v3_length.js";
3
+ import { v3_dot } from "../../../../core/geom/v3_dot.js";
4
+
5
+ /**
6
+ * executes following formula: v1 - v0*( dot(v0,v1) )
7
+ * @param {vec3} out
8
+ * @param {vec3} v0
9
+ * @param {vec3} v1
10
+ */
11
+ export function v3_scale_dot_sub_normalize(out, v0, v1) {
12
+ const v0x = v0[0];
13
+ const v0y = v0[1];
14
+ const v0z = v0[2];
15
+
16
+ const v1x = v1[0];
17
+ const v1y = v1[1];
18
+ const v1z = v1[2];
19
+
20
+ // dot product
21
+ const _dot = v3_dot(v0x, v0y, v0z, v1x, v1y, v1z);
22
+
23
+ // scale
24
+ const _x0 = v0x * _dot;
25
+ const _y0 = v0y * _dot;
26
+ const _z0 = v0z * _dot;
27
+
28
+ // subtract
29
+ const _x1 = v1x - _x0;
30
+ const _z1 = v1z - _z0;
31
+ const _y1 = v1y - _y0;
32
+
33
+ // "safe" normalization
34
+ const len = v3_length(_x1, _y1, _z1);
35
+
36
+ if (len !== 0) {
37
+
38
+ const m = 1 / len;
39
+
40
+ out[0] = _x1 * m;
41
+ out[1] = _y1 * m;
42
+ out[2] = _z1 * m;
43
+
44
+ } else {
45
+
46
+ out[0] = _x1;
47
+ out[1] = _y1;
48
+ out[2] = _z1;
49
+
50
+ }
51
+
52
+ }
@@ -1,4 +1,4 @@
1
- import { isArrayEqualStrict } from "../../../../core/collection/array/isArrayEqualStrict.d.ts";
1
+ import { isArrayEqualStrict } from "../../../../core/collection/array/isArrayEqualStrict.js";
2
2
  import { is_typed_array_equals } from "../../../../core/collection/array/typed/is_typed_array_equals.js";
3
3
 
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { computeBufferAttributeHash } from "./computeBufferAttributeHash.js";
2
- import { computeStringHash } from "../../../../core/primitives/strings/computeStringHash.d.ts";
2
+ import { computeStringHash } from "../../../../core/primitives/strings/computeStringHash.js";
3
3
 
4
4
  /**
5
5
  *
@@ -3,7 +3,7 @@ import { assert } from "../../../../core/assert.js";
3
3
  import { isPowerOfTwo } from "../../../../core/math/isPowerOrTwo.js";
4
4
  import { Mesh, OrthographicCamera, Scene, Vector4, WebGLMultipleRenderTargets } from "three";
5
5
  import { ImpostorDescription } from "./ImpostorDescription.js";
6
- import { mat4 } from "gl-matrix";
6
+ import { mat4, vec3 } from "gl-matrix";
7
7
  import { BakeShaderStandard } from "./shader/BakeShaderStandard.js";
8
8
  import { Sampler2D } from "../../texture/sampler/Sampler2D.js";
9
9
  import Signal from "../../../../core/events/signal/Signal.js";
@@ -14,8 +14,9 @@ import { UvEncoder } from "./grid/UvEncoder.js";
14
14
  import { OctahedralUvEncoder } from "./grid/OctahedralUvEncoder.js";
15
15
  import { HemiOctahedralUvEncoder } from "./grid/HemiOctahedralUvEncoder.js";
16
16
  import { prepare_bake_material } from "./bake/prepare_bake_material.js";
17
- import { compute_bounding_sphere } from "./bake/compute_bounding_sphere.js";
18
17
  import { collectIteratorValueToArray } from "../../../../core/collection/IteratorUtils.js";
18
+ import { compute_bounding_sphere } from "./bake/compute_bounding_sphere.js";
19
+ import { buffer_geometry_ensure_tangents } from "../../geometry/MikkT/buffer_geometry_ensure_tangents.js";
19
20
 
20
21
  export class ImpostorBaker {
21
22
 
@@ -37,20 +38,22 @@ export class ImpostorBaker {
37
38
 
38
39
  /**
39
40
  *
40
- * @param {number} distance
41
+ * @param {number[]|vec4} bounding_sphere
41
42
  * @param {{mesh:ShadedGeometry, transform:mat4}[]} objects
42
43
  * @param {number} resolution
43
44
  * @param {number} frames
44
45
  * @param {UvEncoder} encoder
45
46
  */
46
47
  bake_internal({
47
- distance,
48
+ bounding_sphere,
48
49
  objects,
49
50
  resolution,
50
51
  frames,
51
52
  encoder
52
53
  }) {
53
54
 
55
+ const distance = bounding_sphere[3];
56
+
54
57
  assert.isNumber(distance, 'distance');
55
58
  assert.isNonNegativeInteger(resolution, 'resolution');
56
59
  assert.isNonNegativeInteger(frames, 'frames');
@@ -66,7 +69,6 @@ export class ImpostorBaker {
66
69
  rt.texture[1].name = 'normal+depth';
67
70
  rt.texture[2].name = 'orm'; // Occlusion, Roughness, Metalness
68
71
 
69
-
70
72
  const renderer = this._renderer;
71
73
 
72
74
  // remember render state
@@ -74,6 +76,7 @@ export class ImpostorBaker {
74
76
  const _vp = new Vector4();
75
77
  renderer.getViewport(_vp);
76
78
  const _autoClear = renderer.autoClear;
79
+ const _pixelRatio = renderer.getPixelRatio();
77
80
 
78
81
  const gl = this._renderer.getContext();
79
82
 
@@ -90,6 +93,7 @@ export class ImpostorBaker {
90
93
  renderer.setRenderTarget(rt);
91
94
  renderer.setClearColor(0xFFFFFF, 0);
92
95
  renderer.clearColor();
96
+ renderer.setPixelRatio(1);
93
97
 
94
98
  const frame_width = resolution / frames;
95
99
  const frame_height = resolution / frames;
@@ -122,6 +126,7 @@ export class ImpostorBaker {
122
126
  keyEqualityFunction: computeMaterialEquality
123
127
  });
124
128
 
129
+ const max_anisotropic_filtering_level = renderer.capabilities.getMaxAnisotropy();
125
130
 
126
131
  for (let k = 0; k < object_count; k++) {
127
132
  const object = objects[k];
@@ -129,7 +134,7 @@ export class ImpostorBaker {
129
134
  const source_mesh = object.mesh;
130
135
 
131
136
  // ensure tangents are generated
132
- // buffer_geometry_ensure_tangents(source_mesh.geometry);
137
+ buffer_geometry_ensure_tangents(source_mesh.geometry);
133
138
 
134
139
  const source_material = source_mesh.material;
135
140
 
@@ -139,7 +144,14 @@ export class ImpostorBaker {
139
144
  const bake_material = new BakeShaderStandard();
140
145
 
141
146
  // prepare bake material to match the source material
142
- prepare_bake_material(bake_material, source_material, cleanup_signal);
147
+ prepare_bake_material({
148
+ bake_material: bake_material,
149
+ source_material: source_material,
150
+ cleanup_signal: cleanup_signal,
151
+ anisotropy: max_anisotropic_filtering_level
152
+ });
153
+
154
+ bake_material.uniforms.uAtlasResolution.value.set(resolution, resolution);
143
155
 
144
156
  cleanup_signal.addOne(bake_material.dispose, bake_material);
145
157
 
@@ -183,9 +195,9 @@ export class ImpostorBaker {
183
195
  encoder.uv_to_unit(unit_sphere_direction, [octahedron_u, octahedron_v]);
184
196
 
185
197
  // offset by the radius of the sphere
186
- const camera_px = distance * unit_sphere_direction[0];
187
- const camera_py = distance * unit_sphere_direction[1];
188
- const camera_pz = distance * unit_sphere_direction[2];
198
+ const camera_px = distance * unit_sphere_direction[0] + bounding_sphere[0];
199
+ const camera_py = distance * unit_sphere_direction[1] + bounding_sphere[1];
200
+ const camera_pz = distance * unit_sphere_direction[2] + bounding_sphere[2];
189
201
 
190
202
  // console.log(`UV:${octahedron_u.toFixed(2)},${octahedron_v.toFixed(2)}\t V3:${unit_sphere_direction.map(n => n.toFixed(2)).join(', ')}`);
191
203
 
@@ -203,7 +215,7 @@ export class ImpostorBaker {
203
215
  camera_pz
204
216
  );
205
217
 
206
- cam.lookAt(0, 0, 0);
218
+ cam.lookAt(bounding_sphere[0], bounding_sphere[1], bounding_sphere[2]);
207
219
  cam.updateProjectionMatrix();
208
220
 
209
221
  // update materials
@@ -237,6 +249,7 @@ export class ImpostorBaker {
237
249
  renderer.setRenderTarget(_rt);
238
250
  renderer.setViewport(_vp);
239
251
  renderer.autoClear = _autoClear;
252
+ renderer.setPixelRatio(_pixelRatio);
240
253
  if (_enabled_antialias) {
241
254
  gl.enable(gl.SAMPLE_ALPHA_TO_COVERAGE);
242
255
  }
@@ -302,7 +315,7 @@ export class ImpostorBaker {
302
315
  throw new Error('No renderer attached. Renderer is required for baking.');
303
316
  }
304
317
 
305
- const objects_radius = compute_bounding_sphere(objects);
318
+ const bounding_sphere = compute_bounding_sphere(objects);
306
319
 
307
320
  // we need to compute bounding sphere around origin of the object
308
321
  let encoder;
@@ -318,12 +331,13 @@ export class ImpostorBaker {
318
331
  resolution,
319
332
  frames,
320
333
  objects,
321
- distance: objects_radius,
334
+ bounding_sphere,
322
335
  encoder
323
336
  });
324
337
 
325
338
  r.capture_type = type;
326
- r.sphere_radius = objects_radius;
339
+ r.sphere_radius = bounding_sphere[3];
340
+ vec3.copy(r.offset, bounding_sphere);
327
341
 
328
342
  console.timeEnd('bake');
329
343
 
@@ -27,6 +27,12 @@ export class ImpostorDescription {
27
27
  */
28
28
  sphere_radius = 0;
29
29
 
30
+ /**
31
+ * Baking offset
32
+ * @type {number[]}
33
+ */
34
+ offset = [0, 0, 0];
35
+
30
36
  /**
31
37
  * Actual baked data
32
38
  * @type {Sampler2D|null}
@@ -22,6 +22,7 @@ This is inherently a deferred rendering technique, where an impostor asset is re
22
22
  ---
23
23
  references:
24
24
 
25
+ - [2021] [Rendering a Sphere on a Quad](https://bgolus.medium.com/rendering-a-sphere-on-a-quad-13c92025570c) by Ben Golus
25
26
  - [2018] [Octahedral Impostors](https://shaderbits.com/blog/octahedral-impostors) by Ryan Brucks
26
27
  - [2018] https://github.com/xraxra/IMP
27
28
  - [2018] https://github.com/wojtekpil/Godot-Octahedral-Impostors