@woosh/meep-engine 2.40.1 → 2.42.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.
Files changed (75) hide show
  1. package/core/collection/HashMap.d.ts +2 -0
  2. package/core/collection/HashMap.js +22 -0
  3. package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
  4. package/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -0
  5. package/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.js +31 -0
  6. package/core/geom/3d/normal/octahedron/encode_unit_to_octahedron.js +33 -0
  7. package/core/geom/3d/normal/octahedron/encoding.spec.js +29 -0
  8. package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
  9. package/core/geom/3d/topology/struct/BinaryTopology.js +112 -0
  10. package/core/geom/Quaternion.js +14 -0
  11. package/core/math/sign_not_zero.js +8 -0
  12. package/core/parser/simple/SimpleParser.js +3 -86
  13. package/core/parser/simple/readUnsignedInteger.js +66 -0
  14. package/core/parser/simple/skipWhitespace.js +21 -0
  15. package/engine/EngineHarness.js +13 -3
  16. package/engine/asset/AssetDescription.spec.js +27 -0
  17. package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
  18. package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
  19. package/engine/ecs/transform/Transform.js +23 -3
  20. package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
  21. package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
  22. package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
  23. package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +213 -0
  24. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +237 -0
  25. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
  26. package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
  27. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
  28. package/engine/graphics/filter/ImageFilter.js +2 -1
  29. package/engine/graphics/geometry/MikkT/MikkTSpace.js +466 -305
  30. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
  31. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
  32. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
  33. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
  34. package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
  35. package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
  36. package/engine/graphics/impostors/card_cluster/README.md +13 -0
  37. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +345 -0
  38. package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
  39. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +69 -0
  40. package/engine/graphics/impostors/octahedral/README.md +30 -0
  41. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +45 -0
  42. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
  43. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +117 -0
  44. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
  45. package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
  46. package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
  47. package/engine/graphics/impostors/octahedral/prototypeBaker.js +237 -0
  48. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +196 -0
  49. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
  50. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
  51. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
  52. package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
  53. package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
  54. package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
  55. package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
  56. package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
  57. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
  58. package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
  59. package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
  60. package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
  61. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  62. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +1 -3
  63. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +2 -1
  64. package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
  65. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
  66. package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
  67. package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
  68. package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
  69. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
  70. package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
  71. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
  72. package/engine/ui/GUIEngine.js +8 -1
  73. package/package.json +1 -1
  74. package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
  75. package/engine/asset/GameAssetManager.js +0 -137
