ohzi-core 7.0.1 → 7.1.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/build/index.module.js +1 -1
- package/build/index.module.js.map +1 -1
- package/package.json +1 -1
- package/src/Graphics.js +54 -1
- package/src/gpu_particles/GPUParticleSystem.js +69 -47
- package/src/gpu_particles/ParticleAttribute.js +30 -21
- package/src/gpu_particles/ParticlePositionAttribute.js +26 -6
- package/src/index.js +4 -0
- package/src/materials/gpu_particles/ParticleStorageMaterial.js +12 -5
- package/src/materials/gpu_particles/PositionStorageMaterial.js +16 -1
- package/src/shaders/gpu_particles/generic_storage.frag +0 -1
package/package.json
CHANGED
package/src/Graphics.js
CHANGED
|
@@ -7,6 +7,17 @@ import Capabilities from './Capabilities';
|
|
|
7
7
|
import DepthAndNormalsRenderer from './render_utilities/DepthAndNormalsRenderer';
|
|
8
8
|
import Blitter from './render_utilities/Blitter';
|
|
9
9
|
|
|
10
|
+
import {
|
|
11
|
+
NearestFilter,
|
|
12
|
+
RGBAFormat,
|
|
13
|
+
LinearEncoding,
|
|
14
|
+
FloatType,
|
|
15
|
+
WebGLRenderTarget,
|
|
16
|
+
ShaderMaterial,
|
|
17
|
+
NoBlending,
|
|
18
|
+
AlwaysDepth
|
|
19
|
+
} from 'three';
|
|
20
|
+
|
|
10
21
|
import { WebGLRenderer } from 'three';
|
|
11
22
|
|
|
12
23
|
class Graphics
|
|
@@ -87,7 +98,7 @@ class Graphics
|
|
|
87
98
|
this.current_render_mode = this.no_render;
|
|
88
99
|
Capabilities.max_anisotropy = this._renderer.capabilities.getMaxAnisotropy();
|
|
89
100
|
Capabilities.vertex_texture_sampler_available = this._renderer.capabilities.maxVertexTextures > 0;
|
|
90
|
-
Capabilities.fp_textures_available = this.
|
|
101
|
+
Capabilities.fp_textures_available = this.is_floating_point_texture_available();
|
|
91
102
|
|
|
92
103
|
this.generateDepthNormalTexture = false;
|
|
93
104
|
|
|
@@ -332,6 +343,48 @@ class Graphics
|
|
|
332
343
|
this.current_render_mode.dispose();
|
|
333
344
|
this.blitter.dispose();
|
|
334
345
|
}
|
|
346
|
+
|
|
347
|
+
is_floating_point_texture_available()
|
|
348
|
+
{
|
|
349
|
+
const RT = new WebGLRenderTarget(1, 1, {
|
|
350
|
+
minFilter: NearestFilter,
|
|
351
|
+
magFilter: NearestFilter,
|
|
352
|
+
format: RGBAFormat,
|
|
353
|
+
encoding: LinearEncoding,
|
|
354
|
+
type: FloatType,
|
|
355
|
+
stencilBuffer: false,
|
|
356
|
+
depthBuffer: false
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
const vert = `
|
|
360
|
+
void main()
|
|
361
|
+
{
|
|
362
|
+
gl_Position = vec4(uv * 2.0 - 1.0, 1.0, 1.0);
|
|
363
|
+
}
|
|
364
|
+
`;
|
|
365
|
+
const frag = `
|
|
366
|
+
void main()
|
|
367
|
+
{
|
|
368
|
+
gl_FragColor = vec4(0.0, 4865.35, 0.0, 1.0);
|
|
369
|
+
}
|
|
370
|
+
`;
|
|
371
|
+
|
|
372
|
+
const mat = new ShaderMaterial({
|
|
373
|
+
vertexShader: vert,
|
|
374
|
+
fragmentShader: frag,
|
|
375
|
+
depthWrite: false,
|
|
376
|
+
blending: NoBlending,
|
|
377
|
+
depthTest: false,
|
|
378
|
+
depthFunc: AlwaysDepth
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
this.material_pass(mat, RT);
|
|
382
|
+
|
|
383
|
+
const output = new Float32Array(4);
|
|
384
|
+
this._renderer.readRenderTargetPixels(RT, 0, 0, 1, 1, output);
|
|
385
|
+
|
|
386
|
+
return Math.abs(output[1] - 4865.35) < 0.001;
|
|
387
|
+
}
|
|
335
388
|
}
|
|
336
389
|
|
|
337
390
|
export default new Graphics();
|
|
@@ -1,87 +1,109 @@
|
|
|
1
1
|
import { Object3D } from 'three';
|
|
2
2
|
import { BufferAttribute } from 'three';
|
|
3
|
+
import { PlaneGeometry } from 'three';
|
|
4
|
+
import { Mesh } from 'three';
|
|
5
|
+
import { BufferGeometry } from 'three';
|
|
6
|
+
import { Scene } from 'three';
|
|
3
7
|
import { Points } from 'three';
|
|
8
|
+
import { InstancedBufferGeometry } from 'three';
|
|
9
|
+
import { InstancedBufferAttribute } from 'three';
|
|
10
|
+
import ParticleAttribute from './ParticleAttribute';
|
|
4
11
|
|
|
5
12
|
export default class GPUParticleSystem extends Object3D
|
|
6
13
|
{
|
|
7
|
-
constructor()
|
|
14
|
+
constructor(particle_count, material)
|
|
8
15
|
{
|
|
9
16
|
super();
|
|
10
17
|
this.attributes = [];
|
|
11
18
|
|
|
12
|
-
this.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
set_from_geometry(geometry, material, init_attribute_uvs)
|
|
16
|
-
{
|
|
17
|
-
// let position = new ParticlePositionAttribute("_Position");
|
|
18
|
-
if (init_attribute_uvs && geometry.getAttribute('storage_uv') === undefined)
|
|
19
|
-
{
|
|
20
|
-
const uv_storage_attr = this.build_uv_storage_attribute(geometry.getAttribute('position').count);
|
|
21
|
-
geometry.setAttribute('storage_uv', uv_storage_attr);
|
|
22
|
-
}
|
|
23
|
-
// position.init_from_geometry(geometry);
|
|
24
|
-
// this.attributes.push(position);
|
|
19
|
+
this.mesh = this.build_point_mesh(particle_count, material);
|
|
20
|
+
this.add(this.mesh);
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
points.frustumCulled = false;
|
|
30
|
-
this.particles = points;
|
|
31
|
-
|
|
32
|
-
this.add(points);
|
|
22
|
+
this.attribute_writter_mesh = this.build_attribute_writter_mesh(particle_count);
|
|
23
|
+
this.attribute_writter_scene = new Scene();
|
|
24
|
+
this.attribute_writter_scene.add(this.attribute_writter_mesh);
|
|
33
25
|
}
|
|
34
26
|
|
|
35
27
|
add_texture_attribute(buffer_attribute)
|
|
36
28
|
{
|
|
37
|
-
|
|
29
|
+
this.attributes.push(buffer_attribute);
|
|
38
30
|
}
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
add_update_attribute_array(name, array, item_size)
|
|
41
33
|
{
|
|
34
|
+
this.attribute_writter_mesh.geometry.setAttribute(name, new BufferAttribute(array, item_size, false));
|
|
35
|
+
}
|
|
42
36
|
|
|
37
|
+
add_attribute_array(name, array, item_size)
|
|
38
|
+
{
|
|
39
|
+
this.mesh.geometry.setAttribute(name, new InstancedBufferAttribute(array, item_size, false));
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
update()
|
|
46
43
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
for (let i = 0, j = 0; i < particle_count * 2; i += 2, j++)
|
|
44
|
+
this.mesh.material.update();
|
|
45
|
+
for (let i = 0; i < this.attributes.length; i++)
|
|
50
46
|
{
|
|
51
|
-
|
|
52
|
-
uvs[i + 1] = (Math.floor(j / resolution) / resolution) + (0.5 / resolution);
|
|
47
|
+
this.attributes[i].update(this.attribute_writter_scene);
|
|
53
48
|
}
|
|
54
|
-
|
|
55
|
-
return new BufferAttribute(uvs, 2);
|
|
56
49
|
}
|
|
57
50
|
|
|
58
|
-
|
|
51
|
+
dispose()
|
|
59
52
|
{
|
|
60
|
-
|
|
53
|
+
this.mesh.geometry.dispose();
|
|
54
|
+
this.mesh.material.dispose();
|
|
61
55
|
}
|
|
62
56
|
|
|
63
|
-
|
|
57
|
+
build_point_mesh(instance_count = 1, material)
|
|
64
58
|
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
const geo = new PlaneGeometry();
|
|
60
|
+
|
|
61
|
+
const instanced_geo = new InstancedBufferGeometry();
|
|
62
|
+
instanced_geo.setAttribute('position', geo.getAttribute('position'));
|
|
63
|
+
instanced_geo.index = geo.index;
|
|
64
|
+
|
|
65
|
+
instanced_geo.setAttribute('storage_uv', this.build_uv_storage_attribute(instance_count));
|
|
66
|
+
instanced_geo.instanceCount = instance_count;
|
|
67
|
+
const mesh = new Mesh(instanced_geo, material);
|
|
68
|
+
mesh.frustumCulled = false;
|
|
69
|
+
return mesh;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
build_attribute_writter_mesh(particle_count)
|
|
72
73
|
{
|
|
73
|
-
|
|
74
|
+
const { width, height } = ParticleAttribute.calculate_resolution(particle_count);
|
|
75
|
+
|
|
76
|
+
const uvs = new Float32Array(particle_count * 3);
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < particle_count; i++)
|
|
74
79
|
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
const x = i % width;
|
|
81
|
+
const y = Math.floor(i / width);
|
|
82
|
+
uvs[i * 3 + 0] = (x + 0.5) / width;
|
|
83
|
+
uvs[i * 3 + 1] = (y + 0.5) / height;
|
|
84
|
+
uvs[i * 3 + 2] = i;
|
|
79
85
|
}
|
|
86
|
+
const geo = new BufferGeometry();
|
|
87
|
+
geo.setAttribute('position', new BufferAttribute(uvs, 3, false));
|
|
88
|
+
|
|
89
|
+
const points = new Points(geo);
|
|
90
|
+
points.frustumCulled = false;
|
|
91
|
+
return points;
|
|
80
92
|
}
|
|
81
93
|
|
|
82
|
-
|
|
94
|
+
build_uv_storage_attribute(particle_count)
|
|
83
95
|
{
|
|
84
|
-
|
|
85
|
-
|
|
96
|
+
const { width, height } = ParticleAttribute.calculate_resolution(particle_count);
|
|
97
|
+
|
|
98
|
+
const uvs = new Float32Array(particle_count * 2);
|
|
99
|
+
|
|
100
|
+
for (let i = 0; i < particle_count; i++)
|
|
101
|
+
{
|
|
102
|
+
const x = i % width;
|
|
103
|
+
const y = Math.floor(i / width);
|
|
104
|
+
uvs[i * 2 + 0] = (x + 0.5) / width;
|
|
105
|
+
uvs[i * 2 + 1] = (y + 0.5) / height;
|
|
106
|
+
}
|
|
107
|
+
return new InstancedBufferAttribute(uvs, 2, false);
|
|
86
108
|
}
|
|
87
109
|
}
|
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import Graphics from '../Graphics';
|
|
2
2
|
|
|
3
|
-
import { Scene } from 'three';
|
|
4
3
|
import { NearestFilter } from 'three';
|
|
5
4
|
import { RGBAFormat } from 'three';
|
|
6
5
|
import { LinearEncoding } from 'three';
|
|
7
6
|
import { HalfFloatType } from 'three';
|
|
8
7
|
import { FloatType } from 'three';
|
|
9
8
|
import { WebGLRenderTarget } from 'three';
|
|
10
|
-
import
|
|
9
|
+
import Capabilities from '../Capabilities';
|
|
11
10
|
|
|
12
11
|
export default class ParticleAttribute
|
|
13
12
|
{
|
|
14
|
-
constructor(attr_name)
|
|
13
|
+
constructor(attr_name, update_material)
|
|
15
14
|
{
|
|
16
15
|
this.read = undefined;
|
|
17
16
|
this.write = undefined;
|
|
18
17
|
|
|
19
18
|
this.name = attr_name;
|
|
20
19
|
|
|
21
|
-
this.update_material =
|
|
22
|
-
|
|
23
|
-
this.update_scene = new Scene();
|
|
20
|
+
this.update_material = update_material;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
init_from_geometry(geometry)
|
|
@@ -35,23 +32,25 @@ export default class ParticleAttribute
|
|
|
35
32
|
|
|
36
33
|
build_RT(particle_count)
|
|
37
34
|
{
|
|
38
|
-
const resolution =
|
|
35
|
+
const resolution = ParticleAttribute.calculate_resolution(particle_count);
|
|
39
36
|
const options = {
|
|
40
37
|
minFilter: NearestFilter,
|
|
41
38
|
magFilter: NearestFilter,
|
|
42
39
|
format: RGBAFormat,
|
|
43
40
|
encoding: LinearEncoding,
|
|
44
|
-
type:
|
|
41
|
+
type: Capabilities.fp_textures_available ? FloatType : HalfFloatType,
|
|
45
42
|
stencilBuffer: false,
|
|
46
43
|
depthBuffer: false
|
|
47
44
|
};
|
|
48
45
|
|
|
49
|
-
return new WebGLRenderTarget(resolution, resolution, options);
|
|
46
|
+
return new WebGLRenderTarget(resolution.width, resolution.height, options);
|
|
50
47
|
}
|
|
51
48
|
|
|
52
|
-
calculate_resolution(particle_count)
|
|
49
|
+
static calculate_resolution(particle_count)
|
|
53
50
|
{
|
|
54
|
-
|
|
51
|
+
const width = Math.min(particle_count, 512);
|
|
52
|
+
const height = Math.max(1, Math.ceil(particle_count / width));
|
|
53
|
+
return { width, height };
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
swap_RT()
|
|
@@ -61,23 +60,33 @@ export default class ParticleAttribute
|
|
|
61
60
|
this.write = tmp;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
update()
|
|
63
|
+
update(attribute_writter_scene)
|
|
65
64
|
{
|
|
66
65
|
if (this.update_material)
|
|
67
66
|
{
|
|
68
|
-
|
|
67
|
+
this.update_material.update();
|
|
68
|
+
attribute_writter_scene.children[0].material = this.update_material;
|
|
69
|
+
this.update_material.uniforms._MainTex.value = this.read.texture;
|
|
70
|
+
Graphics.render(attribute_writter_scene, undefined, this.write);
|
|
71
|
+
attribute_writter_scene.children[0].material = undefined;
|
|
72
|
+
|
|
69
73
|
this.swap_RT();
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
store_geometry_attribute_in_RT(attribute, RT, storage_material, attribute_writter_scene)
|
|
78
|
+
{
|
|
79
|
+
attribute_writter_scene.children[0].geometry.setAttribute('data', attribute);
|
|
80
|
+
attribute_writter_scene.children[0].material = storage_material;
|
|
81
|
+
|
|
82
|
+
Graphics.render(attribute_writter_scene, undefined, RT);
|
|
83
|
+
|
|
84
|
+
attribute_writter_scene.children[0].geometry.deleteAttribute('data');
|
|
85
|
+
attribute_writter_scene.children[0].material = undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get_texture()
|
|
74
89
|
{
|
|
75
|
-
|
|
76
|
-
points.frustumCulled = false;
|
|
77
|
-
// let scene = new Scene();
|
|
78
|
-
// scene.add( points );
|
|
79
|
-
this.update_scene.add(points);
|
|
80
|
-
Graphics.render(this.update_scene, undefined, RT);
|
|
81
|
-
// Graphics.render(scene, undefined, RT);
|
|
90
|
+
return this.read.texture;
|
|
82
91
|
}
|
|
83
92
|
}
|
|
@@ -1,20 +1,40 @@
|
|
|
1
|
+
import { BufferAttribute } from 'three';
|
|
2
|
+
|
|
1
3
|
import ParticleAttribute from '../gpu_particles/ParticleAttribute';
|
|
2
|
-
import
|
|
4
|
+
import ParticleStorageMaterial from '../materials/gpu_particles/ParticleStorageMaterial';
|
|
3
5
|
|
|
4
6
|
export default class ParticlePositionAttribute extends ParticleAttribute
|
|
5
7
|
{
|
|
6
|
-
constructor()
|
|
8
|
+
constructor(update_material)
|
|
7
9
|
{
|
|
8
|
-
super('_Position');
|
|
10
|
+
super('_Position', update_material);
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
store_geometry(geometry, attribute_writter_scene)
|
|
12
14
|
{
|
|
13
15
|
const pos_attr = geometry.getAttribute('position');
|
|
14
16
|
this.read = this.build_RT(pos_attr.count);
|
|
15
17
|
this.write = this.build_RT(pos_attr.count);
|
|
16
18
|
|
|
17
|
-
const mat = new
|
|
18
|
-
this.
|
|
19
|
+
const mat = new ParticleStorageMaterial();
|
|
20
|
+
this.store_geometry_attribute_in_RT(geometry.getAttribute('position'), this.read, mat, attribute_writter_scene);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
store_positions(positions, attribute_writter_scene)
|
|
24
|
+
{
|
|
25
|
+
this.read = this.build_RT(positions.length);
|
|
26
|
+
this.write = this.build_RT(positions.length);
|
|
27
|
+
|
|
28
|
+
const arr = new Float32Array(positions.length * 4);
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < positions.length; i++)
|
|
31
|
+
{
|
|
32
|
+
arr[i * 4 + 0] = positions[i].x;
|
|
33
|
+
arr[i * 4 + 1] = positions[i].y;
|
|
34
|
+
arr[i * 4 + 2] = positions[i].z;
|
|
35
|
+
arr[i * 4 + 3] = (Math.random() * 2 - 1) * 10;
|
|
36
|
+
}
|
|
37
|
+
const mat = new ParticleStorageMaterial();
|
|
38
|
+
this.store_geometry_attribute_in_RT(new BufferAttribute(arr, 4), this.read, mat, attribute_writter_scene);
|
|
19
39
|
}
|
|
20
40
|
}
|
package/src/index.js
CHANGED
|
@@ -82,6 +82,8 @@ import DualFilteringBlurrer from './render_utilities/DualFilteringBlurrer';
|
|
|
82
82
|
import Blurrer from './render_utilities/Blurrer';
|
|
83
83
|
|
|
84
84
|
import GPUParticleSystem from './gpu_particles/GPUParticleSystem';
|
|
85
|
+
import ParticleAttribute from './gpu_particles/ParticleAttribute';
|
|
86
|
+
import ParticlePositionAttribute from './gpu_particles/ParticlePositionAttribute';
|
|
85
87
|
|
|
86
88
|
import DualFilteringBlurMaterial from './materials/DualFilteringBlurMaterial';
|
|
87
89
|
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
@@ -187,6 +189,8 @@ export {
|
|
|
187
189
|
DualFilteringBlurrer,
|
|
188
190
|
|
|
189
191
|
GPUParticleSystem,
|
|
192
|
+
ParticleAttribute,
|
|
193
|
+
ParticlePositionAttribute,
|
|
190
194
|
PerspectiveFrustumPointFitter,
|
|
191
195
|
OrthographicFrustumPointFitter,
|
|
192
196
|
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import frag from '../../shaders/gpu_particles/generic_storage.frag';
|
|
2
|
-
import common_utils from '../../shaders/gpu_particles/common_utils.glsl';
|
|
3
|
-
|
|
4
2
|
import { ShaderMaterial } from 'three';
|
|
5
|
-
import { ShaderChunk } from 'three';
|
|
6
3
|
import { NoBlending } from 'three';
|
|
7
4
|
import { AlwaysDepth } from 'three';
|
|
8
5
|
|
|
9
6
|
export default class ParticleStorageMaterial extends ShaderMaterial
|
|
10
7
|
{
|
|
11
|
-
constructor(
|
|
8
|
+
constructor()
|
|
12
9
|
{
|
|
13
|
-
|
|
10
|
+
const vert = `
|
|
11
|
+
varying vec4 value;
|
|
12
|
+
attribute vec4 data;
|
|
13
|
+
|
|
14
|
+
void main()
|
|
15
|
+
{
|
|
16
|
+
gl_Position = vec4(position.xy * 2.0 - 1.0, 1.0,1.0);
|
|
17
|
+
gl_PointSize = 1.0;
|
|
14
18
|
|
|
19
|
+
value = data;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
15
22
|
super({
|
|
16
23
|
uniforms: {
|
|
17
24
|
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import ParticleStorageMaterial from '../../materials/gpu_particles/ParticleStorageMaterial';
|
|
2
|
-
import vert from '../../shaders/gpu_particles/store/store_position.vert';
|
|
3
2
|
|
|
4
3
|
export default class PositionStorageMaterial extends ParticleStorageMaterial
|
|
5
4
|
{
|
|
6
5
|
constructor()
|
|
7
6
|
{
|
|
7
|
+
const vert = `
|
|
8
|
+
|
|
9
|
+
varying vec4 value;
|
|
10
|
+
|
|
11
|
+
attribute vec2 storage_uv;
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
void main()
|
|
15
|
+
{
|
|
16
|
+
gl_Position = vec4(storage_uv * 2.0 - 1.0, 1.0,1.0);
|
|
17
|
+
gl_PointSize = 1.0;
|
|
18
|
+
|
|
19
|
+
value = vec4(position.xyz, 1.0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
`;
|
|
8
23
|
super(vert);
|
|
9
24
|
}
|
|
10
25
|
}
|