@woosh/meep-engine 2.40.0 → 2.41.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 (68) hide show
  1. package/core/binary/BinaryBuffer.js +6 -1
  2. package/core/collection/HashMap.d.ts +2 -0
  3. package/core/collection/HashMap.js +22 -0
  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/topology/struct/BinaryTopology.js +112 -0
  9. package/core/geom/Quaternion.js +8 -8
  10. package/core/geom/Quaternion.spec.js +13 -0
  11. package/core/geom/Vector1.d.ts +2 -0
  12. package/core/math/sign_not_zero.js +8 -0
  13. package/core/parser/simple/SimpleParser.js +3 -86
  14. package/core/parser/simple/readUnsignedInteger.js +66 -0
  15. package/core/parser/simple/skipWhitespace.js +21 -0
  16. package/editor/view/ecs/components/common/NumberController.js +24 -6
  17. package/engine/EngineHarness.js +6 -1
  18. package/engine/asset/AssetDescription.spec.js +27 -0
  19. package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
  20. package/engine/asset/loaders/image/png/PNG.js +6 -0
  21. package/engine/asset/loaders/image/png/PNGReader.js +41 -0
  22. package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
  23. package/engine/ecs/terrain/tiles/TerrainTile.js +2 -0
  24. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
  25. package/engine/graphics/filter/ImageFilter.js +2 -1
  26. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
  27. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
  28. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
  29. package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
  30. package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
  31. package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
  32. package/engine/graphics/impostors/card_cluster/README.md +13 -0
  33. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +332 -0
  34. package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
  35. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +63 -0
  36. package/engine/graphics/impostors/octahedral/README.md +29 -0
  37. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +42 -0
  38. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +88 -0
  39. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
  40. package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
  41. package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
  42. package/engine/graphics/impostors/octahedral/prototypeBaker.js +138 -0
  43. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +157 -0
  44. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
  45. package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
  46. package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
  47. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
  48. package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
  49. package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
  50. package/engine/graphics/render/forward_plus/LightManager.js +25 -0
  51. package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +6 -2
  52. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +6 -11
  53. package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +268 -2
  54. package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
  55. package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
  56. package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
  57. package/engine/graphics/texture/atlas/AtlasPatch.js +12 -6
  58. package/engine/logging/ConsoleLoggerBackend.js +15 -0
  59. package/engine/logging/Logger.js +24 -1
  60. package/engine/logging/LoggerBackend.js +1 -0
  61. package/engine/physics/fluid/FluidField.js +9 -0
  62. package/engine/physics/fluid/effector/AbstractFluidEffector.js +6 -0
  63. package/engine/physics/fluid/effector/GlobalFluidEffector.js +12 -0
  64. package/engine/physics/fluid/effector/WakeFluidEffector.js +8 -0
  65. package/engine/ui/GUIEngine.js +8 -1
  66. package/package.json +1 -1
  67. package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
  68. package/engine/asset/GameAssetManager.js +0 -137
