@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.
- package/core/collection/HashMap.d.ts +2 -0
- package/core/collection/HashMap.js +22 -0
- package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
- package/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -0
- package/core/geom/3d/normal/octahedron/decode_octahedron_to_unit.js +31 -0
- package/core/geom/3d/normal/octahedron/encode_unit_to_octahedron.js +33 -0
- package/core/geom/3d/normal/octahedron/encoding.spec.js +29 -0
- package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
- package/core/geom/3d/topology/struct/BinaryTopology.js +112 -0
- package/core/geom/Quaternion.js +14 -0
- package/core/math/sign_not_zero.js +8 -0
- package/core/parser/simple/SimpleParser.js +3 -86
- package/core/parser/simple/readUnsignedInteger.js +66 -0
- package/core/parser/simple/skipWhitespace.js +21 -0
- package/engine/EngineHarness.js +13 -3
- package/engine/asset/AssetDescription.spec.js +27 -0
- package/engine/asset/loaders/GLTFAssetLoader.js +5 -3
- package/engine/ecs/foliage/ImpostorFoliage.js +4 -0
- package/engine/ecs/transform/Transform.js +23 -3
- package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
- package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +213 -0
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +237 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
- package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +22 -7
- package/engine/graphics/filter/ImageFilter.js +2 -1
- package/engine/graphics/geometry/MikkT/MikkTSpace.js +466 -305
- package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +7 -1
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeBufferAttributeHash.js +1 -1
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryEquality.js +2 -2
- package/engine/{asset/loaders/geometry/geometry → graphics/geometry/buffered}/computeGeometryHash.js +1 -1
- package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +2 -2
- package/engine/graphics/impostors/card_cluster/FacePlaneAssignment.js +30 -0
- package/engine/graphics/impostors/card_cluster/README.md +13 -0
- package/engine/graphics/impostors/octahedral/ImpostorBaker.js +345 -0
- package/engine/graphics/impostors/octahedral/ImpostorCaptureType.js +10 -0
- package/engine/graphics/impostors/octahedral/ImpostorDescription.js +69 -0
- package/engine/graphics/impostors/octahedral/README.md +30 -0
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +45 -0
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
- package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +117 -0
- package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +20 -0
- package/engine/graphics/impostors/octahedral/grid/OctahedralUvEncoder.js +25 -0
- package/engine/graphics/impostors/octahedral/grid/UvEncoder.js +21 -0
- package/engine/graphics/impostors/octahedral/prototypeBaker.js +237 -0
- package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +196 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderStandard.js +306 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/common.glsl +206 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
- package/engine/graphics/micron/convert_three_object_to_micron.js +2 -2
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +2 -2
- package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
- package/engine/graphics/particles/node-based/codegen/CodeGenerator.js +1 -1
- package/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.js +1 -1
- package/engine/graphics/render/forward_plus/LightManager.js +1 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +1 -3
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +2 -1
- package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
- package/engine/graphics/render/visibility/hiz/buildCanvasViewFromTexture.js +32 -10
- package/engine/graphics/shaders/ScreenSpaceQuadShader.js +4 -14
- package/engine/graphics/shaders/glsl_gen_swizzled_read.js +39 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
- package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
- package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
- package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
- package/engine/ui/GUIEngine.js +8 -1
- package/package.json +1 -1
- package/view/tooltip/gml/parser/readReferenceToken.js +1 -1
- 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
|
+
}
|