@woosh/meep-engine 2.33.65 → 2.33.70
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/geom/2d/quad-tree/QuadTreeNode.js +3 -2
- package/core/geom/3d/triangle/computeTriangleRayIntersection.js +3 -9
- package/engine/asset/loaders/GLTFAssetLoader.js +0 -4
- package/engine/ecs/fow/FogOfWarRevealerSystem.js +8 -0
- package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +2 -10
- package/engine/ecs/grid/NormalMap2AOMap.js +10 -13
- package/engine/ecs/terrain/ecs/BuildLightTexture.js +106 -0
- package/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +59 -0
- package/engine/ecs/terrain/ecs/Terrain.js +14 -153
- package/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +10 -0
- package/engine/graphics/filter/ImageFilter.js +6 -2
- package/engine/graphics/geometry/buffered/deinterleaveBufferAttribute.js +3 -2
- package/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +28 -27
- package/engine/graphics/geometry/buffered/query/GeometryVisitor.js +29 -2
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +28 -27
- package/engine/graphics/micron/convert_three_object_to_micron.js +14 -3
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +3 -0
- package/engine/graphics/shaders/AmbientOcclusionShader.js +57 -77
- package/engine/graphics/shaders/DenoiseShader.js +119 -0
- package/engine/graphics/texture/noise_octaves.js +33 -0
- package/engine/graphics/texture/sampler/Sampler2D2Texture.js +7 -18
- package/engine/graphics/texture/sampler/debug/paintSamplerOnHTML.js +8 -5
- package/engine/graphics/texture/sampler/sampler2DToFloat32Texture.js +10 -3
- package/generation/example/SampleGenerator0.js +7 -11
- package/generation/example/filters/SampleGroundMoistureFilter.js +2 -1
- package/generation/example/main.js +215 -0
- package/generation/example/themes/SampleTheme0.js +22 -9
- package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +29 -13
- package/generation/grid/GridData.js +17 -2
- package/generation/placement/GridCellPlacementRule.js +3 -5
- package/package.json +1 -1
|
@@ -315,8 +315,9 @@ export class QuadTreeNode extends AABB2 {
|
|
|
315
315
|
const x1 = this.x1;
|
|
316
316
|
const y1 = this.y1;
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
const
|
|
318
|
+
// get center point
|
|
319
|
+
const xm = (x0 + x1) * 0.5;
|
|
320
|
+
const ym = (y0 + y1) * 0.5;
|
|
320
321
|
|
|
321
322
|
for (; i < dataLength; i++) {
|
|
322
323
|
const datum = data[i];
|
|
@@ -25,15 +25,9 @@ export function computeTriangleRayIntersection(
|
|
|
25
25
|
result,
|
|
26
26
|
origin_x, origin_y, origin_z,
|
|
27
27
|
direction_x, direction_y, direction_z,
|
|
28
|
-
ax,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
bx,
|
|
32
|
-
by,
|
|
33
|
-
bz,
|
|
34
|
-
cx,
|
|
35
|
-
cy,
|
|
36
|
-
cz
|
|
28
|
+
ax, ay, az,
|
|
29
|
+
bx, by, bz,
|
|
30
|
+
cx, cy, cz
|
|
37
31
|
) {
|
|
38
32
|
|
|
39
33
|
// edge1 = a - b
|
|
@@ -26,7 +26,6 @@ import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/trave
|
|
|
26
26
|
import { computeTextureHash } from "./material/computeTextureHash.js";
|
|
27
27
|
import { computeTextureEquality } from "./material/computeTextureEquality.js";
|
|
28
28
|
import { async_traverse_three_object } from "./async_traverse_three_object.js";
|
|
29
|
-
import { deinterleaveBufferGeometry } from "../../graphics/geometry/buffered/deinterleaveBufferGeometry.js";
|
|
30
29
|
|
|
31
30
|
const animationOptimizer = new AnimationOptimizer();
|
|
32
31
|
const materialCache = StaticMaterialCache.Global;
|
|
@@ -294,9 +293,6 @@ export class GLTFAssetLoader extends AssetLoader {
|
|
|
294
293
|
mesh.geometry = geometry;
|
|
295
294
|
}
|
|
296
295
|
|
|
297
|
-
mesh.geometry = deinterleaveBufferGeometry(geometry);
|
|
298
|
-
|
|
299
|
-
|
|
300
296
|
if (this.__enable_texture_cache) {
|
|
301
297
|
// replace textures from cache
|
|
302
298
|
replace_material_textures_from_cache(mesh.material, texture_cache);
|
|
@@ -10,6 +10,10 @@ import { obtainTerrain } from "../terrain/util/obtainTerrain.js";
|
|
|
10
10
|
const v2 = new Vector2();
|
|
11
11
|
|
|
12
12
|
export class FogOfWarRevealerSystem extends System {
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {number} team
|
|
16
|
+
*/
|
|
13
17
|
constructor(team) {
|
|
14
18
|
super();
|
|
15
19
|
|
|
@@ -19,6 +23,10 @@ export class FogOfWarRevealerSystem extends System {
|
|
|
19
23
|
|
|
20
24
|
this.data = [];
|
|
21
25
|
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
22
30
|
this.team = team;
|
|
23
31
|
}
|
|
24
32
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Matrix4, NormalBlending, ShaderMaterial, Vector2, Vector4 } from "three";
|
|
2
|
+
import { FULL_SCREEN_QUAD_VERTEX_SHADER } from "../../../graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
Shader for drawing fog of war as a screen-space post-process effect
|
|
@@ -6,16 +7,7 @@ import { Matrix4, NormalBlending, ShaderMaterial, Vector2, Vector4 } from "three
|
|
|
6
7
|
*/
|
|
7
8
|
export function buildScreenSpaceFogOfWarShader() {
|
|
8
9
|
function vertexShader() {
|
|
9
|
-
return
|
|
10
|
-
varying vec2 vUv;
|
|
11
|
-
|
|
12
|
-
void main() {
|
|
13
|
-
|
|
14
|
-
vUv = uv;
|
|
15
|
-
|
|
16
|
-
gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
|
|
17
|
-
|
|
18
|
-
}`;
|
|
10
|
+
return FULL_SCREEN_QUAD_VERTEX_SHADER;
|
|
19
11
|
}
|
|
20
12
|
|
|
21
13
|
function fragmentShader() {
|
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import { ClampToEdgeWrapping, DataTexture, RGBAFormat, UnsignedByteType, Vector2 } from 'three';
|
|
7
7
|
import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
|
|
8
|
-
import sampler2D2Texture from '../../graphics/texture/sampler/Sampler2D2Texture.js';
|
|
9
8
|
import AmbientOcclusionShader from '../../graphics/shaders/AmbientOcclusionShader.js';
|
|
10
|
-
import GaussianBlurShader from '../../graphics/shaders/GaussianBlurShader.js';
|
|
11
9
|
import ImageFilter from '../../graphics/filter/ImageFilter.js';
|
|
12
10
|
import { sampler2DtoFloat32Texture } from "../../graphics/texture/sampler/sampler2DToFloat32Texture.js";
|
|
11
|
+
import { DenoiseShader } from "../../graphics/shaders/DenoiseShader.js";
|
|
13
12
|
|
|
14
13
|
function filterResult2Texture(data, width, height) {
|
|
15
14
|
const result = new DataTexture();
|
|
@@ -37,6 +36,7 @@ function filterResult2Texture(data, width, height) {
|
|
|
37
36
|
* @param {Sampler2D} heightMap
|
|
38
37
|
* @param {Sampler2D} normalMap
|
|
39
38
|
* @param {Vector2} resultSize
|
|
39
|
+
* @param worldSize
|
|
40
40
|
* @param {number} [rayLength]
|
|
41
41
|
* @returns {Sampler2D}
|
|
42
42
|
*/
|
|
@@ -45,13 +45,13 @@ function normalMap2OcclusionMap(
|
|
|
45
45
|
heightMap,
|
|
46
46
|
normalMap,
|
|
47
47
|
resultSize,
|
|
48
|
+
worldSize = new Vector2(heightMap.width, heightMap.width),
|
|
48
49
|
rayLength = 17
|
|
49
50
|
) {
|
|
50
51
|
const width = resultSize.x;
|
|
51
52
|
const height = resultSize.y;
|
|
52
|
-
const resolution = new Vector2(heightMap.width, heightMap.height);
|
|
53
53
|
//
|
|
54
|
-
const normalTexture =
|
|
54
|
+
const normalTexture = sampler2DtoFloat32Texture(normalMap);
|
|
55
55
|
|
|
56
56
|
const heightTexture = sampler2DtoFloat32Texture(heightMap);
|
|
57
57
|
|
|
@@ -60,17 +60,16 @@ function normalMap2OcclusionMap(
|
|
|
60
60
|
const shaderAO = new AmbientOcclusionShader();
|
|
61
61
|
shaderAO.uniforms.heightMap.value = heightTexture;
|
|
62
62
|
shaderAO.uniforms.normalMap.value = normalTexture;
|
|
63
|
-
shaderAO.uniforms.
|
|
63
|
+
shaderAO.uniforms.world_size.value.set(worldSize.x, worldSize.y);
|
|
64
64
|
shaderAO.uniforms.rayLength.value = rayLength;
|
|
65
65
|
//perform filtering
|
|
66
66
|
const rawAO = ImageFilter(renderer, width, height, shaderAO);
|
|
67
67
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
shaderBlur.uniforms.sigma.value.set(1.3, 1.3);
|
|
68
|
+
const shaderDenoise = new DenoiseShader(2);
|
|
69
|
+
shaderDenoise.uniforms.source.value = filterResult2Texture(rawAO.array, width, height);
|
|
70
|
+
shaderDenoise.uniforms.pixelOffset.value.set(1 / width, 1 / height);
|
|
72
71
|
|
|
73
|
-
const smoothAO = ImageFilter(renderer, width, height,
|
|
72
|
+
const smoothAO = ImageFilter(renderer, width, height, shaderDenoise);
|
|
74
73
|
|
|
75
74
|
//create the sampler
|
|
76
75
|
const result = new Sampler2D(new Uint8ClampedArray(width * height), 1, width, height);
|
|
@@ -79,9 +78,7 @@ function normalMap2OcclusionMap(
|
|
|
79
78
|
const size = width * height;
|
|
80
79
|
|
|
81
80
|
for (let i = 0; i < size; i++) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
result.data[i] = smoothAO.array[i4];
|
|
81
|
+
result.data[i] = smoothAO.array[i * 4];
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
return result;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import normalMap2AOMap from "../../grid/NormalMap2AOMap.js";
|
|
2
|
+
import heightMap2NormalMap from "../../grid/HeightMap2NormalMap.js";
|
|
3
|
+
import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
|
|
4
|
+
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
5
|
+
import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {WebGLRenderer} renderer
|
|
10
|
+
* @param {Sampler2D} sampler
|
|
11
|
+
* @returns {Promise<Sampler2D>}
|
|
12
|
+
*/
|
|
13
|
+
function promiseSamplerNormal(renderer, sampler) {
|
|
14
|
+
|
|
15
|
+
console.time("generating normal map");
|
|
16
|
+
const normalSampler = heightMap2NormalMap(renderer, sampler);
|
|
17
|
+
console.timeEnd("generating normal map");
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
return Promise.resolve(normalSampler);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {WebGLRenderer} renderer
|
|
26
|
+
* @param {Promise<Sampler2D>} pSamplerNormal
|
|
27
|
+
* @param {Sampler2D} samplerHeight
|
|
28
|
+
* @param {Vector2} resolution
|
|
29
|
+
* @param {Vector2} [wordSize]
|
|
30
|
+
* @param {number} rayLength
|
|
31
|
+
* @returns {Promise<unknown>}
|
|
32
|
+
*/
|
|
33
|
+
function promiseSamplerAO(
|
|
34
|
+
{
|
|
35
|
+
renderer,
|
|
36
|
+
pSamplerNormal,
|
|
37
|
+
samplerHeight,
|
|
38
|
+
resolution,
|
|
39
|
+
wordSize = resolution,
|
|
40
|
+
rayLength
|
|
41
|
+
}
|
|
42
|
+
) {
|
|
43
|
+
return new Promise(function (resolve, reject) {
|
|
44
|
+
Promise.all([pSamplerNormal]).then(function (values) {
|
|
45
|
+
const samplerNormal = values[0];
|
|
46
|
+
console.time("generating AO map");
|
|
47
|
+
const occlusionSampler = normalMap2AOMap(
|
|
48
|
+
renderer,
|
|
49
|
+
samplerHeight,
|
|
50
|
+
samplerNormal,
|
|
51
|
+
wordSize,
|
|
52
|
+
resolution,
|
|
53
|
+
rayLength
|
|
54
|
+
);
|
|
55
|
+
console.timeEnd("generating AO map");
|
|
56
|
+
//console.info(occlusionSampler);
|
|
57
|
+
//
|
|
58
|
+
// paintSamplerOnHTML(samplerHeight, 0, 0, 40, 3);
|
|
59
|
+
// paintSamplerOnHTML(samplerNormal, 1, 0, 128, 1);
|
|
60
|
+
// paintSamplerOnHTML(occlusionSampler, 2, 0, 1, 0);
|
|
61
|
+
//
|
|
62
|
+
//
|
|
63
|
+
resolve(occlusionSampler);
|
|
64
|
+
}, reject);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @param {THREE.DataTexture} texture
|
|
71
|
+
* @param {Vector2} [resolution]
|
|
72
|
+
* @param {Sampler2D} heightSampler
|
|
73
|
+
* @param {number} [rayLength]
|
|
74
|
+
* @param {Vector2} [worldSize]
|
|
75
|
+
* @returns {Promise}
|
|
76
|
+
*/
|
|
77
|
+
export function buildLightTexture({
|
|
78
|
+
texture,
|
|
79
|
+
heightSampler,
|
|
80
|
+
resolution= new Vector2(texture.image.width, texture.image.height),
|
|
81
|
+
rayLength = 11,
|
|
82
|
+
worldSize = resolution
|
|
83
|
+
}) {
|
|
84
|
+
|
|
85
|
+
const renderer = WebGLRendererPool.global.get();
|
|
86
|
+
|
|
87
|
+
const normal = promiseSamplerNormal(renderer, heightSampler);
|
|
88
|
+
const ao = promiseSamplerAO({
|
|
89
|
+
renderer: renderer,
|
|
90
|
+
pSamplerNormal: normal,
|
|
91
|
+
samplerHeight: heightSampler,
|
|
92
|
+
resolution: resolution,
|
|
93
|
+
rayLength: rayLength,
|
|
94
|
+
worldSize
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const promise = ao.then(sampler => {
|
|
98
|
+
writeSample2DDataToDataTexture(sampler, texture);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
Promise.all([normal, ao]).finally(() => {
|
|
102
|
+
WebGLRendererPool.global.release(renderer);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return promise;
|
|
106
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
|
|
2
|
+
import { deserializeTexture } from "../../../graphics/texture/sampler/TextureBinaryBufferSerializer.js";
|
|
3
|
+
import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js";
|
|
4
|
+
import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
5
|
+
import rgbaData2valueSampler2D from "../../../graphics/texture/sampler/rgbaData2valueSampler2D.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param zRange
|
|
10
|
+
* @param heightMapURL
|
|
11
|
+
* @param {AssetManager} assetManager
|
|
12
|
+
* @returns {Promise<any>}
|
|
13
|
+
*/
|
|
14
|
+
export function promiseSamplerHeight(zRange, heightMapURL, assetManager) {
|
|
15
|
+
return new Promise(function (fulfill, reject) {
|
|
16
|
+
|
|
17
|
+
function assetObtained(asset) {
|
|
18
|
+
const array = asset.create();
|
|
19
|
+
|
|
20
|
+
const binaryBuffer = new BinaryBuffer();
|
|
21
|
+
//
|
|
22
|
+
// binaryBuffer.writeUint32(2560);
|
|
23
|
+
// binaryBuffer.writeUint32(2560);
|
|
24
|
+
//
|
|
25
|
+
// binaryBuffer.writeUint8(1);
|
|
26
|
+
//
|
|
27
|
+
// binaryBuffer.writeUint8(6);
|
|
28
|
+
|
|
29
|
+
binaryBuffer.writeBytes(new Uint8Array(array), 0, array.length);
|
|
30
|
+
|
|
31
|
+
binaryBuffer.position = 0;
|
|
32
|
+
|
|
33
|
+
const sampler2D = deserializeTexture(binaryBuffer);
|
|
34
|
+
fulfill(sampler2D);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if (heightMapURL === undefined) {
|
|
39
|
+
console.warn('Height map is not specified');
|
|
40
|
+
const defaultSampler = new Sampler2D(new Uint8Array(1), 1, 1, 1);
|
|
41
|
+
fulfill(defaultSampler);
|
|
42
|
+
} else if (heightMapURL.endsWith('.bin')) {
|
|
43
|
+
//load texture from a binary file
|
|
44
|
+
assetManager.get(heightMapURL, GameAssetType.ArrayBuffer, assetObtained, reject);
|
|
45
|
+
} else {
|
|
46
|
+
assetManager.get(heightMapURL, GameAssetType.Image, function (asset) {
|
|
47
|
+
const image = asset.create();
|
|
48
|
+
|
|
49
|
+
// plane
|
|
50
|
+
const imgWidth = image.width;
|
|
51
|
+
const imgHeight = image.height;
|
|
52
|
+
|
|
53
|
+
const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
|
|
54
|
+
|
|
55
|
+
fulfill(samplerHeight);
|
|
56
|
+
}, reject);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -14,9 +14,6 @@ import {
|
|
|
14
14
|
} from 'three';
|
|
15
15
|
import { clamp } from "../../../../core/math/clamp.js";
|
|
16
16
|
import { Sampler2D } from '../../../graphics/texture/sampler/Sampler2D.js';
|
|
17
|
-
import heightMap2NormalMap from '../../grid/HeightMap2NormalMap.js';
|
|
18
|
-
import normalMap2AOMap from '../../grid/NormalMap2AOMap.js';
|
|
19
|
-
import rgbaData2valueSampler2D from '../../../graphics/texture/sampler/rgbaData2valueSampler2D.js';
|
|
20
17
|
import { BinaryNode } from '../../../../core/bvh2/BinaryNode.js';
|
|
21
18
|
import Vector2 from '../../../../core/geom/Vector2.js';
|
|
22
19
|
import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
|
|
@@ -24,13 +21,9 @@ import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
|
|
|
24
21
|
import Clouds from '../TerrainClouds.js';
|
|
25
22
|
|
|
26
23
|
import TerrainTileManager from '../tiles/TerrainTileManager.js';
|
|
27
|
-
import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
|
|
28
|
-
import { deserializeTexture } from "../../../graphics/texture/sampler/TextureBinaryBufferSerializer.js";
|
|
29
|
-
import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
|
|
30
24
|
import { TerrainPreview } from "../TerrainPreview.js";
|
|
31
25
|
import { assert } from "../../../../core/assert.js";
|
|
32
26
|
import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
33
|
-
import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
|
|
34
27
|
import { TerrainLayers } from "./layers/TerrainLayers.js";
|
|
35
28
|
import { SplatMaterial } from "../../../graphics/material/SplatMaterial.js";
|
|
36
29
|
import { loadLegacyTerrainSplats, SplatMapping } from "./splat/SplatMapping.js";
|
|
@@ -41,147 +34,8 @@ import { MeepSettings } from "../../../MeepSettings.js";
|
|
|
41
34
|
import { loadLegacyTerrainLayers } from "./layers/loadLegacyTerrainLayers.js";
|
|
42
35
|
import { TerrainFlags } from "./TerrainFlags.js";
|
|
43
36
|
import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
*
|
|
47
|
-
* @param zRange
|
|
48
|
-
* @param heightMapURL
|
|
49
|
-
* @param {AssetManager} assetManager
|
|
50
|
-
* @returns {Promise<any>}
|
|
51
|
-
*/
|
|
52
|
-
function promiseSamplerHeight(zRange, heightMapURL, assetManager) {
|
|
53
|
-
return new Promise(function (fulfill, reject) {
|
|
54
|
-
|
|
55
|
-
function assetObtained(asset) {
|
|
56
|
-
const array = asset.create();
|
|
57
|
-
|
|
58
|
-
const binaryBuffer = new BinaryBuffer();
|
|
59
|
-
//
|
|
60
|
-
// binaryBuffer.writeUint32(2560);
|
|
61
|
-
// binaryBuffer.writeUint32(2560);
|
|
62
|
-
//
|
|
63
|
-
// binaryBuffer.writeUint8(1);
|
|
64
|
-
//
|
|
65
|
-
// binaryBuffer.writeUint8(6);
|
|
66
|
-
|
|
67
|
-
binaryBuffer.writeBytes(new Uint8Array(array), 0, array.length);
|
|
68
|
-
|
|
69
|
-
binaryBuffer.position = 0;
|
|
70
|
-
|
|
71
|
-
const sampler2D = deserializeTexture(binaryBuffer);
|
|
72
|
-
fulfill(sampler2D);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (heightMapURL === undefined) {
|
|
77
|
-
console.warn('Height map is not specified');
|
|
78
|
-
const defaultSampler = new Sampler2D(new Uint8Array(1), 1, 1, 1);
|
|
79
|
-
fulfill(defaultSampler);
|
|
80
|
-
} else if (heightMapURL.endsWith('.bin')) {
|
|
81
|
-
//load texture from a binary file
|
|
82
|
-
assetManager.get(heightMapURL, GameAssetType.ArrayBuffer, assetObtained, reject);
|
|
83
|
-
} else {
|
|
84
|
-
assetManager.get(heightMapURL, GameAssetType.Image, function (asset) {
|
|
85
|
-
const image = asset.create();
|
|
86
|
-
|
|
87
|
-
// plane
|
|
88
|
-
const imgWidth = image.width;
|
|
89
|
-
const imgHeight = image.height;
|
|
90
|
-
|
|
91
|
-
const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
|
|
92
|
-
|
|
93
|
-
fulfill(samplerHeight);
|
|
94
|
-
}, reject);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
* @param {WebGLRenderer} renderer
|
|
102
|
-
* @param {Sampler2D} sampler
|
|
103
|
-
* @returns {Promise<Sampler2D>}
|
|
104
|
-
*/
|
|
105
|
-
function promiseSamplerNormal(renderer, sampler) {
|
|
106
|
-
|
|
107
|
-
console.time("generating normal map");
|
|
108
|
-
const normalSampler = heightMap2NormalMap(renderer, sampler);
|
|
109
|
-
console.timeEnd("generating normal map");
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return Promise.resolve(normalSampler);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
*
|
|
117
|
-
* @param {WebGLRenderer} renderer
|
|
118
|
-
* @param {Promise<Sampler2D>} pSamplerNormal
|
|
119
|
-
* @param {Sampler2D} samplerHeight
|
|
120
|
-
* @param {Vector2} resolution
|
|
121
|
-
* @param {number} rayLength
|
|
122
|
-
* @returns {Promise<unknown>}
|
|
123
|
-
*/
|
|
124
|
-
function promiseSamplerAO(
|
|
125
|
-
renderer,
|
|
126
|
-
pSamplerNormal,
|
|
127
|
-
samplerHeight,
|
|
128
|
-
resolution,
|
|
129
|
-
rayLength
|
|
130
|
-
) {
|
|
131
|
-
return new Promise(function (resolve, reject) {
|
|
132
|
-
Promise.all([pSamplerNormal]).then(function (values) {
|
|
133
|
-
const samplerNormal = values[0];
|
|
134
|
-
console.time("generating AO map");
|
|
135
|
-
const occlusionSampler = normalMap2AOMap(
|
|
136
|
-
renderer,
|
|
137
|
-
samplerHeight,
|
|
138
|
-
samplerNormal,
|
|
139
|
-
resolution,
|
|
140
|
-
rayLength
|
|
141
|
-
);
|
|
142
|
-
console.timeEnd("generating AO map");
|
|
143
|
-
//console.info(occlusionSampler);
|
|
144
|
-
//
|
|
145
|
-
// paintSamplerOnHTML(samplerHeight, 0, 0, 40, 3);
|
|
146
|
-
// paintSamplerOnHTML(samplerNormal, 1, 0, 128, 1);
|
|
147
|
-
// paintSamplerOnHTML(occlusionSampler, 2, 0, 1, 0);
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
resolve(occlusionSampler);
|
|
151
|
-
}, reject);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
*
|
|
157
|
-
* @param {DataTexture} texture
|
|
158
|
-
* @param {Vector2} resolution
|
|
159
|
-
* @param {Sampler2D} heightSampler
|
|
160
|
-
* @param {number} heightRange
|
|
161
|
-
* @param {number} [rayLength]
|
|
162
|
-
* @returns {Promise}
|
|
163
|
-
*/
|
|
164
|
-
function buildLightTexture({ texture, heightSampler, resolution, rayLength = 17 }) {
|
|
165
|
-
|
|
166
|
-
const renderer = WebGLRendererPool.global.get();
|
|
167
|
-
|
|
168
|
-
if (resolution === undefined) {
|
|
169
|
-
resolution = new Vector2(texture.image.width, texture.image.height);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const normal = promiseSamplerNormal(renderer, heightSampler);
|
|
173
|
-
const ao = promiseSamplerAO(renderer, normal, heightSampler, resolution, rayLength);
|
|
174
|
-
|
|
175
|
-
const promise = ao.then(sampler => {
|
|
176
|
-
writeSample2DDataToDataTexture(sampler, texture);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
Promise.all([normal, ao]).finally(() => {
|
|
180
|
-
WebGLRendererPool.global.release(renderer);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
return promise;
|
|
184
|
-
}
|
|
37
|
+
import { buildLightTexture } from "./BuildLightTexture.js";
|
|
38
|
+
import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
|
|
185
39
|
|
|
186
40
|
let idCounter = 0;
|
|
187
41
|
|
|
@@ -903,13 +757,13 @@ class Terrain {
|
|
|
903
757
|
this.updateWorkerHeights();
|
|
904
758
|
}
|
|
905
759
|
|
|
906
|
-
updateWorkerHeights() {
|
|
760
|
+
async updateWorkerHeights() {
|
|
907
761
|
const s = this.samplerHeight;
|
|
908
762
|
const worker = this.buildWorker;
|
|
909
763
|
|
|
910
|
-
worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
|
|
764
|
+
await worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
|
|
911
765
|
|
|
912
|
-
|
|
766
|
+
return await worker.computeHeightRange()
|
|
913
767
|
.then(({ min, max }) => {
|
|
914
768
|
this.tiles.setHeightRange(min, max);
|
|
915
769
|
});
|
|
@@ -1012,7 +866,12 @@ class Terrain {
|
|
|
1012
866
|
this.setFlag(TerrainFlags.Built);
|
|
1013
867
|
}
|
|
1014
868
|
|
|
1015
|
-
|
|
869
|
+
/**
|
|
870
|
+
*
|
|
871
|
+
* @param {number} quality resolution in texels per grid cell (4 = 4x4 light map texels per single grid cell)
|
|
872
|
+
* @return {Promise<DataTexture>}
|
|
873
|
+
*/
|
|
874
|
+
buildLightMap(quality = 4) {
|
|
1016
875
|
|
|
1017
876
|
|
|
1018
877
|
const size_x = this.size.x;
|
|
@@ -1035,7 +894,9 @@ class Terrain {
|
|
|
1035
894
|
|
|
1036
895
|
const promise = buildLightTexture({
|
|
1037
896
|
texture,
|
|
1038
|
-
heightSampler: this.samplerHeight
|
|
897
|
+
heightSampler: this.samplerHeight,
|
|
898
|
+
worldSize: new Vector2(size_x * this.gridScale, size_y * this.gridScale),
|
|
899
|
+
resolution: new Vector2(size_x * quality, size_y *quality)
|
|
1039
900
|
});
|
|
1040
901
|
|
|
1041
902
|
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import { LinearFilter, Mesh, OrthographicCamera, Scene, ShaderMaterial, WebGLRenderTarget } from 'three';
|
|
7
7
|
import { FULL_SCREEN_TRIANGLE_GEOMETRY } from "../geometry/FULL_SCREEN_TRIANGLE_GEOMETRY.js";
|
|
8
|
+
import { FULL_SCREEN_QUAD_VERTEX_SHADER } from "../FULL_SCREEN_QUAD_VERTEX_SHADER.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
11
12
|
* @param {WebGLRenderer} renderer
|
|
12
13
|
* @param {number} width
|
|
13
14
|
* @param {number} height
|
|
14
|
-
* @param {{vertexShader
|
|
15
|
+
* @param {{vertexShader?:string,fragmentShader:string, uniforms?:Object, defines?:Object}} processShader
|
|
15
16
|
* @param {Uint8Array} [destination]
|
|
16
17
|
* @return {{array: Uint8Array, renderer: WebGLRenderer}}
|
|
17
18
|
*/
|
|
@@ -34,9 +35,12 @@ function processTexture(
|
|
|
34
35
|
scene.add(camera);
|
|
35
36
|
|
|
36
37
|
//make a quad to render
|
|
37
|
-
const material = new ShaderMaterial(processShader);
|
|
38
|
+
const material = new ShaderMaterial(Object.assign({ vertexShader: FULL_SCREEN_QUAD_VERTEX_SHADER }, processShader));
|
|
39
|
+
|
|
38
40
|
material.lights = false;
|
|
39
41
|
material.fog = false;
|
|
42
|
+
material.uniformsNeedUpdate = true;
|
|
43
|
+
material.needsUpdate = true;
|
|
40
44
|
|
|
41
45
|
const quad = new Mesh(FULL_SCREEN_TRIANGLE_GEOMETRY, material);
|
|
42
46
|
|
|
@@ -28,9 +28,10 @@ export function deinterleaveBufferAttribute(source_attribute) {
|
|
|
28
28
|
attribute.normalized = source_attribute.normalized;
|
|
29
29
|
attribute.name = source_attribute.name;
|
|
30
30
|
|
|
31
|
+
let i = 0, j = 0;
|
|
31
32
|
// copy data
|
|
32
|
-
for (
|
|
33
|
-
for (
|
|
33
|
+
for (; i < item_count; i++) {
|
|
34
|
+
for (j = 0; j < itemSize; j++) {
|
|
34
35
|
destination_array[i * itemSize + j] = source_data_array[i * stride + offset + j];
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -79,21 +79,32 @@ export class ClippingPlaneContainmentComputingVisitor extends GeometrySpatialAcc
|
|
|
79
79
|
|
|
80
80
|
const index3 = index * 3;
|
|
81
81
|
|
|
82
|
-
const
|
|
83
|
-
const b = this.__buffer_indices[index3 + 1] * 3;
|
|
84
|
-
const c = this.__buffer_indices[index3 + 2] * 3;
|
|
82
|
+
const indices = this.__buffer_indices;
|
|
85
83
|
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
const
|
|
84
|
+
const a = indices[index3];
|
|
85
|
+
const b = indices[index3 + 1];
|
|
86
|
+
const c = indices[index3 + 2];
|
|
89
87
|
|
|
90
|
-
const
|
|
91
|
-
const by = this.__buffer_vertices[b + 1];
|
|
92
|
-
const bz = this.__buffer_vertices[b + 2];
|
|
88
|
+
const vertices = this.__buffer_vertices;
|
|
93
89
|
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
90
|
+
const stride = this.__buffer_vertex_stride;
|
|
91
|
+
const offset = this.__buffer_position_offset;
|
|
92
|
+
|
|
93
|
+
const a_address = a * stride + offset;
|
|
94
|
+
const b_address = b * stride + offset;
|
|
95
|
+
const c_address = c * stride + offset;
|
|
96
|
+
|
|
97
|
+
const ax = vertices[a_address];
|
|
98
|
+
const ay = vertices[a_address + 1];
|
|
99
|
+
const az = vertices[a_address + 2];
|
|
100
|
+
|
|
101
|
+
const bx = vertices[b_address];
|
|
102
|
+
const by = vertices[b_address + 1];
|
|
103
|
+
const bz = vertices[b_address + 2];
|
|
104
|
+
|
|
105
|
+
const cx = vertices[c_address];
|
|
106
|
+
const cy = vertices[c_address + 1];
|
|
107
|
+
const cz = vertices[c_address + 2];
|
|
97
108
|
|
|
98
109
|
for (let i = 0; i < plane_count; i++) {
|
|
99
110
|
const plane = planes[i];
|
|
@@ -108,15 +119,9 @@ export class ClippingPlaneContainmentComputingVisitor extends GeometrySpatialAcc
|
|
|
108
119
|
plane_normal_y,
|
|
109
120
|
plane_normal_z,
|
|
110
121
|
plane_constant,
|
|
111
|
-
ax,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
bx,
|
|
115
|
-
by,
|
|
116
|
-
bz,
|
|
117
|
-
cx,
|
|
118
|
-
cy,
|
|
119
|
-
cz
|
|
122
|
+
ax, ay, az,
|
|
123
|
+
bx, by, bz,
|
|
124
|
+
cx, cy, cz
|
|
120
125
|
);
|
|
121
126
|
|
|
122
127
|
if (side === -3) {
|
|
@@ -163,12 +168,8 @@ export class ClippingPlaneContainmentComputingVisitor extends GeometrySpatialAcc
|
|
|
163
168
|
plane_normal_z,
|
|
164
169
|
plane_constant,
|
|
165
170
|
|
|
166
|
-
x0,
|
|
167
|
-
|
|
168
|
-
z0,
|
|
169
|
-
x1,
|
|
170
|
-
y1,
|
|
171
|
-
z1
|
|
171
|
+
x0, y0, z0,
|
|
172
|
+
x1, y1, z1
|
|
172
173
|
);
|
|
173
174
|
|
|
174
175
|
if (side === -2) {
|