@@ -0,0 +1,29 @@
1
+ # Octahedral Impostor system
2
+
3
+ This system is based on the idea presented by Ryan Brucks
4
+
5
+ Conceptually, the system has 2 parts:
6
+ 1. Baking. This is where we take the source mesh, and prepare assets for impostor. These assets are mainly textures, copied from materials of the source meshes as well as depth fields.
7
+ 2. Drawing. Assets prepared during "Baking" part are being rendered, using a simple geometry (6 triangles), and performing ray marching as well as shading inside the pixel shader.
8
+
9
+ This is inherently a deferred rendering technique, where an impostor asset is represented as a collection of pre-rendered G-Buffers from different view angles, those "frames" are looked up at runtime in the shader to create the best approximation of a G-Buffer for the given projection transform, and the shading is performed. Depth is written out as well, this allows impostors to not only exist in color space, but also in depth space. The fact that impostors write depth gives them ability to be used for shadow mapping as well.
10
+
11
+ ## Limitations
12
+ * Materials. Currently only PBR rendering is supported with the following attributes recorded
13
+ * Albedo (vertex colors are included as well)
14
+ * Normal
15
+ * Metalness
16
+ * Roughness
17
+ * Ambient Occlusion
18
+ * Animations are not supported, neither vertex, nor pixel-shader based ones. The whole impostor can move around and be transformed, but the contents are static and pre-baked.
19
+ * When camera moves too close to the impostor, or an extreme projection is applied - artefacts will become visible. In case of camera getting too close - parts of the mesh that are occluded by outer shell will not become visible in the impostor, as that information is simply not captured. In cases of extreme projection - certain parts of the captured G-Buffer may undergo warping and stretching converting a handful of baked pixel to a larger number of on-screen pixels, creating pixelation and smearing. Note that impostors are not a replacement for your meshes, so use them sensibly.
20
+
21
+
22
+ ---
23
+ references:
24
+
25
+ - [2018] [Octahedral Impostors](https://shaderbits.com/blog/octahedral-impostors) by Ryan Brucks
26
+ - [2018] https://github.com/xraxra/IMP
27
+ - [2018] https://github.com/wojtekpil/Godot-Octahedral-Impostors
28
+ - [2011] BN11 : "Real-time Realistic Rendering and Lighting of Forests" by Eric Bruneton, Fabrice Neyret
29
+ - [2007] TSK07: "Fast (Spherical) Light Field Rendering with Per-Pixel Depth." by Severin Todt, Christof Rezk-Salama and Andreas Kolb
@@ -0,0 +1,42 @@
1
+ import { vec3 } from "gl-matrix";
2
+ import { max2 } from "../../../../../core/math/max2.js";
3
+
4
+ /**
5
+ * Computes radius of bounding sphere around origin for given group of objects
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
+ * @param {{mesh:ShadedGeometry, transform:mat4}[]} objects
10
+ * @returns {number}
11
+ */
12
+ export function compute_bounding_sphere(objects) {
13
+ let distance = 0;
14
+
15
+ const v3 = [];
16
+ const n = objects.length;
17
+ for (let i = 0; i < n; i++) {
18
+ const object = objects[i];
19
+
20
+ const attribute = object.mesh.geometry.getAttribute('position');
21
+
22
+ const array = attribute.array;
23
+
24
+ const transform = object.transform;
25
+
26
+ const n = array.length;
27
+
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
+
33
+ vec3.transformMat4(v3, v3, transform);
34
+
35
+ distance = max2(distance, vec3.length(v3));
36
+ }
37
+
38
+ }
39
+
40
+
41
+ return distance;
42
+ }
@@ -0,0 +1,88 @@
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
+ * @param {THREE.RawShaderMaterial} bake_material
24
+ * @param {THREE.Material | THREE.MeshStandardMaterial} source_material
25
+ * @param {Signal} cleanup_signal
26
+ */
27
+ export function prepare_bake_material(bake_material, source_material, cleanup_signal) {
28
+
29
+
30
+ const target_uniforms = bake_material.uniforms;
31
+
32
+
33
+ let texture_diffuse = null;
34
+ let texture_normal = null;
35
+ let texture_roughness = null;
36
+ let texture_metalness = null;
37
+ let texture_occlusion = null;
38
+ let texture_emissive = null;
39
+
40
+ if (source_material.isMeshStandardMaterial) {
41
+ texture_diffuse = source_material.map;
42
+ texture_normal = source_material.normalMap;
43
+ texture_roughness = source_material.roughnessMap;
44
+ texture_metalness = source_material.metalnessMap;
45
+ texture_occlusion = source_material.aoMap;
46
+ texture_emissive = source_material.emissiveMap;
47
+ } else {
48
+ if (source_material.map !== undefined && source_material.map !== null) {
49
+ texture_diffuse = source_material.map;
50
+ }
51
+ }
52
+
53
+ if (texture_diffuse === null) {
54
+ // plug white texture
55
+ texture_diffuse = onePixelTexture([255, 255, 255, 255], cleanup_signal);
56
+ }
57
+ if (texture_roughness === null) {
58
+ texture_roughness = onePixelTexture([255, 255, 255, 255], cleanup_signal);
59
+ }
60
+
61
+ if (texture_metalness === null) {
62
+ texture_metalness = onePixelTexture([0, 0, 0, 0], cleanup_signal);
63
+ }
64
+
65
+ if (texture_occlusion === null) {
66
+ texture_occlusion = onePixelTexture([255, 255, 255, 255], cleanup_signal);
67
+ }
68
+
69
+ if (texture_emissive === null) {
70
+ texture_emissive = onePixelTexture([0, 0, 0, 0], cleanup_signal);
71
+ }
72
+
73
+ target_uniforms.tDiffuse.value = texture_diffuse;
74
+ target_uniforms.tNormal.value = texture_normal;
75
+ target_uniforms.tRoughness.value = texture_roughness;
76
+ target_uniforms.tMetalness.value = texture_metalness;
77
+ target_uniforms.tOcclusion.value = texture_occlusion;
78
+ target_uniforms.tEmissive.value = texture_emissive;
79
+
80
+
81
+ target_uniforms.color.value.copy(source_material.color);
82
+
83
+ // TODO process texture transforms (offset, rotation, repeat)
84
+
85
+ bake_material.side = source_material.side;
86
+
87
+ bake_material.uniformsNeedUpdate = true;
88
+ }
@@ -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,138 @@
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 { ImpostorShaderStandard } from "./shader/ImpostorShaderStandard.js";
21
+ import { ShadedGeometrySystem } from "../../ecs/mesh-v2/ShadedGeometrySystem.js";
22
+
23
+ /**
24
+ *
25
+ * @param {Engine} engine
26
+ * @return {Promise<void>}
27
+ */
28
+ async function main(engine) {
29
+ await EngineHarness.buildBasics({
30
+ engine
31
+ });
32
+
33
+ const baker = new ImpostorBaker();
34
+ const renderer = engine.graphics.renderer;
35
+ baker.renderer = renderer;
36
+
37
+
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);
48
+
49
+ const node_hierarchy = three_object_to_entity_composition(gltf_asset.create());
50
+
51
+
52
+ const objects = [];
53
+
54
+ node_hierarchy.traverse(n => {
55
+ const sg = n.entity.getComponent(ShadedGeometry);
56
+ if (sg !== null) {
57
+ objects.push({
58
+ mesh: sg,
59
+ transform: n.entity.getComponent(Transform).matrix
60
+ })
61
+ // objects.push({
62
+ // mesh: ShadedGeometry.from(new BoxBufferGeometry(), sg.material),
63
+ // transform: mat4.create()
64
+ // })
65
+ }
66
+ });
67
+
68
+ // objects.push(
69
+ // {
70
+ // mesh: ShadedGeometry.from(new BoxBufferGeometry(), new MeshStandardMaterial({
71
+ // color: 0xFF0000
72
+ // })),
73
+ // transform: mat4.create()
74
+ // }
75
+ // );
76
+
77
+ const id = baker.bake({
78
+ objects,
79
+ frames: 12,
80
+ resolution: 1024,
81
+ type: ImpostorCaptureType.Hemisphere
82
+ });
83
+
84
+ console.log(id);
85
+
86
+ const ctrl = buildCanvasViewFromTexture({
87
+ texture: id.rt.texture[1],
88
+ renderer: renderer,
89
+ // swizzle: ['a', 'a', 'a', 1]
90
+ swizzle: ['r', 'g', 'b', 1]
91
+ });
92
+ ctrl.view.css({
93
+ opacity: 0.2
94
+ });
95
+ ctrl.render();
96
+
97
+ const cv = new CanvasView();
98
+ cv.size.set(id.atlas.width, id.atlas.height);
99
+ cv.css({
100
+ background: "rgba(0,0,0,0.1)"
101
+ });
102
+
103
+ sampler2D2Canvas(id.atlas, 255, 0, cv.el);
104
+
105
+ WebGLRendererPool.global.release(renderer);
106
+
107
+ new EntityBuilder()
108
+ .add(new ViewportPosition())
109
+ .add(GUIElement.fromView(cv))
110
+ // .build(engine.entityManager.dataset);
111
+
112
+ const ecd = engine.entityManager.dataset;
113
+ new EntityBuilder()
114
+ .add(new ViewportPosition({
115
+ offset: new Vector2(0, 0)
116
+ }))
117
+ .add(GUIElement.fromView(ctrl.view))
118
+ .build(ecd);
119
+
120
+
121
+ new EntityBuilder()
122
+ .add(new Transform())
123
+ .add(ShadedGeometry.from(new PlaneBufferGeometry(1, 1, 1), new ImpostorShaderStandard()))
124
+ .build(ecd);
125
+ }
126
+
127
+ new EngineHarness().initialize({
128
+ configuration(config, engine) {
129
+ config.addSystem(new GUIElementSystem(engine.gui.view, engine));
130
+ config.addSystem(new ViewportPositionSystem(engine.graphics.viewport.size));
131
+ config.addSystem(new ShadedGeometrySystem(engine));
132
+
133
+ const gltfAssetLoader = new GLTFAssetLoader();
134
+
135
+ config.addLoader(GameAssetType.ModelGLTF, gltfAssetLoader);
136
+ config.addLoader(GameAssetType.ModelGLTF_JSON, gltfAssetLoader);
137
+ }
138
+ }).then(main);
@@ -0,0 +1,157 @@
1
+ //
2
+
3
+ import { Color, GLSL3, RawShaderMaterial, 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 vec2 repeat;
72
+
73
+ in vec3 vNormal;
74
+ in vec2 vUv;
75
+ in mat3 TBN;
76
+ in vec3 vColor;
77
+ in float depth;
78
+
79
+ void main() {
80
+ // write color to G-Buffer
81
+ vec4 diffuse_texture_sample = texture( tDiffuse, vUv);
82
+
83
+ if(diffuse_texture_sample.a < 0.5){
84
+ // alpha masking
85
+ discard;
86
+ }
87
+
88
+ gColor = diffuse_texture_sample;
89
+ gColor.rgb *= vColor;
90
+ gColor.rgb *= color;
91
+
92
+ // write normals to G-Buffer
93
+ // see https://learnopengl.com/Advanced-Lighting/Normal-Mapping
94
+ vec3 normal_sample = texture(tNormal, vUv).rgb*2.0 - 1.0;
95
+ vec3 normal = normalize(TBN * normal_sample);
96
+
97
+ gNormal = vec4( normal*0.5 + 0.5, depth);
98
+
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;
103
+
104
+ gORM = vec4(occlusion, roughness, metalness, 1.0);
105
+ }
106
+ `;
107
+
108
+ /**
109
+ * PBR shader:
110
+ * - albedo + alpha
111
+ * - normal
112
+ * - roughness
113
+ * - metalness
114
+ * - ambient occlusion
115
+ */
116
+ export class BakeShaderStandard extends RawShaderMaterial {
117
+ constructor() {
118
+ super({
119
+ vertexShader: shader_vx,
120
+ fragmentShader: shader_fg,
121
+ glslVersion: GLSL3,
122
+ uniforms: {
123
+ color: {
124
+ value: new Color(1, 1, 1)
125
+ },
126
+ tDiffuse: {
127
+ value: null
128
+ },
129
+ tNormal: {
130
+ value: null
131
+ },
132
+ tRoughness: {
133
+ value: null
134
+ },
135
+ tMetalness: {
136
+ value: null
137
+ },
138
+ tOcclusion: {
139
+ value: null
140
+ },
141
+ tEmissive: {
142
+ value: null
143
+ },
144
+ /**
145
+ * @see https://docs.unity3d.com/2020.3/Documentation/Manual/SL-UnityShaderVariables.html
146
+ */
147
+ projection_params: {
148
+ value: new Vector4(0, 0, 0, 0)
149
+ }
150
+ }
151
+ });
152
+
153
+ this.defaultAttributeValues.tangent = [
154
+ 1, 0, 0, 1
155
+ ];
156
+ }
157
+ }