@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
@@ -1,42 +1,45 @@
1
- import { vec3 } from "gl-matrix";
2
- import { max2 } from "../../../../../core/math/max2.js";
1
+ import { Miniball } from "../../../../../core/geom/packing/miniball/Miniball.js";
2
+ import { PointSet } from "../../../../../core/geom/packing/miniball/PointSet.js";
3
+ import { apply_mat4_transform_to_v3_array } from "../../../../../core/geom/3d/apply_mat4_transform_to_v3_array.js";
3
4
 
4
5
  /**
5
- * Computes radius of bounding sphere around origin for given group of objects
6
6
  *
7
- * NOTE: This may seem pointless, but by doing this computation on per-vertex basis we get the tightest possible bounds,
8
- * allowing us to get the best possible texture space utilization.
9
7
  * @param {{mesh:ShadedGeometry, transform:mat4}[]} objects
10
- * @returns {number}
11
8
  */
12
9
  export function compute_bounding_sphere(objects) {
13
- let distance = 0;
10
+ let total_point_count = 0;
11
+ const object_count = objects.length;
14
12
 
15
- const v3 = [];
16
- const n = objects.length;
17
- for (let i = 0; i < n; i++) {
13
+ for (let i = 0; i < object_count; i++) {
18
14
  const object = objects[i];
19
15
 
20
- const attribute = object.mesh.geometry.getAttribute('position');
16
+ const geometry = object.mesh.geometry;
21
17
 
22
- const array = attribute.array;
18
+ const attribute = geometry.getAttribute('position');
23
19
 
24
- const transform = object.transform;
20
+ total_point_count += attribute.count;
21
+ }
22
+
23
+ const final_buffer = new Float32Array(total_point_count * 3);
24
+
25
+ let pointer = 0;
26
+
27
+ for (let i = 0; i < object_count; i++) {
28
+ const object = objects[i];
25
29
 
26
- const n = array.length;
30
+ const geometry = object.mesh.geometry;
27
31
 
28
- for (let j = 0; j < n; j += 3) {
29
- v3[0] = array[j];
30
- v3[1] = array[j + 1];
31
- v3[2] = array[j + 2];
32
+ const attribute = geometry.getAttribute('position');
32
33
 
33
- vec3.transformMat4(v3, v3, transform);
34
+ const source_length = attribute.array.length;
34
35
 
35
- distance = max2(distance, vec3.length(v3));
36
- }
36
+ apply_mat4_transform_to_v3_array(attribute.array, 0, final_buffer, pointer, attribute.count, object.transform);
37
37
 
38
+ pointer += source_length;
38
39
  }
39
40
 
41
+ const points = new PointSet(total_point_count, 3, final_buffer);
42
+ const miniball = new Miniball(points);
40
43
 
41
- return distance;
44
+ return [...miniball.center(), miniball.radius()];
42
45
  }
@@ -0,0 +1,37 @@
1
+ import { max2 } from "../../../../../core/math/max2.js";
2
+ import {
3
+ sphere_radius_sqr_from_v3_array_transformed
4
+ } from "../../../../../core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js";
5
+
6
+ /**
7
+ * Computes radius of bounding sphere around origin for given group of objects
8
+ *
9
+ * NOTE: This may seem pointless, but by doing this computation on per-vertex basis we get the tightest possible bounds,
10
+ * allowing us to get the best possible texture space utilization.
11
+ * @param {{mesh:ShadedGeometry, transform:mat4}[]} objects
12
+ * @returns {number}
13
+ */
14
+ export function compute_bounding_sphere_radius_only(objects) {
15
+ let distance_sqr = 0;
16
+
17
+ const n = objects.length;
18
+ for (let i = 0; i < n; i++) {
19
+ const object = objects[i];
20
+
21
+ const attribute = object.mesh.geometry.getAttribute('position');
22
+
23
+ const array = attribute.array;
24
+
25
+ const transform = object.transform;
26
+
27
+ const n = array.length;
28
+
29
+ const radius2 = sphere_radius_sqr_from_v3_array_transformed(array, n, transform);
30
+
31
+ distance_sqr = max2(distance_sqr, radius2);
32
+
33
+ }
34
+
35
+
36
+ return Math.sqrt(distance_sqr);
37
+ }
@@ -18,13 +18,20 @@ function onePixelTexture(contents, cleanup_signal) {
18
18
  return t;
19
19
  }
20
20
 
21
+
21
22
  /**
22
23
  *
23
24
  * @param {THREE.RawShaderMaterial} bake_material
24
25
  * @param {THREE.Material | THREE.MeshStandardMaterial} source_material
25
26
  * @param {Signal} cleanup_signal
27
+ * @param {number} anisotropy
26
28
  */
27
- export function prepare_bake_material(bake_material, source_material, cleanup_signal) {
29
+ export function prepare_bake_material({
30
+ bake_material,
31
+ source_material,
32
+ cleanup_signal,
33
+ anisotropy
34
+ }) {
28
35
 
29
36
 
30
37
  const target_uniforms = bake_material.uniforms;
@@ -70,6 +77,28 @@ export function prepare_bake_material(bake_material, source_material, cleanup_si
70
77
  texture_emissive = onePixelTexture([0, 0, 0, 0], cleanup_signal);
71
78
  }
72
79
 
80
+ // set rendering parameters on textures
81
+ [
82
+ texture_diffuse,
83
+ texture_emissive,
84
+ texture_occlusion,
85
+ texture_metalness,
86
+ texture_roughness,
87
+ texture_normal
88
+ ].forEach(t => {
89
+ if (t === null) {
90
+ return;
91
+ }
92
+
93
+ const _old_a = t.anisotropy;
94
+
95
+ t.anisotropy = anisotropy;
96
+
97
+ cleanup_signal.addOne(() => {
98
+ t.anisotropy = _old_a;
99
+ });
100
+ });
101
+
73
102
  target_uniforms.tDiffuse.value = texture_diffuse;
74
103
  target_uniforms.tNormal.value = texture_normal;
75
104
  target_uniforms.tRoughness.value = texture_roughness;
@@ -9,7 +9,7 @@ export class HemiOctahedralUvEncoder extends UvEncoder {
9
9
  const abs_x = Math.abs(px);
10
10
  const abs_z = Math.abs(pz);
11
11
 
12
- const r_y = 1 - abs_x - abs_z;
12
+ const r_y = 1 - (abs_x + abs_z);
13
13
 
14
14
  output[0] = px;
15
15
  output[1] = r_y;
@@ -17,8 +17,18 @@ import { Transform } from "../../../ecs/transform/Transform.js";
17
17
  import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
18
18
  import { ImpostorCaptureType } from "./ImpostorCaptureType.js";
19
19
  import { PlaneBufferGeometry } from "three";
20
- import { ImpostorShaderStandard } from "./shader/ImpostorShaderStandard.js";
21
20
  import { ShadedGeometrySystem } from "../../ecs/mesh-v2/ShadedGeometrySystem.js";
21
+ import { ImpostorShaderV0 } from "./shader/ImpostorShaderV0.js";
22
+ import Quaternion from "../../../../core/geom/Quaternion.js";
23
+ import { DEG2RAD } from "three/src/math/MathUtils.js";
24
+ import { SGMesh } from "../../ecs/mesh-v2/aggregate/SGMesh.js";
25
+ import { SGMeshSystem } from "../../ecs/mesh-v2/aggregate/SGMeshSystem.js";
26
+ import { ShadedGeometryFlags } from "../../ecs/mesh-v2/ShadedGeometryFlags.js";
27
+ import { TransformAttachmentSystem } from "../../../ecs/transform-attachment/TransformAttachmentSystem.js";
28
+ import { BehaviorComponent } from "../../../intelligence/behavior/ecs/BehaviorComponent.js";
29
+ import Vector3 from "../../../../core/geom/Vector3.js";
30
+ import { BehaviorSystem } from "../../../intelligence/behavior/ecs/BehaviorSystem.js";
31
+ import { RotationBehavior } from "../../../intelligence/behavior/util/RotationBehavior.js";
22
32
 
23
33
  /**
24
34
  *
@@ -27,7 +37,9 @@ import { ShadedGeometrySystem } from "../../ecs/mesh-v2/ShadedGeometrySystem.js"
27
37
  */
28
38
  async function main(engine) {
29
39
  await EngineHarness.buildBasics({
30
- engine
40
+ engine,
41
+ enableWater: false,
42
+ cameraFieldOfView: 45
31
43
  });
32
44
 
33
45
  const baker = new ImpostorBaker();
@@ -35,16 +47,18 @@ async function main(engine) {
35
47
  baker.renderer = renderer;
36
48
 
37
49
 
38
- // const gltf_asset = await engine.assetManager.promise('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf', GameAssetType.ModelGLTF_JSON);
39
- // const gltf_asset = await engine.assetManager.promise('data/models/LowPolyTownshipSet/Barrel/model.gltf', GameAssetType.ModelGLTF_JSON);
40
- // const gltf_asset = await engine.assetManager.promise('data/models/LowPolyTownshipSet/Town_Hall/model.gltf', GameAssetType.ModelGLTF_JSON);
41
- // const gltf_asset = await engine.assetManager.promise('data/models/LowPolyTownshipSet/Small_house/Small_house.gltf', GameAssetType.ModelGLTF_JSON);
42
- const gltf_asset = await engine.assetManager.promise('data/models/MOBA and Tower Defense/Tree_03.gltf', GameAssetType.ModelGLTF_JSON);
43
- // const gltf_asset = await engine.assetManager.promise('data/models/samples/transform-hierarchy.glb', GameAssetType.ModelGLTF_JSON);
44
- // const gltf_asset = await engine.assetManager.promise('data/models/sponza-pbr/gltf/sponza.glb', GameAssetType.ModelGLTF_JSON);
45
- // const gltf_asset = await engine.assetManager.promise('moicon/gnutti_not_optimized/model.gltf', GameAssetType.ModelGLTF_JSON);
46
- // const gltf_asset = await engine.assetManager.promise('moicon/isiflow_Oct_15_21/2/model.gltf', GameAssetType.ModelGLTF_JSON);
47
- // const gltf_asset = await engine.assetManager.promise('moicon/Kople/EVCharger1.gltf', GameAssetType.ModelGLTF_JSON);
50
+ // const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
51
+ // const path = 'data/models/LowPolyTownshipSet/Barrel/model.gltf';
52
+ const path = 'data/models/LowPolyTownshipSet/Town_Hall/model.gltf';
53
+ // const path = 'data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf';
54
+ // const path = 'data/models/MOBA and Tower Defense/Tree_01.gltf';
55
+ // const path = 'data/models/samples/transform-hierarchy.glb';
56
+ // const path = 'data/models/sponza-pbr/gltf/sponza.glb';
57
+ // const path = 'moicon/gnutti_not_optimized/model.gltf';
58
+ // const path = 'moicon/isiflow_Oct_15_21/1/model.gltf';
59
+ // const path = 'moicon/Kople/EVCharger1.gltf';
60
+
61
+ const gltf_asset = await engine.assetManager.promise(path, GameAssetType.ModelGLTF_JSON);
48
62
 
49
63
  const node_hierarchy = three_object_to_entity_composition(gltf_asset.create());
50
64
 
@@ -74,23 +88,26 @@ async function main(engine) {
74
88
  // }
75
89
  // );
76
90
 
91
+ console.profile('bake');
77
92
  const id = baker.bake({
78
93
  objects,
79
- frames: 12,
80
- resolution: 1024,
81
- type: ImpostorCaptureType.Hemisphere
94
+ frames: 16,
95
+ resolution: 2048,
96
+ type: ImpostorCaptureType.FullSphere
82
97
  });
98
+ console.profileEnd('bake');
83
99
 
84
100
  console.log(id);
85
101
 
86
102
  const ctrl = buildCanvasViewFromTexture({
87
- texture: id.rt.texture[1],
103
+ texture: id.rt.texture[0],
88
104
  renderer: renderer,
89
105
  // swizzle: ['a', 'a', 'a', 1]
90
- swizzle: ['r', 'g', 'b', 1]
106
+ // swizzle: ['r', 'g', 'b', 1]
107
+ swizzle: ['r', 'g', 'b', 'a']
91
108
  });
92
109
  ctrl.view.css({
93
- opacity: 0.2
110
+ opacity: 1
94
111
  });
95
112
  ctrl.render();
96
113
 
@@ -115,13 +132,92 @@ async function main(engine) {
115
132
  offset: new Vector2(0, 0)
116
133
  }))
117
134
  .add(GUIElement.fromView(ctrl.view))
118
- .build(ecd);
135
+ // .build(ecd);
119
136
 
137
+ const t0 = Transform.fromJSON({
138
+ position: { x: 10, y: 0.5, z: 10 },
139
+ scale: 3,
140
+ rotation: Quaternion.fromEulerAngles(0, 90 * DEG2RAD, 0)
141
+ });
120
142
 
121
- new EntityBuilder()
122
- .add(new Transform())
123
- .add(ShadedGeometry.from(new PlaneBufferGeometry(1, 1, 1), new ImpostorShaderStandard()))
143
+ t0.scale.setScalar(3 / (id.sphere_radius * 2));
144
+
145
+ const entity_impostor = make_impostor_entity(id, t0);
146
+ entity_impostor.build(ecd);
147
+
148
+ const t1 = new Transform();
149
+ t1.copy(t0);
150
+ t1.position._add(3, 0, 0);
151
+ // t1.scale.setScalar(1.9);
152
+
153
+ const sg_mesh = SGMesh.fromURL(path);
154
+
155
+ sg_mesh.castShadow = false;
156
+ sg_mesh.receiveShadow = false;
157
+
158
+ const entity_true_mesh = new EntityBuilder();
159
+ entity_true_mesh
160
+ .add(sg_mesh)
161
+ .add(t1)
124
162
  .build(ecd);
163
+
164
+
165
+ // [entity_true_mesh, entity_impostor].forEach(e => make_spin(e));
166
+ }
167
+
168
+ /**
169
+ *
170
+ * @param {EntityBuilder} entity
171
+ * @param {number} [speed]
172
+ * @param {Vector3} [axis]
173
+ */
174
+ function make_spin(entity, speed = 1, axis = Vector3.up) {
175
+ /**
176
+ *
177
+ * @type {Transform}
178
+ */
179
+ const t = entity.getComponent(Transform);
180
+
181
+ if (t === null) {
182
+ return;
183
+ }
184
+
185
+ entity.add(BehaviorComponent.fromOne(RotationBehavior.fromJSON({
186
+ axis, speed
187
+ })));
188
+ }
189
+
190
+ /**
191
+ *
192
+ * @param {ImpostorDescription} id
193
+ * @param {Transform} t
194
+ * @returns {EntityBuilder}
195
+ */
196
+ function make_impostor_entity(id, t = new Transform()) {
197
+
198
+ const mat = new ImpostorShaderV0();
199
+
200
+ mat.uniforms.tBase.value = id.rt.texture[0];
201
+ mat.uniforms.tGeometry.value = id.rt.texture[1];
202
+ mat.uniforms.uFrames.value = id.frame_count;
203
+ mat.uniforms.uOffset.value.set(id.offset[0], id.offset[1], id.offset[2]);
204
+ mat.uniforms.uRadius.value = id.sphere_radius;
205
+ mat.uniforms.uIsFullSphere.value = id.capture_type === ImpostorCaptureType.FullSphere;
206
+
207
+ const transform = new Transform();
208
+
209
+ transform.copy(t);
210
+
211
+ const sg = ShadedGeometry.from(new PlaneBufferGeometry(1, 1, 1), mat);
212
+
213
+ sg.depth_material = mat;
214
+ sg.clearFlag(ShadedGeometryFlags.CastShadow);
215
+ sg.clearFlag(ShadedGeometryFlags.ReceiveShadow);
216
+
217
+ return new EntityBuilder()
218
+ .add(transform)
219
+ .add(sg)
220
+ ;
125
221
  }
126
222
 
127
223
  new EngineHarness().initialize({
@@ -129,6 +225,9 @@ new EngineHarness().initialize({
129
225
  config.addSystem(new GUIElementSystem(engine.gui.view, engine));
130
226
  config.addSystem(new ViewportPositionSystem(engine.graphics.viewport.size));
131
227
  config.addSystem(new ShadedGeometrySystem(engine));
228
+ config.addSystem(new SGMeshSystem(engine));
229
+ config.addSystem(new TransformAttachmentSystem());
230
+ config.addSystem(new BehaviorSystem(engine));
132
231
 
133
232
  const gltfAssetLoader = new GLTFAssetLoader();
134
233
 
@@ -1,6 +1,6 @@
1
1
  //
2
2
 
3
- import { Color, GLSL3, RawShaderMaterial, Vector4 } from "three";
3
+ import { Color, GLSL3, RawShaderMaterial, Vector2, Vector4 } from "three";
4
4
 
5
5
  const shader_vx = `
6
6
  in vec3 position;
@@ -68,6 +68,9 @@ const shader_fg = `
68
68
  uniform sampler2D tOcclusion;
69
69
  uniform sampler2D tEmissive;
70
70
 
71
+ uniform float uTextureLODBias;
72
+ uniform vec2 uAtlasResolution;
73
+
71
74
  uniform vec2 repeat;
72
75
 
73
76
  in vec3 vNormal;
@@ -75,10 +78,37 @@ const shader_fg = `
75
78
  in mat3 TBN;
76
79
  in vec3 vColor;
77
80
  in float depth;
81
+
82
+ vec4 texture_supersample_4(in sampler2D sampler, in vec2 uv, float lod_bias){
83
+ vec2 half_pixel_size = vec2(0.5) / uAtlasResolution;
84
+
85
+ // per pixel partial derivatives
86
+ vec2 dx = dFdx(uv.xy);
87
+ vec2 dy = dFdy(uv.xy);
88
+ // rotated grid uv offsets
89
+ vec2 uvOffsets = vec2(0.125, 0.375);
90
+ vec4 offsetUV = vec4(0.0, 0.0, 0.0, uTextureLODBias);
91
+
92
+ float bias = -1.0 + lod_bias;
93
+
94
+ // supersampled using 2x2 rotated grid
95
+ vec4 col;
96
+ offsetUV.xy = uv.xy + uvOffsets.x * dx + uvOffsets.y * dy;
97
+ col += texture(sampler, offsetUV.xy, bias);
98
+ offsetUV.xy = uv.xy - uvOffsets.x * dx - uvOffsets.y * dy;
99
+ col += texture(sampler, offsetUV.xy, bias);
100
+ offsetUV.xy = uv.xy + uvOffsets.y * dx - uvOffsets.x * dy;
101
+ col += texture(sampler, offsetUV.xy, bias);
102
+ offsetUV.xy = uv.xy - uvOffsets.y * dx + uvOffsets.x * dy;
103
+ col += texture(sampler, offsetUV.xy, bias);
104
+ col *= 0.25;
105
+
106
+ return col;
107
+ }
78
108
 
79
109
  void main() {
80
110
  // write color to G-Buffer
81
- vec4 diffuse_texture_sample = texture( tDiffuse, vUv);
111
+ vec4 diffuse_texture_sample = texture_supersample_4( tDiffuse, vUv, uTextureLODBias);
82
112
 
83
113
  if(diffuse_texture_sample.a < 0.5){
84
114
  // alpha masking
@@ -91,15 +121,15 @@ const shader_fg = `
91
121
 
92
122
  // write normals to G-Buffer
93
123
  // see https://learnopengl.com/Advanced-Lighting/Normal-Mapping
94
- vec3 normal_sample = texture(tNormal, vUv).rgb*2.0 - 1.0;
124
+ vec3 normal_sample = texture_supersample_4(tNormal, vUv,uTextureLODBias).rgb*2.0 - 1.0;
95
125
  vec3 normal = normalize(TBN * normal_sample);
96
126
 
97
127
  gNormal = vec4( normal*0.5 + 0.5, depth);
98
128
 
99
- float roughness = texture(tRoughness, vUv).g;
100
- float metalness = texture(tMetalness, vUv).b;
101
- float occlusion = texture(tOcclusion, vUv).r;
102
- vec3 emissive = texture(tEmissive, vUv).rgb;
129
+ float roughness = texture_supersample_4(tRoughness, vUv,uTextureLODBias).g;
130
+ float metalness = texture_supersample_4(tMetalness, vUv,uTextureLODBias).b;
131
+ float occlusion = texture_supersample_4(tOcclusion, vUv,uTextureLODBias).r;
132
+ vec3 emissive = texture_supersample_4(tEmissive, vUv,uTextureLODBias).rgb;
103
133
 
104
134
  gORM = vec4(occlusion, roughness, metalness, 1.0);
105
135
  }
@@ -146,6 +176,15 @@ export class BakeShaderStandard extends RawShaderMaterial {
146
176
  */
147
177
  projection_params: {
148
178
  value: new Vector4(0, 0, 0, 0)
179
+ },
180
+ /**
181
+ * Bias texture LOD, -0.5 pushes MIP switching a half a LOD further away, and produces more crisp-looking results
182
+ */
183
+ uTextureLODBias:{
184
+ value:-0.5
185
+ },
186
+ uAtlasResolution:{
187
+ value: new Vector2(1,1)
149
188
  }
150
189
  }
151
190
  });