@woosh/meep-engine 2.33.55 → 2.33.59
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/3d/shape/json/type_adapters.js +1 -1
- package/core/math/MathUtils.spec.js +0 -1
- package/engine/ecs/gui/GUIElement.js +0 -106
- package/engine/ecs/gui/GUIElementSerializationAdapter.js +108 -0
- package/engine/ecs/transform/Transform.d.ts +4 -0
- package/engine/graphics/composit/CompositLayer.js +22 -2
- package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +0 -1
- package/engine/graphics/ecs/camera/topdown/TopDownCameraController.spec.js +8 -0
- package/engine/graphics/ecs/path/PathDisplaySystem.d.ts +3 -1
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +38 -66
- package/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +1 -1
- package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.d.ts +2 -0
- package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +23 -8
- package/engine/graphics/render/buffer/simple-fx/DepthLimitedBlur.js +8 -4
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +24 -17
- package/engine/graphics/render/buffer/simple-fx/ao/SAOShader.js +27 -31
- package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +2 -0
- package/engine/graphics/shaders/ScreenSpaceQuadShader.js +23 -3
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { UnitCubeShape3D } from "../UnitCubeShape3D.js";
|
|
|
2
2
|
import { UnitSphereShape3D } from "../UnitSphereShape3D.js";
|
|
3
3
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
4
4
|
import { UnionShape3D } from "../UnionShape3D.js";
|
|
5
|
-
import { shape_from_json} from "./shape_from_json.js";
|
|
5
|
+
import { shape_from_json } from "./shape_from_json.js";
|
|
6
6
|
import { shape_to_json } from "./shape_to_json.js";
|
|
7
7
|
|
|
8
8
|
export const type_adapters = {
|
|
@@ -13,7 +13,6 @@ import { isValueBetweenInclusive } from "./isValueBetweenInclusive.js";
|
|
|
13
13
|
import { solveQuadratic } from "./solveQuadratic.js";
|
|
14
14
|
import { overlap1D } from "./overlap1D.js";
|
|
15
15
|
import { computeHashFloat } from "./hash/computeHashFloat.js";
|
|
16
|
-
import { computeHashFloatArray } from "./hash/computeHashFloatArray.js";
|
|
17
16
|
|
|
18
17
|
test('min2', () => {
|
|
19
18
|
expect(min2(0, 0)).toBe(0);
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import Vector2 from '../../../core/geom/Vector2.js';
|
|
5
5
|
import ObservedBoolean from "../../../core/model/ObservedBoolean.js";
|
|
6
|
-
import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
|
|
7
6
|
import { COMPONENT_SERIALIZATION_TRANSIENT_FIELD } from "../storage/COMPONENT_SERIALIZATION_TRANSIENT_FIELD.js";
|
|
8
7
|
import { assert } from "../../../core/assert.js";
|
|
9
8
|
import { objectDeepEquals } from "../../../core/model/object/objectDeepEquals.js";
|
|
@@ -238,108 +237,3 @@ GUIElement.serializable = true;
|
|
|
238
237
|
export default GUIElement;
|
|
239
238
|
|
|
240
239
|
|
|
241
|
-
export class GUIElementSerializationAdapter extends BinaryClassSerializationAdapter {
|
|
242
|
-
constructor() {
|
|
243
|
-
super();
|
|
244
|
-
|
|
245
|
-
this.klass = GUIElement;
|
|
246
|
-
this.version = 0;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
*
|
|
251
|
-
* @param {BinaryBuffer} buffer
|
|
252
|
-
* @param {GUIElement} value
|
|
253
|
-
*/
|
|
254
|
-
serialize(buffer, value) {
|
|
255
|
-
|
|
256
|
-
if (!value.getFlag(GUIElementFlag.Managed)) {
|
|
257
|
-
throw new Error(`Expected 'Managed' flag to be set, instead it was cleared. Cannot serialize un-managed component`);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
value.anchor.toBinaryBufferFloat32(buffer);
|
|
261
|
-
buffer.writeUTF8String(value.group);
|
|
262
|
-
|
|
263
|
-
buffer.writeUint8(value.visible.getValue() ? 1 : 0);
|
|
264
|
-
|
|
265
|
-
buffer.writeUTF8String(value.klass);
|
|
266
|
-
//write parameters
|
|
267
|
-
|
|
268
|
-
const paramKeys = Object.keys(value.parameters);
|
|
269
|
-
|
|
270
|
-
const numParamKeys = paramKeys.length;
|
|
271
|
-
buffer.writeUintVar(numParamKeys);
|
|
272
|
-
|
|
273
|
-
for (let i = 0; i < numParamKeys; i++) {
|
|
274
|
-
const paramKey = paramKeys[i];
|
|
275
|
-
|
|
276
|
-
buffer.writeUTF8String(paramKey);
|
|
277
|
-
|
|
278
|
-
const parameter = value.parameters[paramKey];
|
|
279
|
-
|
|
280
|
-
const paramType = typeof parameter;
|
|
281
|
-
|
|
282
|
-
if (paramType === "number") {
|
|
283
|
-
buffer.writeUint8(1);
|
|
284
|
-
|
|
285
|
-
buffer.writeFloat64(parameter);
|
|
286
|
-
} else if (paramType === "boolean") {
|
|
287
|
-
buffer.writeUint8(2);
|
|
288
|
-
|
|
289
|
-
buffer.writeUint8(parameter ? 1 : 0);
|
|
290
|
-
} else if (paramType === "string") {
|
|
291
|
-
buffer.writeUint8(3);
|
|
292
|
-
|
|
293
|
-
buffer.writeUTF8String(parameter);
|
|
294
|
-
} else {
|
|
295
|
-
throw new TypeError(`Unsupported parameter type ${paramType}`);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
*
|
|
303
|
-
* @param {BinaryBuffer} buffer
|
|
304
|
-
* @param {GUIElement} value
|
|
305
|
-
*/
|
|
306
|
-
deserialize(buffer, value) {
|
|
307
|
-
value.anchor.fromBinaryBufferFloat32(buffer);
|
|
308
|
-
|
|
309
|
-
value.group = buffer.readUTF8String();
|
|
310
|
-
|
|
311
|
-
value.visible.set(buffer.readUint8() !== 0);
|
|
312
|
-
|
|
313
|
-
value.klass = buffer.readUTF8String();
|
|
314
|
-
|
|
315
|
-
const numParamKeys = buffer.readUintVar();
|
|
316
|
-
|
|
317
|
-
const params = {};
|
|
318
|
-
|
|
319
|
-
for (let i = 0; i < numParamKeys; i++) {
|
|
320
|
-
//read key
|
|
321
|
-
const paramKey = buffer.readUTF8String();
|
|
322
|
-
|
|
323
|
-
//read type flag
|
|
324
|
-
const paramTypeHeader = buffer.readUint8();
|
|
325
|
-
|
|
326
|
-
let paramValue;
|
|
327
|
-
if (paramTypeHeader === 1) {
|
|
328
|
-
//number
|
|
329
|
-
paramValue = buffer.readFloat64();
|
|
330
|
-
} else if (paramTypeHeader === 2) {
|
|
331
|
-
//boolean
|
|
332
|
-
paramValue = buffer.readUint8() !== 0;
|
|
333
|
-
} else if (paramTypeHeader === 3) {
|
|
334
|
-
//string
|
|
335
|
-
paramValue = buffer.readUTF8String();
|
|
336
|
-
} else {
|
|
337
|
-
throw new TypeError(`Unknown type header value '${paramTypeHeader}' for parameter key '${paramKey}'`);
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
params[paramKey] = paramValue;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
value.parameters = params;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
|
|
2
|
+
import GUIElement, { GUIElementFlag } from "./GUIElement.js";
|
|
3
|
+
|
|
4
|
+
export class GUIElementSerializationAdapter extends BinaryClassSerializationAdapter {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
|
|
8
|
+
this.klass = GUIElement;
|
|
9
|
+
this.version = 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {BinaryBuffer} buffer
|
|
15
|
+
* @param {GUIElement} value
|
|
16
|
+
*/
|
|
17
|
+
serialize(buffer, value) {
|
|
18
|
+
|
|
19
|
+
if (!value.getFlag(GUIElementFlag.Managed)) {
|
|
20
|
+
throw new Error(`Expected 'Managed' flag to be set, instead it was cleared. Cannot serialize un-managed component`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
value.anchor.toBinaryBufferFloat32(buffer);
|
|
24
|
+
buffer.writeUTF8String(value.group);
|
|
25
|
+
|
|
26
|
+
buffer.writeUint8(value.visible.getValue() ? 1 : 0);
|
|
27
|
+
|
|
28
|
+
buffer.writeUTF8String(value.klass);
|
|
29
|
+
//write parameters
|
|
30
|
+
|
|
31
|
+
const paramKeys = Object.keys(value.parameters);
|
|
32
|
+
|
|
33
|
+
const numParamKeys = paramKeys.length;
|
|
34
|
+
buffer.writeUintVar(numParamKeys);
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < numParamKeys; i++) {
|
|
37
|
+
const paramKey = paramKeys[i];
|
|
38
|
+
|
|
39
|
+
buffer.writeUTF8String(paramKey);
|
|
40
|
+
|
|
41
|
+
const parameter = value.parameters[paramKey];
|
|
42
|
+
|
|
43
|
+
const paramType = typeof parameter;
|
|
44
|
+
|
|
45
|
+
if (paramType === "number") {
|
|
46
|
+
buffer.writeUint8(1);
|
|
47
|
+
|
|
48
|
+
buffer.writeFloat64(parameter);
|
|
49
|
+
} else if (paramType === "boolean") {
|
|
50
|
+
buffer.writeUint8(2);
|
|
51
|
+
|
|
52
|
+
buffer.writeUint8(parameter ? 1 : 0);
|
|
53
|
+
} else if (paramType === "string") {
|
|
54
|
+
buffer.writeUint8(3);
|
|
55
|
+
|
|
56
|
+
buffer.writeUTF8String(parameter);
|
|
57
|
+
} else {
|
|
58
|
+
throw new TypeError(`Unsupported parameter type ${paramType}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param {BinaryBuffer} buffer
|
|
67
|
+
* @param {GUIElement} value
|
|
68
|
+
*/
|
|
69
|
+
deserialize(buffer, value) {
|
|
70
|
+
value.anchor.fromBinaryBufferFloat32(buffer);
|
|
71
|
+
|
|
72
|
+
value.group = buffer.readUTF8String();
|
|
73
|
+
|
|
74
|
+
value.visible.set(buffer.readUint8() !== 0);
|
|
75
|
+
|
|
76
|
+
value.klass = buffer.readUTF8String();
|
|
77
|
+
|
|
78
|
+
const numParamKeys = buffer.readUintVar();
|
|
79
|
+
|
|
80
|
+
const params = {};
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < numParamKeys; i++) {
|
|
83
|
+
//read key
|
|
84
|
+
const paramKey = buffer.readUTF8String();
|
|
85
|
+
|
|
86
|
+
//read type flag
|
|
87
|
+
const paramTypeHeader = buffer.readUint8();
|
|
88
|
+
|
|
89
|
+
let paramValue;
|
|
90
|
+
if (paramTypeHeader === 1) {
|
|
91
|
+
//number
|
|
92
|
+
paramValue = buffer.readFloat64();
|
|
93
|
+
} else if (paramTypeHeader === 2) {
|
|
94
|
+
//boolean
|
|
95
|
+
paramValue = buffer.readUint8() !== 0;
|
|
96
|
+
} else if (paramTypeHeader === 3) {
|
|
97
|
+
//string
|
|
98
|
+
paramValue = buffer.readUTF8String();
|
|
99
|
+
} else {
|
|
100
|
+
throw new TypeError(`Unknown type header value '${paramTypeHeader}' for parameter key '${paramKey}'`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
params[paramKey] = paramValue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
value.parameters = params;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AddEquation,
|
|
3
|
+
CustomBlending,
|
|
4
|
+
Mesh,
|
|
5
|
+
OneFactor,
|
|
6
|
+
OneMinusSrcAlphaFactor,
|
|
7
|
+
RedFormat,
|
|
8
|
+
RGBAFormat,
|
|
9
|
+
ShaderMaterial
|
|
10
|
+
} from "three";
|
|
2
11
|
import Vector2 from "../../../core/geom/Vector2.js";
|
|
3
12
|
import { assert } from "../../../core/assert.js";
|
|
4
13
|
import { blendingType2three } from "../texture/sampler/blendingType2Three.js";
|
|
@@ -201,10 +210,21 @@ export class CompositLayer {
|
|
|
201
210
|
}
|
|
202
211
|
};
|
|
203
212
|
|
|
213
|
+
// determine swizzle for the material
|
|
214
|
+
let swizzle;
|
|
215
|
+
const texture_format = this.renderTarget.texture.format;
|
|
216
|
+
if (texture_format === RedFormat) {
|
|
217
|
+
swizzle = ['r', 'r', 'r', 1];
|
|
218
|
+
} else if (texture_format === RGBAFormat) {
|
|
219
|
+
swizzle = ['r', 'g', 'b', 'a'];
|
|
220
|
+
} else {
|
|
221
|
+
throw new Error('Unsupported format');
|
|
222
|
+
}
|
|
223
|
+
|
|
204
224
|
const material = new ShaderMaterial({
|
|
205
225
|
uniforms,
|
|
206
226
|
vertexShader: ScreenSpaceQuadShader.vertexShader(),
|
|
207
|
-
fragmentShader: ScreenSpaceQuadShader.fragmentShader(),
|
|
227
|
+
fragmentShader: ScreenSpaceQuadShader.fragmentShader(swizzle),
|
|
208
228
|
lights: false,
|
|
209
229
|
fog: false,
|
|
210
230
|
depthTest: false,
|
|
@@ -3,6 +3,14 @@ import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
|
3
3
|
import { computeTopDownTransform } from "./TopDownCameraControllerSystem.js";
|
|
4
4
|
import { Transform } from "../../../../ecs/transform/Transform.js";
|
|
5
5
|
|
|
6
|
+
test('setFromEyeAndTarget does not introduce roll when UP is aligned with +Y', () => {
|
|
7
|
+
const ut = new TopDownCameraController();
|
|
8
|
+
|
|
9
|
+
ut.setFromEyeAndTarget(new Vector3(0, 1, -1), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
|
|
10
|
+
|
|
11
|
+
expect(ut.roll).toBe(0);
|
|
12
|
+
});
|
|
13
|
+
|
|
6
14
|
test('setFromEyeAndTarget results in roll respecting UP vector', () => {
|
|
7
15
|
const eye = new Vector3();
|
|
8
16
|
const target = new Vector3();
|
package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js
CHANGED
|
@@ -28,27 +28,11 @@ backGeometry.viewDir = geometry.viewDir;
|
|
|
28
28
|
|
|
29
29
|
vLightFront = vec3( 0.0 );
|
|
30
30
|
vIndirectFront = vec3( 0.0 );
|
|
31
|
-
#ifdef DOUBLE_SIDED
|
|
32
|
-
vLightBack = vec3( 0.0 );
|
|
33
|
-
vIndirectBack = vec3( 0.0 );
|
|
34
|
-
#endif
|
|
35
31
|
|
|
36
32
|
IncidentLight directLight;
|
|
37
33
|
float dotNL;
|
|
38
34
|
vec3 directLightColor_Diffuse;
|
|
39
35
|
|
|
40
|
-
vIndirectFront += getAmbientLightIrradiance( ambientLightColor );
|
|
41
|
-
|
|
42
|
-
vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
|
|
43
|
-
|
|
44
|
-
#ifdef DOUBLE_SIDED
|
|
45
|
-
|
|
46
|
-
vIndirectBack += getAmbientLightIrradiance( ambientLightColor );
|
|
47
|
-
|
|
48
|
-
vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );
|
|
49
|
-
|
|
50
|
-
#endif
|
|
51
|
-
|
|
52
36
|
#if NUM_POINT_LIGHTS > 0
|
|
53
37
|
|
|
54
38
|
#pragma unroll_loop_start
|
|
@@ -56,17 +40,8 @@ vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
|
|
|
56
40
|
|
|
57
41
|
getPointLightInfo( pointLights[ i ], geometry, directLight );
|
|
58
42
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
|
|
63
|
-
|
|
64
|
-
#ifdef DOUBLE_SIDED
|
|
65
|
-
|
|
66
|
-
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
|
|
67
|
-
|
|
68
|
-
#endif
|
|
69
|
-
|
|
43
|
+
RE_Direct( directLight, geometry, material, reflectedLight );
|
|
44
|
+
|
|
70
45
|
}
|
|
71
46
|
#pragma unroll_loop_end
|
|
72
47
|
|
|
@@ -79,16 +54,7 @@ vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
|
|
|
79
54
|
|
|
80
55
|
getSpotLightInfo( spotLights[ i ], geometry, directLight );
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
directLightColor_Diffuse = directLight.color;
|
|
84
|
-
|
|
85
|
-
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
|
|
86
|
-
|
|
87
|
-
#ifdef DOUBLE_SIDED
|
|
88
|
-
|
|
89
|
-
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
|
|
90
|
-
|
|
91
|
-
#endif
|
|
57
|
+
RE_Direct( directLight, geometry, material, reflectedLight );
|
|
92
58
|
}
|
|
93
59
|
#pragma unroll_loop_end
|
|
94
60
|
|
|
@@ -101,38 +67,50 @@ vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );
|
|
|
101
67
|
|
|
102
68
|
getDirectionalLightInfo( directionalLights[ i ], geometry, directLight );
|
|
103
69
|
|
|
104
|
-
|
|
105
|
-
directLightColor_Diffuse = directLight.color;
|
|
106
|
-
|
|
107
|
-
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
|
|
108
|
-
|
|
109
|
-
#ifdef DOUBLE_SIDED
|
|
110
|
-
|
|
111
|
-
vLightBack += saturate( - dotNL ) * directLightColor_Diffuse;
|
|
112
|
-
|
|
113
|
-
#endif
|
|
70
|
+
RE_Direct( directLight, geometry, material, reflectedLight );
|
|
114
71
|
|
|
115
72
|
}
|
|
116
73
|
#pragma unroll_loop_end
|
|
117
74
|
|
|
118
75
|
#endif
|
|
119
76
|
|
|
120
|
-
#if NUM_HEMI_LIGHTS > 0
|
|
121
77
|
|
|
122
|
-
#pragma unroll_loop_start
|
|
123
|
-
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
|
|
124
78
|
|
|
125
|
-
|
|
79
|
+
#if defined( RE_IndirectDiffuse )
|
|
80
|
+
vec3 iblIrradiance = vec3( 0.0 );
|
|
81
|
+
vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
|
|
82
|
+
irradiance += getLightProbeIrradiance( lightProbe, geometry.normal );
|
|
83
|
+
#if NUM_HEMI_LIGHTS > 0
|
|
126
84
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
85
|
+
#pragma unroll_loop_start
|
|
86
|
+
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
|
|
87
|
+
|
|
88
|
+
vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
#pragma unroll_loop_end
|
|
92
|
+
|
|
93
|
+
#endif
|
|
94
|
+
|
|
95
|
+
#if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )
|
|
96
|
+
iblIrradiance += getIBLIrradiance( geometry.normal );
|
|
97
|
+
#endif
|
|
98
|
+
#endif
|
|
130
99
|
|
|
131
|
-
|
|
100
|
+
#if defined( RE_IndirectSpecular )
|
|
101
|
+
vec3 radiance = vec3( 0.0 );
|
|
102
|
+
vec3 clearcoatRadiance = vec3( 0.0 );
|
|
103
|
+
#endif
|
|
132
104
|
|
|
133
|
-
|
|
134
|
-
|
|
105
|
+
#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )
|
|
106
|
+
radiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );
|
|
107
|
+
#endif
|
|
135
108
|
|
|
109
|
+
#if defined( RE_IndirectDiffuse )
|
|
110
|
+
RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );
|
|
111
|
+
#endif
|
|
112
|
+
#if defined( RE_IndirectSpecular )
|
|
113
|
+
RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );
|
|
136
114
|
#endif
|
|
137
115
|
`;
|
|
138
116
|
|
|
@@ -389,18 +367,12 @@ function make_fragment_shader() {
|
|
|
389
367
|
|
|
390
368
|
vec3 transformedNormal = construct_spherical_normal_from_point_coord(gl_PointCoord.xy);
|
|
391
369
|
|
|
392
|
-
${CHUNK_LAMBERT_LIGHTING}
|
|
393
|
-
|
|
394
370
|
LambertMaterial material = LambertMaterial(texel.rgb);
|
|
395
|
-
|
|
396
371
|
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
|
|
397
|
-
vec3 totalEmissiveRadiance = vec3(0.0);
|
|
398
|
-
|
|
399
|
-
reflectedLight.indirectDiffuse += vIndirectFront;
|
|
400
|
-
reflectedLight.indirectDiffuse *= BRDF_Lambert( texel.rgb );
|
|
401
372
|
|
|
402
|
-
|
|
403
|
-
|
|
373
|
+
${CHUNK_LAMBERT_LIGHTING}
|
|
374
|
+
|
|
375
|
+
vec3 totalEmissiveRadiance = vec3(0.0);
|
|
404
376
|
|
|
405
377
|
//@injection_point FORWARD_PLUS:accumulation
|
|
406
378
|
|
|
@@ -257,8 +257,10 @@ export class ParticleVolume {
|
|
|
257
257
|
init_attributes() {
|
|
258
258
|
const spec = PARTICULAR_PARTICLE_SPECIFICATION;
|
|
259
259
|
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
const attributeSpecs = spec.attributes;
|
|
261
|
+
const attribute_count = attributeSpecs.length;
|
|
262
|
+
for (let i = 0; i < attribute_count; i++) {
|
|
263
|
+
const attributeSpec = attributeSpecs[i];
|
|
262
264
|
|
|
263
265
|
const av = new AttributeValue();
|
|
264
266
|
av.spec = attributeSpec;
|
|
@@ -300,6 +302,7 @@ export class ParticleVolume {
|
|
|
300
302
|
* @param {number} [particle_size]
|
|
301
303
|
* @param {AbstractShape3D} [shape]
|
|
302
304
|
* @param {boolean} sort
|
|
305
|
+
* @param {boolean} lighting
|
|
303
306
|
* @param {string} [sprite]
|
|
304
307
|
*/
|
|
305
308
|
from({
|
|
@@ -307,14 +310,19 @@ export class ParticleVolume {
|
|
|
307
310
|
particle_size = 1,
|
|
308
311
|
shape = new UnitCubeShape3D(),
|
|
309
312
|
sort = false,
|
|
313
|
+
lighting = true,
|
|
310
314
|
sprite = "data/textures/particle/smokeparticle.png"
|
|
311
315
|
} = {}) {
|
|
312
316
|
|
|
313
317
|
this.__density = density;
|
|
314
318
|
this.__shape = shape;
|
|
315
319
|
|
|
316
|
-
this.__emitter
|
|
317
|
-
|
|
320
|
+
const emitter = this.__emitter;
|
|
321
|
+
|
|
322
|
+
emitter.writeFlag(ParticleEmitterFlag.DepthSorting, sort);
|
|
323
|
+
emitter.writeFlag(ParticleEmitterFlag.Lit, lighting);
|
|
324
|
+
|
|
325
|
+
emitter.layers.get(0).imageURL = sprite;
|
|
318
326
|
|
|
319
327
|
const attributes = this.attributes;
|
|
320
328
|
|
|
@@ -328,6 +336,7 @@ export class ParticleVolume {
|
|
|
328
336
|
* @param {number} [particle_size]
|
|
329
337
|
* @param {Object} shape
|
|
330
338
|
* @param {boolean} [is_sorted]
|
|
339
|
+
* @param {boolean} [is_lit]
|
|
331
340
|
* @param {string} sprite
|
|
332
341
|
* @param {Object<Object>} [attributes]
|
|
333
342
|
*/
|
|
@@ -337,6 +346,7 @@ export class ParticleVolume {
|
|
|
337
346
|
particle_size = 1,
|
|
338
347
|
shape,
|
|
339
348
|
is_sorted = true,
|
|
349
|
+
is_lit = true,
|
|
340
350
|
sprite,
|
|
341
351
|
attributes = {}
|
|
342
352
|
}) {
|
|
@@ -350,9 +360,11 @@ export class ParticleVolume {
|
|
|
350
360
|
shape: shape_object,
|
|
351
361
|
particle_size,
|
|
352
362
|
sort: is_sorted,
|
|
363
|
+
lighting: is_lit,
|
|
353
364
|
sprite
|
|
354
365
|
});
|
|
355
366
|
|
|
367
|
+
// parse attributes
|
|
356
368
|
for (const attributesKey in attributes) {
|
|
357
369
|
const attribute_object = this.attributes[attributesKey];
|
|
358
370
|
|
|
@@ -397,13 +409,13 @@ export class ParticleVolume {
|
|
|
397
409
|
|
|
398
410
|
const layer = emitter.layers.get(0);
|
|
399
411
|
|
|
412
|
+
// build transform matrix
|
|
400
413
|
const m4_transform = new Matrix4();
|
|
401
414
|
|
|
402
415
|
const t = this.__transform;
|
|
403
416
|
|
|
404
417
|
composeMatrix4(m4_transform, t.position, t.rotation, t.scale);
|
|
405
418
|
|
|
406
|
-
|
|
407
419
|
const m4_layer = new Matrix4();
|
|
408
420
|
|
|
409
421
|
composeMatrix4(m4_layer, layer.position, new Quaternion(), layer.scale);
|
|
@@ -414,11 +426,14 @@ export class ParticleVolume {
|
|
|
414
426
|
|
|
415
427
|
m4_final.multiplyMatrices(m4_transform, m4_layer);
|
|
416
428
|
|
|
417
|
-
|
|
429
|
+
// cache variables to save a bit on de-referencing
|
|
430
|
+
const matrix_elements = m4_final.elements;
|
|
431
|
+
const shape = this.__shape;
|
|
418
432
|
|
|
419
|
-
|
|
433
|
+
for (let i = 0; i < particle_count; i++) {
|
|
434
|
+
shape.sample_random_point_in_volume(v3_position, 0, random);
|
|
420
435
|
|
|
421
|
-
vec3.transformMat4(v3_position, v3_position,
|
|
436
|
+
vec3.transformMat4(v3_position, v3_position, matrix_elements);
|
|
422
437
|
|
|
423
438
|
particles.writeAttributeVector3(i, PARTICLE_ATTRIBUTE_POSITION, v3_position[0], v3_position[1], v3_position[2]);
|
|
424
439
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { NoBlending, ShaderMaterial, UniformsUtils, Vector2, WebGLMultisampleRenderTarget } from "three";
|
|
1
|
+
import { NoBlending, RGBAFormat, ShaderMaterial, UniformsUtils, Vector2, WebGLMultisampleRenderTarget } from "three";
|
|
2
2
|
import { BlurShaderUtils, DepthLimitedBlurShader } from "three/examples/jsm/shaders/DepthLimitedBlurShader.js";
|
|
3
3
|
import { renderScreenSpace } from "../../utils/renderScreenSpace.js";
|
|
4
4
|
|
|
5
5
|
export class DepthLimitedBlur {
|
|
6
|
-
constructor() {
|
|
6
|
+
constructor({ format = RGBAFormat, radius = 8 }) {
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
@@ -19,7 +19,7 @@ export class DepthLimitedBlur {
|
|
|
19
19
|
*/
|
|
20
20
|
this.__rt_output = null;
|
|
21
21
|
|
|
22
|
-
this.__intermediate = new WebGLMultisampleRenderTarget({});
|
|
22
|
+
this.__intermediate = new WebGLMultisampleRenderTarget({ format });
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
this.__material_blur_x = new ShaderMaterial({
|
|
@@ -41,7 +41,7 @@ export class DepthLimitedBlur {
|
|
|
41
41
|
|
|
42
42
|
this.__depth_cutoff = 0.01;
|
|
43
43
|
|
|
44
|
-
this.__blur_radius =
|
|
44
|
+
this.__blur_radius = radius;
|
|
45
45
|
this.__blur_std_dev = 4;
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -161,4 +161,8 @@ export class DepthLimitedBlur {
|
|
|
161
161
|
this.__rt_output = render_target;
|
|
162
162
|
|
|
163
163
|
}
|
|
164
|
+
|
|
165
|
+
dispose() {
|
|
166
|
+
this.__intermediate.dispose();
|
|
167
|
+
}
|
|
164
168
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { EnginePlugin } from "../../../../../plugin/EnginePlugin.js";
|
|
2
2
|
import {
|
|
3
|
+
GLSL3,
|
|
3
4
|
LinearFilter,
|
|
4
5
|
NoBlending,
|
|
5
|
-
|
|
6
|
+
RedFormat,
|
|
6
7
|
ShaderMaterial,
|
|
7
8
|
UniformsUtils,
|
|
8
9
|
WebGLMultisampleRenderTarget
|
|
@@ -25,9 +26,18 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
25
26
|
defines: defines,
|
|
26
27
|
fragmentShader: SAOShader.fragmentShader,
|
|
27
28
|
vertexShader: SAOShader.vertexShader,
|
|
28
|
-
uniforms: UniformsUtils.clone(SAOShader.uniforms)
|
|
29
|
+
uniforms: UniformsUtils.clone(SAOShader.uniforms),
|
|
30
|
+
glslVersion: GLSL3
|
|
29
31
|
});
|
|
30
32
|
|
|
33
|
+
// AO parameters
|
|
34
|
+
const uniforms = this.__material.uniforms;
|
|
35
|
+
uniforms.bias.value = 0.5;
|
|
36
|
+
uniforms.intensity.value = 2;
|
|
37
|
+
|
|
38
|
+
uniforms.kernelRadius.value = 30;
|
|
39
|
+
uniforms.minResolution.value = 0;
|
|
40
|
+
|
|
31
41
|
this.__material.blending = NoBlending;
|
|
32
42
|
|
|
33
43
|
this.__material.extensions.derivatives = true;
|
|
@@ -43,7 +53,7 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
43
53
|
defines.NUM_SAMPLES = 13;
|
|
44
54
|
|
|
45
55
|
// More rings = better quality
|
|
46
|
-
defines.NUM_RINGS =
|
|
56
|
+
defines.NUM_RINGS = 5;
|
|
47
57
|
|
|
48
58
|
/**
|
|
49
59
|
* Should normal buffer be used or not? Using normal buffer might be significantly more expensive, as this would require normal buffer to be built every frame. If there are other users of the buffer - this is not an issue
|
|
@@ -78,10 +88,10 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
78
88
|
minFilter: LinearFilter,
|
|
79
89
|
magFilter: LinearFilter,
|
|
80
90
|
|
|
81
|
-
format:
|
|
91
|
+
format: RedFormat,
|
|
82
92
|
depthBuffer: false,
|
|
83
93
|
stencilBuffer: false,
|
|
84
|
-
generateMipmaps: false
|
|
94
|
+
generateMipmaps: false,
|
|
85
95
|
});
|
|
86
96
|
|
|
87
97
|
/**
|
|
@@ -96,7 +106,7 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
96
106
|
* @type {DepthLimitedBlur}
|
|
97
107
|
* @private
|
|
98
108
|
*/
|
|
99
|
-
this.__blur = new DepthLimitedBlur();
|
|
109
|
+
this.__blur = new DepthLimitedBlur({ format: RedFormat });
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
/**
|
|
@@ -156,16 +166,6 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
156
166
|
uniforms.cameraInverseProjectionMatrix.value.copy(camera.projectionMatrixInverse);
|
|
157
167
|
uniforms.cameraProjectionMatrix.value.copy(camera.projectionMatrix);
|
|
158
168
|
|
|
159
|
-
// AO parameters
|
|
160
|
-
uniforms.bias.value = 0.5;
|
|
161
|
-
uniforms.intensity.value = 0.18;
|
|
162
|
-
|
|
163
|
-
// scale is divided by camera far in the shader, we unbias it here
|
|
164
|
-
// TODO remove this term from the shader
|
|
165
|
-
uniforms.scale.value = far * 0.25;
|
|
166
|
-
|
|
167
|
-
uniforms.kernelRadius.value = 30;
|
|
168
|
-
uniforms.minResolution.value = 0;
|
|
169
169
|
|
|
170
170
|
// trigger uniform update
|
|
171
171
|
material.uniformsNeedUpdate = true;
|
|
@@ -300,7 +300,12 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
300
300
|
const graphics = engine.graphics;
|
|
301
301
|
|
|
302
302
|
// bind compositing layer
|
|
303
|
-
this.__composit_layer = graphics.layerComposer.createLayer(
|
|
303
|
+
this.__composit_layer = graphics.layerComposer.createLayer(
|
|
304
|
+
{
|
|
305
|
+
format: RedFormat
|
|
306
|
+
},
|
|
307
|
+
BlendingType.Multiply
|
|
308
|
+
);
|
|
304
309
|
this.__composit_layer.name = 'Ambient Occlusion';
|
|
305
310
|
|
|
306
311
|
// apply ambient occlusion on opaque pass, otherwise it would occlude transparent geometry
|
|
@@ -344,6 +349,8 @@ export class AmbientOcclusionPostProcessEffect extends EnginePlugin {
|
|
|
344
349
|
this.__composit_layer.on.preRender.remove(this.__render, this);
|
|
345
350
|
graphics.viewport.size.onChanged.add(this.__update_render_target_size, this);
|
|
346
351
|
|
|
352
|
+
this.__blur.dispose();
|
|
353
|
+
|
|
347
354
|
return super.shutdown();
|
|
348
355
|
}
|
|
349
356
|
|
|
@@ -16,7 +16,6 @@ const SAOShader = {
|
|
|
16
16
|
uniforms: {
|
|
17
17
|
|
|
18
18
|
'tDepth': { value: null },
|
|
19
|
-
'tDiffuse': { value: null },
|
|
20
19
|
'tNormal': { value: null },
|
|
21
20
|
'size': { value: new Vector2(512, 512) },
|
|
22
21
|
|
|
@@ -25,7 +24,6 @@ const SAOShader = {
|
|
|
25
24
|
'cameraProjectionMatrix': { value: new Matrix4() },
|
|
26
25
|
'cameraInverseProjectionMatrix': { value: new Matrix4() },
|
|
27
26
|
|
|
28
|
-
'scale': { value: 1.0 },
|
|
29
27
|
'intensity': { value: 0.1 },
|
|
30
28
|
'bias': { value: 0.5 },
|
|
31
29
|
|
|
@@ -48,10 +46,6 @@ const SAOShader = {
|
|
|
48
46
|
|
|
49
47
|
varying vec2 vUv;
|
|
50
48
|
|
|
51
|
-
#if DIFFUSE_TEXTURE == 1
|
|
52
|
-
uniform sampler2D tDiffuse;
|
|
53
|
-
#endif
|
|
54
|
-
|
|
55
49
|
uniform sampler2D tDepth;
|
|
56
50
|
|
|
57
51
|
#if NORMAL_TEXTURE == 1
|
|
@@ -63,7 +57,6 @@ const SAOShader = {
|
|
|
63
57
|
uniform mat4 cameraProjectionMatrix;
|
|
64
58
|
uniform mat4 cameraInverseProjectionMatrix;
|
|
65
59
|
|
|
66
|
-
uniform float scale;
|
|
67
60
|
uniform float intensity;
|
|
68
61
|
uniform float bias;
|
|
69
62
|
uniform float kernelRadius;
|
|
@@ -74,14 +67,8 @@ const SAOShader = {
|
|
|
74
67
|
// RGBA depth
|
|
75
68
|
|
|
76
69
|
#include <packing>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
#if DIFFUSE_TEXTURE == 1
|
|
80
|
-
return texture2D( tDiffuse, vUv );
|
|
81
|
-
#else
|
|
82
|
-
return vec4( 1.0 );
|
|
83
|
-
#endif
|
|
84
|
-
}
|
|
70
|
+
|
|
71
|
+
out float out_occlusion;
|
|
85
72
|
|
|
86
73
|
float getDepth( const in vec2 screenPosition ) {
|
|
87
74
|
#if DEPTH_PACKING == 1
|
|
@@ -114,16 +101,26 @@ const SAOShader = {
|
|
|
114
101
|
return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) );
|
|
115
102
|
#endif
|
|
116
103
|
}
|
|
117
|
-
|
|
118
|
-
|
|
104
|
+
|
|
105
|
+
// Non-sin based hash function, fast and has good randomness
|
|
106
|
+
float hash12(vec2 p){
|
|
107
|
+
vec3 p3 = fract(vec3(p.xyx) * .1031);
|
|
108
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
109
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
110
|
+
}
|
|
111
|
+
|
|
119
112
|
float minResolutionMultipliedByCameraFar;
|
|
120
113
|
|
|
121
114
|
float getOcclusion( const in vec3 centerViewPosition, const in vec3 centerViewNormal, const in vec3 sampleViewPosition ) {
|
|
122
115
|
vec3 viewDelta = sampleViewPosition - centerViewPosition;
|
|
116
|
+
|
|
123
117
|
float viewDistance = length( viewDelta );
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
|
|
119
|
+
float vn = dot( centerViewNormal, viewDelta );
|
|
120
|
+
float a2 = (vn - minResolutionMultipliedByCameraFar) / viewDistance - bias;
|
|
121
|
+
float a1 = (1.0 + pow2( viewDistance ) );
|
|
122
|
+
|
|
123
|
+
return max(0.0, a2) / a1;
|
|
127
124
|
}
|
|
128
125
|
|
|
129
126
|
// moving costly divides into consts
|
|
@@ -132,31 +129,34 @@ const SAOShader = {
|
|
|
132
129
|
|
|
133
130
|
float getAmbientOcclusion( const in vec3 centerViewPosition ) {
|
|
134
131
|
// precompute some variables require in getOcclusion.
|
|
135
|
-
scaleDividedByCameraFar = scale / cameraFar;
|
|
136
132
|
minResolutionMultipliedByCameraFar = minResolution * cameraFar;
|
|
137
133
|
vec3 centerViewNormal = getViewNormal( centerViewPosition, vUv );
|
|
138
134
|
|
|
139
135
|
// jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/
|
|
140
|
-
float angle =
|
|
136
|
+
float angle = hash12( vUv + randomSeed ) * PI2;
|
|
141
137
|
vec2 radius = vec2( kernelRadius * INV_NUM_SAMPLES ) / size;
|
|
142
|
-
vec2 radiusStep = radius;
|
|
143
138
|
|
|
144
139
|
float occlusionSum = 0.0;
|
|
145
140
|
float weightSum = 0.0;
|
|
146
141
|
|
|
147
142
|
for( int i = 0; i < NUM_SAMPLES; i ++ ) {
|
|
148
|
-
vec2 sampleUv = vUv + vec2( cos( angle ), sin( angle ) ) * radius;
|
|
149
|
-
|
|
143
|
+
vec2 sampleUv = vUv + vec2( cos( angle ), sin( angle ) ) * radius * float(i+1);
|
|
144
|
+
|
|
150
145
|
angle += ANGLE_STEP;
|
|
151
146
|
|
|
152
147
|
float sampleDepth = getDepth( sampleUv );
|
|
148
|
+
|
|
153
149
|
if( sampleDepth >= ( 1.0 - EPSILON ) ) {
|
|
150
|
+
// skip, too far
|
|
154
151
|
continue;
|
|
155
152
|
}
|
|
156
153
|
|
|
157
154
|
float sampleViewZ = getViewZ( sampleDepth );
|
|
155
|
+
|
|
158
156
|
vec3 sampleViewPosition = getViewPosition( sampleUv, sampleDepth, sampleViewZ );
|
|
157
|
+
|
|
159
158
|
occlusionSum += getOcclusion( centerViewPosition, centerViewNormal, sampleViewPosition );
|
|
159
|
+
|
|
160
160
|
weightSum += 1.0;
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -177,12 +177,8 @@ const SAOShader = {
|
|
|
177
177
|
float ambientOcclusion = getAmbientOcclusion( viewPosition );
|
|
178
178
|
|
|
179
179
|
float invOcclusion = 1.0 - ambientOcclusion;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
gl_FragColor.xyz *= invOcclusion;
|
|
183
|
-
#else
|
|
184
|
-
gl_FragColor = vec4(invOcclusion,invOcclusion,invOcclusion,1.0);
|
|
185
|
-
#endif
|
|
180
|
+
|
|
181
|
+
out_occlusion = invOcclusion;
|
|
186
182
|
}`
|
|
187
183
|
|
|
188
184
|
};
|
|
@@ -83,6 +83,7 @@ import { ShadedGeometrySystem } from "../../../ecs/mesh-v2/ShadedGeometrySystem.
|
|
|
83
83
|
import { FogOfWar } from "../../../../ecs/fow/FogOfWar.js";
|
|
84
84
|
import { FogOfWarRevealer } from "../../../../ecs/fow/FogOfWarRevealer.js";
|
|
85
85
|
import Team from "../../../../../../model/game/ecs/component/Team.js";
|
|
86
|
+
import { AmbientOcclusionPostProcessEffect } from "../../buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js";
|
|
86
87
|
|
|
87
88
|
const geo_light_center_octahedron = new BoxBufferGeometry(0.1, 0.1, 0.1);
|
|
88
89
|
const engineHarness = new EngineHarness();
|
|
@@ -163,6 +164,7 @@ function makeConfig(engine) {
|
|
|
163
164
|
|
|
164
165
|
// Plugins
|
|
165
166
|
config.addPlugin(ForwardPlusRenderingPlugin);
|
|
167
|
+
config.addPlugin(AmbientOcclusionPostProcessEffect);
|
|
166
168
|
// config.addPlugin(MicronRenderPlugin);
|
|
167
169
|
|
|
168
170
|
// Knowledge
|
|
@@ -11,13 +11,33 @@ function vertexShader() {
|
|
|
11
11
|
`;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {string[]} [swizzle] what to read from the texture
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
function fragmentShader(swizzle = ['r', 'g', 'b', 'a']) {
|
|
20
|
+
const swizzle_read = [];
|
|
21
|
+
const n = swizzle.length;
|
|
22
|
+
for (let i = 0; i < n; i++) {
|
|
23
|
+
const token = swizzle[i];
|
|
24
|
+
|
|
25
|
+
if (typeof token === "string") {
|
|
26
|
+
swizzle_read[i] = `texel.${token}`;
|
|
27
|
+
} else if (typeof token === "number") {
|
|
28
|
+
swizzle_read[i] = Number(token).toFixed(4);
|
|
29
|
+
} else {
|
|
30
|
+
throw new Error(`Unsupported swizzle token '${token}'`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
15
34
|
return `
|
|
16
35
|
uniform sampler2D tTexture;
|
|
17
36
|
varying vec2 vUv;
|
|
18
37
|
|
|
19
38
|
void main(){
|
|
20
|
-
|
|
39
|
+
vec4 texel = texture2D( tTexture, vUv );
|
|
40
|
+
gl_FragColor = vec4(${swizzle_read.join(',')});
|
|
21
41
|
}
|
|
22
42
|
`;
|
|
23
43
|
}
|
|
@@ -25,4 +45,4 @@ function fragmentShader() {
|
|
|
25
45
|
export const ScreenSpaceQuadShader = {
|
|
26
46
|
vertexShader,
|
|
27
47
|
fragmentShader
|
|
28
|
-
};
|
|
48
|
+
};
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.33.
|
|
8
|
+
"version": "2.33.59",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|