@@ -0,0 +1,117 @@
1
+ import { DataTexture, UnsignedByteType } from "three";
2
+
3
+ /**
4
+ *
5
+ * @param contents
6
+ * @param {Signal} cleanup_signal
7
+ * @returns {DataTexture}
8
+ */
9
+ function onePixelTexture(contents, cleanup_signal) {
10
+ const t = new DataTexture(new Uint8Array(contents), 1, 1);
11
+
12
+ t.generateMipmaps = false;
13
+ t.needsUpdate = true;
14
+ t.type = UnsignedByteType;
15
+
16
+ cleanup_signal.addOne(t.dispose, t);
17
+
18
+ return t;
19
+ }
20
+
21
+
22
+ /**
23
+ *
24
+ * @param {THREE.RawShaderMaterial} bake_material
25
+ * @param {THREE.Material | THREE.MeshStandardMaterial} source_material
26
+ * @param {Signal} cleanup_signal
27
+ * @param {number} anisotropy
28
+ */
29
+ export function prepare_bake_material({
30
+ bake_material,
31
+ source_material,
32
+ cleanup_signal,
33
+ anisotropy
34
+ }) {
35
+
36
+
37
+ const target_uniforms = bake_material.uniforms;
38
+
39
+
40
+ let texture_diffuse = null;
41
+ let texture_normal = null;
42
+ let texture_roughness = null;
43
+ let texture_metalness = null;
44
+ let texture_occlusion = null;
45
+ let texture_emissive = null;
46
+
47
+ if (source_material.isMeshStandardMaterial) {
48
+ texture_diffuse = source_material.map;
49
+ texture_normal = source_material.normalMap;
50
+ texture_roughness = source_material.roughnessMap;
51
+ texture_metalness = source_material.metalnessMap;
52
+ texture_occlusion = source_material.aoMap;
53
+ texture_emissive = source_material.emissiveMap;
54
+ } else {
55
+ if (source_material.map !== undefined && source_material.map !== null) {
56
+ texture_diffuse = source_material.map;
57
+ }
58
+ }
59
+
60
+ if (texture_diffuse === null) {
61
+ // plug white texture
62
+ texture_diffuse = onePixelTexture([255, 255, 255, 255], cleanup_signal);
63
+ }
64
+ if (texture_roughness === null) {
65
+ texture_roughness = onePixelTexture([255, 255, 255, 255], cleanup_signal);
66
+ }
67
+
68
+ if (texture_metalness === null) {
69
+ texture_metalness = onePixelTexture([0, 0, 0, 0], cleanup_signal);
70
+ }
71
+
72
+ if (texture_occlusion === null) {
73
+ texture_occlusion = onePixelTexture([255, 255, 255, 255], cleanup_signal);
74
+ }
75
+
76
+ if (texture_emissive === null) {
77
+ texture_emissive = onePixelTexture([0, 0, 0, 0], cleanup_signal);
78
+ }
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
+
102
+ target_uniforms.tDiffuse.value = texture_diffuse;
103
+ target_uniforms.tNormal.value = texture_normal;
104
+ target_uniforms.tRoughness.value = texture_roughness;
105
+ target_uniforms.tMetalness.value = texture_metalness;
106
+ target_uniforms.tOcclusion.value = texture_occlusion;
107
+ target_uniforms.tEmissive.value = texture_emissive;
108
+
109
+
110
+ target_uniforms.color.value.copy(source_material.color);
111
+
112
+ // TODO process texture transforms (offset, rotation, repeat)
113
+
114
+ bake_material.side = source_material.side;
115
+
116
+ bake_material.uniformsNeedUpdate = true;
117
+ }
@@ -0,0 +1,20 @@
1
+ import { UvEncoder } from "./UvEncoder.js";
2
+ import { vec3 } from "gl-matrix";
3
+
4
+ export class HemiOctahedralUvEncoder extends UvEncoder {
5
+ uv_to_unit(output, input) {
6
+ const px = input[0] - input[1];
7
+ const pz = -1 + input[0] + input[1];
8
+
9
+ const abs_x = Math.abs(px);
10
+ const abs_z = Math.abs(pz);
11
+
12
+ const r_y = 1 - (abs_x + abs_z);
13
+
14
+ output[0] = px;
15
+ output[1] = r_y;
16
+ output[2] = pz;
17
+
18
+ vec3.normalize(output, output);
19
+ }
20
+ }
@@ -0,0 +1,25 @@
1
+ import { UvEncoder } from "./UvEncoder.js";
2
+ import { vec3 } from "gl-matrix";
3
+
4
+ export class OctahedralUvEncoder extends UvEncoder {
5
+ uv_to_unit(output, input) {
6
+ let px = input[0] * 2 - 1;
7
+ let pz = input[1] * 2 - 1;
8
+
9
+ const abs_x = Math.abs(px);
10
+ const abs_z = Math.abs(pz);
11
+ const py = 1 - abs_x - abs_z;
12
+
13
+ if (py < 0) {
14
+ px = (px > 0 ? 1 : -1) * (1 - abs_z);
15
+ pz = (pz > 0 ? 1 : -1) * (1 - abs_x);
16
+ }
17
+
18
+ output[0] = px;
19
+ output[1] = py;
20
+ output[2] = pz;
21
+
22
+ vec3.normalize(output, output);
23
+ }
24
+
25
+ }
@@ -0,0 +1,21 @@
1
+ export class UvEncoder {
2
+ /**
3
+ *
4
+ * @param {number[]|vec3} output
5
+ * @param {number[]|vec2} input
6
+ * @returns {void}
7
+ */
8
+ uv_to_unit(output, input) {
9
+ throw new Error('Not implemented');
10
+ }
11
+
12
+ /**
13
+ *
14
+ * @param {number[]|vec2} output
15
+ * @param {number[]|vec3} input
16
+ * @returns {void}
17
+ */
18
+ unit_to_uv(output, input) {
19
+ throw new Error('Not implemented');
20
+ }
21
+ }
@@ -0,0 +1,237 @@
1
+ import { EngineHarness } from "../../../EngineHarness.js";
2
+ import { ImpostorBaker } from "./ImpostorBaker.js";
3
+ import { ShadedGeometry } from "../../ecs/mesh-v2/ShadedGeometry.js";
4
+ import sampler2D2Canvas from "../../texture/sampler/Sampler2D2Canvas.js";
5
+ import { CanvasView } from "../../../../view/elements/CanvasView.js";
6
+ import EntityBuilder from "../../../ecs/EntityBuilder.js";
7
+ import ViewportPosition from "../../../ecs/gui/position/ViewportPosition.js";
8
+ import GUIElement from "../../../ecs/gui/GUIElement.js";
9
+ import GUIElementSystem from "../../../ecs/gui/GUIElementSystem.js";
10
+ import ViewportPositionSystem from "../../../ecs/gui/position/ViewportPositionSystem.js";
11
+ import { WebGLRendererPool } from "../../render/RendererPool.js";
12
+ import { buildCanvasViewFromTexture } from "../../render/visibility/hiz/buildCanvasViewFromTexture.js";
13
+ import Vector2 from "../../../../core/geom/Vector2.js";
14
+ import { GameAssetType } from "../../../asset/GameAssetType.js";
15
+ import { three_object_to_entity_composition } from "../../ecs/mesh-v2/three_object_to_entity_composition.js";
16
+ import { Transform } from "../../../ecs/transform/Transform.js";
17
+ import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
18
+ import { ImpostorCaptureType } from "./ImpostorCaptureType.js";
19
+ import { PlaneBufferGeometry } from "three";
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 "../../../../../model/game/util/behavior/RotationBehavior.js";
32
+
33
+ /**
34
+ *
35
+ * @param {Engine} engine
36
+ * @return {Promise<void>}
37
+ */
38
+ async function main(engine) {
39
+ await EngineHarness.buildBasics({
40
+ engine,
41
+ enableWater: false,
42
+ cameraFieldOfView: 45
43
+ });
44
+
45
+ const baker = new ImpostorBaker();
46
+ const renderer = engine.graphics.renderer;
47
+ baker.renderer = renderer;
48
+
49
+
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);
62
+
63
+ const node_hierarchy = three_object_to_entity_composition(gltf_asset.create());
64
+
65
+
66
+ const objects = [];
67
+
68
+ node_hierarchy.traverse(n => {
69
+ const sg = n.entity.getComponent(ShadedGeometry);
70
+ if (sg !== null) {
71
+ objects.push({
72
+ mesh: sg,
73
+ transform: n.entity.getComponent(Transform).matrix
74
+ })
75
+ // objects.push({
76
+ // mesh: ShadedGeometry.from(new BoxBufferGeometry(), sg.material),
77
+ // transform: mat4.create()
78
+ // })
79
+ }
80
+ });
81
+
82
+ // objects.push(
83
+ // {
84
+ // mesh: ShadedGeometry.from(new BoxBufferGeometry(), new MeshStandardMaterial({
85
+ // color: 0xFF0000
86
+ // })),
87
+ // transform: mat4.create()
88
+ // }
89
+ // );
90
+
91
+ // console.profile('bake');
92
+ const id = baker.bake({
93
+ objects,
94
+ frames: 16,
95
+ resolution: 2048,
96
+ type: ImpostorCaptureType.FullSphere
97
+ });
98
+ // console.profileEnd('bake');
99
+
100
+ console.log(id);
101
+
102
+ const ctrl = buildCanvasViewFromTexture({
103
+ texture: id.rt.texture[0],
104
+ renderer: renderer,
105
+ // swizzle: ['a', 'a', 'a', 1]
106
+ // swizzle: ['r', 'g', 'b', 1]
107
+ swizzle: ['r', 'g', 'b', 'a']
108
+ });
109
+ ctrl.view.css({
110
+ opacity: 1
111
+ });
112
+ ctrl.render();
113
+
114
+ const cv = new CanvasView();
115
+ cv.size.set(id.atlas.width, id.atlas.height);
116
+ cv.css({
117
+ background: "rgba(0,0,0,0.1)"
118
+ });
119
+
120
+ sampler2D2Canvas(id.atlas, 255, 0, cv.el);
121
+
122
+ WebGLRendererPool.global.release(renderer);
123
+
124
+ new EntityBuilder()
125
+ .add(new ViewportPosition())
126
+ .add(GUIElement.fromView(cv))
127
+ // .build(engine.entityManager.dataset);
128
+
129
+ const ecd = engine.entityManager.dataset;
130
+ new EntityBuilder()
131
+ .add(new ViewportPosition({
132
+ offset: new Vector2(0, 0)
133
+ }))
134
+ .add(GUIElement.fromView(ctrl.view))
135
+ // .build(ecd);
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
+ });
142
+
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)
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
+ ;
221
+ }
222
+
223
+ new EngineHarness().initialize({
224
+ configuration(config, engine) {
225
+ config.addSystem(new GUIElementSystem(engine.gui.view, engine));
226
+ config.addSystem(new ViewportPositionSystem(engine.graphics.viewport.size));
227
+ config.addSystem(new ShadedGeometrySystem(engine));
228
+ config.addSystem(new SGMeshSystem(engine));
229
+ config.addSystem(new TransformAttachmentSystem());
230
+ config.addSystem(new BehaviorSystem(engine));
231
+
232
+ const gltfAssetLoader = new GLTFAssetLoader();
233
+
234
+ config.addLoader(GameAssetType.ModelGLTF, gltfAssetLoader);
235
+ config.addLoader(GameAssetType.ModelGLTF_JSON, gltfAssetLoader);
236
+ }
237
+ }).then(main);
@@ -0,0 +1,196 @@
1
+ //
2
+
3
+ import { Color, GLSL3, RawShaderMaterial, Vector2, Vector4 } from "three";
4
+
5
+ const shader_vx = `
6
+ in vec3 position;
7
+ in vec3 normal;
8
+ in vec2 uv;
9
+ in vec3 color;
10
+ in vec4 tangent;
11
+
12
+ out vec3 vNormal;
13
+ out vec3 vTangent;
14
+ out vec3 vBinormal;
15
+
16
+ out vec2 vUv;
17
+ out mat3 TBN;
18
+ out vec3 vColor;
19
+ out float depth;
20
+
21
+ uniform mat4 modelViewMatrix;
22
+ uniform mat4 projectionMatrix;
23
+ uniform mat3 normalMatrix;
24
+ uniform vec4 projection_params;
25
+
26
+
27
+ void main() {
28
+
29
+ vUv = uv;
30
+
31
+ vColor = color;
32
+
33
+ // get smooth normals
34
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
35
+
36
+ vec3 transformedNormal = normalMatrix * normal;
37
+
38
+ vec3 T = normalize(vec3(modelViewMatrix * tangent) );
39
+ vNormal = normalize( transformedNormal );
40
+ vec3 N = vNormal;
41
+ vec3 B = cross(N,T);
42
+
43
+ // construct Tangent Bitangent Normal matrix
44
+ TBN = mat3(T,B,N);
45
+
46
+
47
+ gl_Position = projectionMatrix * mvPosition;
48
+
49
+
50
+ depth = 1.0 + (mvPosition.z * projection_params.w);
51
+ }
52
+ `;
53
+
54
+ const shader_fg = `
55
+ precision highp float;
56
+ precision highp int;
57
+
58
+ layout(location = 0) out vec4 gColor;
59
+ layout(location = 1) out vec4 gNormal;
60
+ layout(location = 2) out vec4 gORM;
61
+
62
+ uniform vec3 color;
63
+
64
+ uniform sampler2D tDiffuse;
65
+ uniform sampler2D tNormal;
66
+ uniform sampler2D tRoughness;
67
+ uniform sampler2D tMetalness;
68
+ uniform sampler2D tOcclusion;
69
+ uniform sampler2D tEmissive;
70
+
71
+ uniform float uTextureLODBias;
72
+ uniform vec2 uAtlasResolution;
73
+
74
+ uniform vec2 repeat;
75
+
76
+ in vec3 vNormal;
77
+ in vec2 vUv;
78
+ in mat3 TBN;
79
+ in vec3 vColor;
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
+ }
108
+
109
+ void main() {
110
+ // write color to G-Buffer
111
+ vec4 diffuse_texture_sample = texture_supersample_4( tDiffuse, vUv, uTextureLODBias);
112
+
113
+ if(diffuse_texture_sample.a < 0.5){
114
+ // alpha masking
115
+ discard;
116
+ }
117
+
118
+ gColor = diffuse_texture_sample;
119
+ gColor.rgb *= vColor;
120
+ gColor.rgb *= color;
121
+
122
+ // write normals to G-Buffer
123
+ // see https://learnopengl.com/Advanced-Lighting/Normal-Mapping
124
+ vec3 normal_sample = texture_supersample_4(tNormal, vUv,uTextureLODBias).rgb*2.0 - 1.0;
125
+ vec3 normal = normalize(TBN * normal_sample);
126
+
127
+ gNormal = vec4( normal*0.5 + 0.5, depth);
128
+
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;
133
+
134
+ gORM = vec4(occlusion, roughness, metalness, 1.0);
135
+ }
136
+ `;
137
+
138
+ /**
139
+ * PBR shader:
140
+ * - albedo + alpha
141
+ * - normal
142
+ * - roughness
143
+ * - metalness
144
+ * - ambient occlusion
145
+ */
146
+ export class BakeShaderStandard extends RawShaderMaterial {
147
+ constructor() {
148
+ super({
149
+ vertexShader: shader_vx,
150
+ fragmentShader: shader_fg,
151
+ glslVersion: GLSL3,
152
+ uniforms: {
153
+ color: {
154
+ value: new Color(1, 1, 1)
155
+ },
156
+ tDiffuse: {
157
+ value: null
158
+ },
159
+ tNormal: {
160
+ value: null
161
+ },
162
+ tRoughness: {
163
+ value: null
164
+ },
165
+ tMetalness: {
166
+ value: null
167
+ },
168
+ tOcclusion: {
169
+ value: null
170
+ },
171
+ tEmissive: {
172
+ value: null
173
+ },
174
+ /**
175
+ * @see https://docs.unity3d.com/2020.3/Documentation/Manual/SL-UnityShaderVariables.html
176
+ */
177
+ projection_params: {
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)
188
+ }
189
+ }
190
+ });
191
+
192
+ this.defaultAttributeValues.tangent = [
193
+ 1, 0, 0, 1
194
+ ];
195
+ }
196
+ }