├── LICENSE
├── base.css
├── index.html
├── main.js
└── resources
├── fire.jpg
├── fire.png
├── negx.jpg
├── negy.jpg
├── negz.jpg
├── posx.jpg
├── posy.jpg
├── posz.jpg
├── readme.txt
└── rocket
├── Rocket_Ship_01.bin
└── Rocket_Ship_01.gltf
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 simondevyoutube
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/base.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100%;
3 | height: 100%;
4 | position: absolute;
5 | background: #000000;
6 | margin: 0;
7 | padding: 0;
8 | overscroll-behavior: none;
9 | }
10 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Basic 3D World
5 |
6 |
7 |
8 |
9 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.118/build/three.module.js';
2 |
3 | import {GLTFLoader} from 'https://cdn.jsdelivr.net/npm/three@0.118.1/examples/jsm/loaders/GLTFLoader.js';
4 | import {OrbitControls} from 'https://cdn.jsdelivr.net/npm/three@0.118/examples/jsm/controls/OrbitControls.js';
5 |
6 |
7 | const _VS = `
8 | uniform float pointMultiplier;
9 |
10 | attribute float size;
11 | attribute float angle;
12 | attribute vec4 colour;
13 |
14 | varying vec4 vColour;
15 | varying vec2 vAngle;
16 |
17 | void main() {
18 | vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
19 |
20 | gl_Position = projectionMatrix * mvPosition;
21 | gl_PointSize = size * pointMultiplier / gl_Position.w;
22 |
23 | vAngle = vec2(cos(angle), sin(angle));
24 | vColour = colour;
25 | }`;
26 |
27 | const _FS = `
28 |
29 | uniform sampler2D diffuseTexture;
30 |
31 | varying vec4 vColour;
32 | varying vec2 vAngle;
33 |
34 | void main() {
35 | vec2 coords = (gl_PointCoord - 0.5) * mat2(vAngle.x, vAngle.y, -vAngle.y, vAngle.x) + 0.5;
36 | gl_FragColor = texture2D(diffuseTexture, coords) * vColour;
37 | }`;
38 |
39 |
40 | class LinearSpline {
41 | constructor(lerp) {
42 | this._points = [];
43 | this._lerp = lerp;
44 | }
45 |
46 | AddPoint(t, d) {
47 | this._points.push([t, d]);
48 | }
49 |
50 | Get(t) {
51 | let p1 = 0;
52 |
53 | for (let i = 0; i < this._points.length; i++) {
54 | if (this._points[i][0] >= t) {
55 | break;
56 | }
57 | p1 = i;
58 | }
59 |
60 | const p2 = Math.min(this._points.length - 1, p1 + 1);
61 |
62 | if (p1 == p2) {
63 | return this._points[p1][1];
64 | }
65 |
66 | return this._lerp(
67 | (t - this._points[p1][0]) / (
68 | this._points[p2][0] - this._points[p1][0]),
69 | this._points[p1][1], this._points[p2][1]);
70 | }
71 | }
72 |
73 |
74 | class ParticleSystem {
75 | constructor(params) {
76 | const uniforms = {
77 | diffuseTexture: {
78 | value: new THREE.TextureLoader().load('./resources/fire.png')
79 | },
80 | pointMultiplier: {
81 | value: window.innerHeight / (2.0 * Math.tan(0.5 * 60.0 * Math.PI / 180.0))
82 | }
83 | };
84 |
85 | this._material = new THREE.ShaderMaterial({
86 | uniforms: uniforms,
87 | vertexShader: _VS,
88 | fragmentShader: _FS,
89 | blending: THREE.AdditiveBlending,
90 | depthTest: true,
91 | depthWrite: false,
92 | transparent: true,
93 | vertexColors: true
94 | });
95 |
96 | this._camera = params.camera;
97 | this._particles = [];
98 |
99 | this._geometry = new THREE.BufferGeometry();
100 | this._geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
101 | this._geometry.setAttribute('size', new THREE.Float32BufferAttribute([], 1));
102 | this._geometry.setAttribute('colour', new THREE.Float32BufferAttribute([], 4));
103 | this._geometry.setAttribute('angle', new THREE.Float32BufferAttribute([], 1));
104 |
105 | this._points = new THREE.Points(this._geometry, this._material);
106 |
107 | params.parent.add(this._points);
108 |
109 | this._alphaSpline = new LinearSpline((t, a, b) => {
110 | return a + t * (b - a);
111 | });
112 | this._alphaSpline.AddPoint(0.0, 0.0);
113 | this._alphaSpline.AddPoint(0.1, 1.0);
114 | this._alphaSpline.AddPoint(0.6, 1.0);
115 | this._alphaSpline.AddPoint(1.0, 0.0);
116 |
117 | this._colourSpline = new LinearSpline((t, a, b) => {
118 | const c = a.clone();
119 | return c.lerp(b, t);
120 | });
121 | this._colourSpline.AddPoint(0.0, new THREE.Color(0xFFFF80));
122 | this._colourSpline.AddPoint(1.0, new THREE.Color(0xFF8080));
123 |
124 | this._sizeSpline = new LinearSpline((t, a, b) => {
125 | return a + t * (b - a);
126 | });
127 | this._sizeSpline.AddPoint(0.0, 1.0);
128 | this._sizeSpline.AddPoint(0.5, 5.0);
129 | this._sizeSpline.AddPoint(1.0, 1.0);
130 |
131 | document.addEventListener('keyup', (e) => this._onKeyUp(e), false);
132 |
133 | this._UpdateGeometry();
134 | }
135 |
136 | _onKeyUp(event) {
137 | switch(event.keyCode) {
138 | case 32: // SPACE
139 | this._AddParticles();
140 | break;
141 | }
142 | }
143 |
144 | _AddParticles(timeElapsed) {
145 | if (!this.gdfsghk) {
146 | this.gdfsghk = 0.0;
147 | }
148 | this.gdfsghk += timeElapsed;
149 | const n = Math.floor(this.gdfsghk * 75.0);
150 | this.gdfsghk -= n / 75.0;
151 |
152 | for (let i = 0; i < n; i++) {
153 | const life = (Math.random() * 0.75 + 0.25) * 10.0;
154 | this._particles.push({
155 | position: new THREE.Vector3(
156 | (Math.random() * 2 - 1) * 1.0,
157 | (Math.random() * 2 - 1) * 1.0,
158 | (Math.random() * 2 - 1) * 1.0),
159 | size: (Math.random() * 0.5 + 0.5) * 4.0,
160 | colour: new THREE.Color(),
161 | alpha: 1.0,
162 | life: life,
163 | maxLife: life,
164 | rotation: Math.random() * 2.0 * Math.PI,
165 | velocity: new THREE.Vector3(0, -15, 0),
166 | });
167 | }
168 | }
169 |
170 | _UpdateGeometry() {
171 | const positions = [];
172 | const sizes = [];
173 | const colours = [];
174 | const angles = [];
175 |
176 | for (let p of this._particles) {
177 | positions.push(p.position.x, p.position.y, p.position.z);
178 | colours.push(p.colour.r, p.colour.g, p.colour.b, p.alpha);
179 | sizes.push(p.currentSize);
180 | angles.push(p.rotation);
181 | }
182 |
183 | this._geometry.setAttribute(
184 | 'position', new THREE.Float32BufferAttribute(positions, 3));
185 | this._geometry.setAttribute(
186 | 'size', new THREE.Float32BufferAttribute(sizes, 1));
187 | this._geometry.setAttribute(
188 | 'colour', new THREE.Float32BufferAttribute(colours, 4));
189 | this._geometry.setAttribute(
190 | 'angle', new THREE.Float32BufferAttribute(angles, 1));
191 |
192 | this._geometry.attributes.position.needsUpdate = true;
193 | this._geometry.attributes.size.needsUpdate = true;
194 | this._geometry.attributes.colour.needsUpdate = true;
195 | this._geometry.attributes.angle.needsUpdate = true;
196 | }
197 |
198 | _UpdateParticles(timeElapsed) {
199 | for (let p of this._particles) {
200 | p.life -= timeElapsed;
201 | }
202 |
203 | this._particles = this._particles.filter(p => {
204 | return p.life > 0.0;
205 | });
206 |
207 | for (let p of this._particles) {
208 | const t = 1.0 - p.life / p.maxLife;
209 |
210 | p.rotation += timeElapsed * 0.5;
211 | p.alpha = this._alphaSpline.Get(t);
212 | p.currentSize = p.size * this._sizeSpline.Get(t);
213 | p.colour.copy(this._colourSpline.Get(t));
214 |
215 | p.position.add(p.velocity.clone().multiplyScalar(timeElapsed));
216 |
217 | const drag = p.velocity.clone();
218 | drag.multiplyScalar(timeElapsed * 0.1);
219 | drag.x = Math.sign(p.velocity.x) * Math.min(Math.abs(drag.x), Math.abs(p.velocity.x));
220 | drag.y = Math.sign(p.velocity.y) * Math.min(Math.abs(drag.y), Math.abs(p.velocity.y));
221 | drag.z = Math.sign(p.velocity.z) * Math.min(Math.abs(drag.z), Math.abs(p.velocity.z));
222 | p.velocity.sub(drag);
223 | }
224 |
225 | this._particles.sort((a, b) => {
226 | const d1 = this._camera.position.distanceTo(a.position);
227 | const d2 = this._camera.position.distanceTo(b.position);
228 |
229 | if (d1 > d2) {
230 | return -1;
231 | }
232 |
233 | if (d1 < d2) {
234 | return 1;
235 | }
236 |
237 | return 0;
238 | });
239 | }
240 |
241 | Step(timeElapsed) {
242 | this._AddParticles(timeElapsed);
243 | this._UpdateParticles(timeElapsed);
244 | this._UpdateGeometry();
245 | }
246 | }
247 |
248 | class ParticleSystemDemo {
249 | constructor() {
250 | this._Initialize();
251 | }
252 |
253 | _Initialize() {
254 | this._threejs = new THREE.WebGLRenderer({
255 | antialias: true,
256 | });
257 | this._threejs.shadowMap.enabled = true;
258 | this._threejs.shadowMap.type = THREE.PCFSoftShadowMap;
259 | this._threejs.setPixelRatio(window.devicePixelRatio);
260 | this._threejs.setSize(window.innerWidth, window.innerHeight);
261 |
262 | document.body.appendChild(this._threejs.domElement);
263 |
264 | window.addEventListener('resize', () => {
265 | this._OnWindowResize();
266 | }, false);
267 |
268 | const fov = 60;
269 | const aspect = 1920 / 1080;
270 | const near = 1.0;
271 | const far = 1000.0;
272 | this._camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
273 | this._camera.position.set(25, 10, 0);
274 |
275 | this._scene = new THREE.Scene();
276 |
277 | let light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
278 | light.position.set(20, 100, 10);
279 | light.target.position.set(0, 0, 0);
280 | light.castShadow = true;
281 | light.shadow.bias = -0.001;
282 | light.shadow.mapSize.width = 2048;
283 | light.shadow.mapSize.height = 2048;
284 | light.shadow.camera.near = 0.1;
285 | light.shadow.camera.far = 500.0;
286 | light.shadow.camera.near = 0.5;
287 | light.shadow.camera.far = 500.0;
288 | light.shadow.camera.left = 100;
289 | light.shadow.camera.right = -100;
290 | light.shadow.camera.top = 100;
291 | light.shadow.camera.bottom = -100;
292 | this._scene.add(light);
293 |
294 | light = new THREE.AmbientLight(0x101010);
295 | this._scene.add(light);
296 |
297 | const controls = new OrbitControls(
298 | this._camera, this._threejs.domElement);
299 | controls.target.set(0, 0, 0);
300 | controls.update();
301 |
302 | const loader = new THREE.CubeTextureLoader();
303 | const texture = loader.load([
304 | './resources/posx.jpg',
305 | './resources/negx.jpg',
306 | './resources/posy.jpg',
307 | './resources/negy.jpg',
308 | './resources/posz.jpg',
309 | './resources/negz.jpg',
310 | ]);
311 | this._scene.background = texture;
312 |
313 | this._particles = new ParticleSystem({
314 | parent: this._scene,
315 | camera: this._camera,
316 | });
317 |
318 | this._LoadModel();
319 |
320 | this._previousRAF = null;
321 | this._RAF();
322 | }
323 |
324 | _LoadModel() {
325 | const loader = new GLTFLoader();
326 | loader.load('./resources/rocket/Rocket_Ship_01.gltf', (gltf) => {
327 | gltf.scene.traverse(c => {
328 | c.castShadow = true;
329 | });
330 | this._scene.add(gltf.scene);
331 | });
332 | }
333 |
334 | _OnWindowResize() {
335 | this._camera.aspect = window.innerWidth / window.innerHeight;
336 | this._camera.updateProjectionMatrix();
337 | this._threejs.setSize(window.innerWidth, window.innerHeight);
338 | }
339 |
340 | _RAF() {
341 | requestAnimationFrame((t) => {
342 | if (this._previousRAF === null) {
343 | this._previousRAF = t;
344 | }
345 |
346 | this._RAF();
347 |
348 | this._threejs.render(this._scene, this._camera);
349 | this._Step(t - this._previousRAF);
350 | this._previousRAF = t;
351 | });
352 | }
353 |
354 | _Step(timeElapsed) {
355 | const timeElapsedS = timeElapsed * 0.001;
356 |
357 | this._particles.Step(timeElapsedS);
358 | }
359 | }
360 |
361 |
362 | let _APP = null;
363 |
364 | window.addEventListener('DOMContentLoaded', () => {
365 | _APP = new ParticleSystemDemo();
366 | });
367 |
--------------------------------------------------------------------------------
/resources/fire.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/fire.jpg
--------------------------------------------------------------------------------
/resources/fire.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/fire.png
--------------------------------------------------------------------------------
/resources/negx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/negx.jpg
--------------------------------------------------------------------------------
/resources/negy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/negy.jpg
--------------------------------------------------------------------------------
/resources/negz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/negz.jpg
--------------------------------------------------------------------------------
/resources/posx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/posx.jpg
--------------------------------------------------------------------------------
/resources/posy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/posy.jpg
--------------------------------------------------------------------------------
/resources/posz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/posz.jpg
--------------------------------------------------------------------------------
/resources/readme.txt:
--------------------------------------------------------------------------------
1 | Author
2 | ======
3 |
4 | This is the work of Emil Persson, aka Humus.
5 | http://www.humus.name
6 |
7 |
8 |
9 | License
10 | =======
11 |
12 | This work is licensed under a Creative Commons Attribution 3.0 Unported License.
13 | http://creativecommons.org/licenses/by/3.0/
14 |
--------------------------------------------------------------------------------
/resources/rocket/Rocket_Ship_01.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/simondevyoutube/ThreeJS_Tutorial_ParticleSystems/c222f41b6cfdece8a32af097f66f9b66a59646da/resources/rocket/Rocket_Ship_01.bin
--------------------------------------------------------------------------------
/resources/rocket/Rocket_Ship_01.gltf:
--------------------------------------------------------------------------------
1 | {
2 | "accessors" : [
3 | {
4 | "bufferView" : 0,
5 | "componentType" : 5123,
6 | "count" : 624,
7 | "max" : [ 623 ],
8 | "min" : [ 0 ],
9 | "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
10 | "type" : "SCALAR"
11 | },
12 | {
13 | "bufferView" : 2,
14 | "componentType" : 5126,
15 | "count" : 624,
16 | "max" : [ 3.294547080993652, 9.564169883728027, 3.294547080993652 ],
17 | "min" : [ -3.294547080993652, 0, -3.294547080993652 ],
18 | "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
19 | "type" : "VEC3"
20 | },
21 | {
22 | "bufferView" : 2,
23 | "byteOffset" : 7488,
24 | "componentType" : 5126,
25 | "count" : 624,
26 | "max" : [ 1, 0.7847999930381775, 1 ],
27 | "min" : [ -1, -0.9914000034332275, -1 ],
28 | "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
29 | "type" : "VEC3"
30 | },
31 | {
32 | "bufferView" : 1,
33 | "componentType" : 5126,
34 | "count" : 0,
35 | "max" : [ 0, 0 ],
36 | "min" : [ 0, 0 ],
37 | "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
38 | "type" : "VEC2"
39 | },
40 | {
41 | "bufferView" : 3,
42 | "componentType" : 5126,
43 | "count" : 0,
44 | "max" : [ 0, 0, 0, 0 ],
45 | "min" : [ 0, 0, 0, 0 ],
46 | "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
47 | "type" : "VEC4"
48 | },
49 | {
50 | "bufferView" : 0,
51 | "byteOffset" : 1248,
52 | "componentType" : 5123,
53 | "count" : 240,
54 | "max" : [ 239 ],
55 | "min" : [ 0 ],
56 | "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
57 | "type" : "SCALAR"
58 | },
59 | {
60 | "bufferView" : 2,
61 | "byteOffset" : 14976,
62 | "componentType" : 5126,
63 | "count" : 240,
64 | "max" : [ 1.958153963088989, 6.53810977935791, 1.958153963088989 ],
65 | "min" : [ -1.958153963088989, 0, -1.958153963088989 ],
66 | "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
67 | "type" : "VEC3"
68 | },
69 | {
70 | "bufferView" : 2,
71 | "byteOffset" : 17856,
72 | "componentType" : 5126,
73 | "count" : 240,
74 | "max" : [ 0.9232000112533569, 0.1186000034213066, 0.9232000112533569 ],
75 | "min" : [ -0.9232000112533569, -1, -0.9232000112533569 ],
76 | "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
77 | "type" : "VEC3"
78 | },
79 | {
80 | "bufferView" : 1,
81 | "componentType" : 5126,
82 | "count" : 0,
83 | "max" : [ 0, 0 ],
84 | "min" : [ 0, 0 ],
85 | "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
86 | "type" : "VEC2"
87 | },
88 | {
89 | "bufferView" : 3,
90 | "componentType" : 5126,
91 | "count" : 0,
92 | "max" : [ 0, 0, 0, 0 ],
93 | "min" : [ 0, 0, 0, 0 ],
94 | "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
95 | "type" : "VEC4"
96 | },
97 | {
98 | "bufferView" : 0,
99 | "byteOffset" : 1728,
100 | "componentType" : 5123,
101 | "count" : 1056,
102 | "max" : [ 1055 ],
103 | "min" : [ 0 ],
104 | "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
105 | "type" : "SCALAR"
106 | },
107 | {
108 | "bufferView" : 2,
109 | "byteOffset" : 20736,
110 | "componentType" : 5126,
111 | "count" : 1056,
112 | "max" : [ 2.062674045562744, 6.647388935089111, 2.062674045562744 ],
113 | "min" : [ -2.062674045562744, 0, -2.062674045562744 ],
114 | "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
115 | "type" : "VEC3"
116 | },
117 | {
118 | "bufferView" : 2,
119 | "byteOffset" : 33408,
120 | "componentType" : 5126,
121 | "count" : 1056,
122 | "max" : [ 1, 1, 1 ],
123 | "min" : [ -1, -1, -1 ],
124 | "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
125 | "type" : "VEC3"
126 | },
127 | {
128 | "bufferView" : 1,
129 | "componentType" : 5126,
130 | "count" : 0,
131 | "max" : [ 0, 0 ],
132 | "min" : [ 0, 0 ],
133 | "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
134 | "type" : "VEC2"
135 | },
136 | {
137 | "bufferView" : 3,
138 | "componentType" : 5126,
139 | "count" : 0,
140 | "max" : [ 0, 0, 0, 0 ],
141 | "min" : [ 0, 0, 0, 0 ],
142 | "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
143 | "type" : "VEC4"
144 | },
145 | {
146 | "bufferView" : 0,
147 | "byteOffset" : 3840,
148 | "componentType" : 5123,
149 | "count" : 480,
150 | "max" : [ 479 ],
151 | "min" : [ 0 ],
152 | "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
153 | "type" : "SCALAR"
154 | },
155 | {
156 | "bufferView" : 2,
157 | "byteOffset" : 46080,
158 | "componentType" : 5126,
159 | "count" : 480,
160 | "max" : [ 0.8525949716567993, 9.915228843688965, 0.8525949716567993 ],
161 | "min" : [ -0.8525949716567993, 0, -0.8525949716567993 ],
162 | "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
163 | "type" : "VEC3"
164 | },
165 | {
166 | "bufferView" : 2,
167 | "byteOffset" : 51840,
168 | "componentType" : 5126,
169 | "count" : 480,
170 | "max" : [ 0.9239000082015991, 0.9775999784469604, 0.9239000082015991 ],
171 | "min" : [ -0.9239000082015991, -1, -0.9239000082015991 ],
172 | "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
173 | "type" : "VEC3"
174 | },
175 | {
176 | "bufferView" : 1,
177 | "componentType" : 5126,
178 | "count" : 0,
179 | "max" : [ 0, 0 ],
180 | "min" : [ 0, 0 ],
181 | "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
182 | "type" : "VEC2"
183 | },
184 | {
185 | "bufferView" : 3,
186 | "componentType" : 5126,
187 | "count" : 0,
188 | "max" : [ 0, 0, 0, 0 ],
189 | "min" : [ 0, 0, 0, 0 ],
190 | "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
191 | "type" : "VEC4"
192 | },
193 | {
194 | "bufferView" : 0,
195 | "byteOffset" : 4800,
196 | "componentType" : 5123,
197 | "count" : 96,
198 | "max" : [ 95 ],
199 | "min" : [ 0 ],
200 | "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
201 | "type" : "SCALAR"
202 | },
203 | {
204 | "bufferView" : 2,
205 | "byteOffset" : 57600,
206 | "componentType" : 5126,
207 | "count" : 96,
208 | "max" : [ 1.929389953613281, 5.365962982177734, 1.92612898349762 ],
209 | "min" : [ -1.929389953613281, 0, -1.92612898349762 ],
210 | "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
211 | "type" : "VEC3"
212 | },
213 | {
214 | "bufferView" : 2,
215 | "byteOffset" : 58752,
216 | "componentType" : 5126,
217 | "count" : 96,
218 | "max" : [ 1, 0, 1 ],
219 | "min" : [ -1, 0, -1 ],
220 | "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
221 | "type" : "VEC3"
222 | },
223 | {
224 | "bufferView" : 1,
225 | "componentType" : 5126,
226 | "count" : 0,
227 | "max" : [ 0, 0 ],
228 | "min" : [ 0, 0 ],
229 | "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
230 | "type" : "VEC2"
231 | },
232 | {
233 | "bufferView" : 3,
234 | "componentType" : 5126,
235 | "count" : 0,
236 | "max" : [ 0, 0, 0, 0 ],
237 | "min" : [ 0, 0, 0, 0 ],
238 | "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
239 | "type" : "VEC4"
240 | }
241 | ],
242 | "asset" : {
243 | "generator" : "Obj2GltfConverter",
244 | "version" : "2.0"
245 | },
246 | "bufferViews" : [
247 | {
248 | "buffer" : 0,
249 | "byteLength" : 4992,
250 | "byteStride" : 0,
251 | "name" : "buffer-0-bufferview-ushort",
252 | "target" : 34963
253 | },
254 | {
255 | "buffer" : 0,
256 | "byteLength" : 1,
257 | "name" : "buffer-0-bufferview-vec2"
258 | },
259 | {
260 | "buffer" : 0,
261 | "byteLength" : 59904,
262 | "byteOffset" : 4992,
263 | "byteStride" : 12,
264 | "name" : "buffer-0-bufferview-vec3",
265 | "target" : 34962
266 | },
267 | {
268 | "buffer" : 0,
269 | "byteLength" : 1,
270 | "name" : "buffer-0-bufferview-vec4"
271 | }
272 | ],
273 | "buffers" : [
274 | {
275 | "byteLength" : 64896,
276 | "name" : "buffer-0",
277 | "uri" : "Rocket_Ship_01.bin"
278 | }
279 | ],
280 | "materials" : [
281 | {
282 | "doubleSided" : true,
283 | "name" : "F44336",
284 | "pbrMetallicRoughness" : {
285 | "baseColorFactor" : [ 0.956863, 0.262745, 0.211765, 1 ],
286 | "metallicFactor" : 0,
287 | "roughnessFactor" : 0.7448017359246658
288 | }
289 | },
290 | {
291 | "doubleSided" : true,
292 | "name" : "FFFFFF",
293 | "pbrMetallicRoughness" : {
294 | "metallicFactor" : 0,
295 | "roughnessFactor" : 0.7448017359246658
296 | }
297 | },
298 | {
299 | "doubleSided" : true,
300 | "name" : "455A64",
301 | "pbrMetallicRoughness" : {
302 | "baseColorFactor" : [ 0.270588, 0.352941, 0.392157, 1 ],
303 | "metallicFactor" : 0,
304 | "roughnessFactor" : 0.7448017359246658
305 | }
306 | },
307 | {
308 | "doubleSided" : true,
309 | "name" : "78909C",
310 | "pbrMetallicRoughness" : {
311 | "baseColorFactor" : [ 0.470588, 0.564706, 0.611765, 1 ],
312 | "metallicFactor" : 0,
313 | "roughnessFactor" : 0.7448017359246658
314 | }
315 | },
316 | {
317 | "doubleSided" : true,
318 | "name" : "80DEEA",
319 | "pbrMetallicRoughness" : {
320 | "baseColorFactor" : [ 0.501961, 0.870588, 0.917647, 1 ],
321 | "metallicFactor" : 0,
322 | "roughnessFactor" : 0.7448017359246658
323 | }
324 | }
325 | ],
326 | "meshes" : [
327 | {
328 | "name" : "buffer-0-mesh-0",
329 | "primitives" : [
330 | {
331 | "attributes" : {
332 | "NORMAL" : 2,
333 | "POSITION" : 1,
334 | "TEXCOORD_0" : 3
335 | },
336 | "indices" : 0,
337 | "material" : 0
338 | },
339 | {
340 | "attributes" : {
341 | "NORMAL" : 7,
342 | "POSITION" : 6,
343 | "TEXCOORD_0" : 8
344 | },
345 | "indices" : 5,
346 | "material" : 1
347 | },
348 | {
349 | "attributes" : {
350 | "NORMAL" : 12,
351 | "POSITION" : 11,
352 | "TEXCOORD_0" : 13
353 | },
354 | "indices" : 10,
355 | "material" : 2
356 | },
357 | {
358 | "attributes" : {
359 | "NORMAL" : 17,
360 | "POSITION" : 16,
361 | "TEXCOORD_0" : 18
362 | },
363 | "indices" : 15,
364 | "material" : 3
365 | },
366 | {
367 | "attributes" : {
368 | "NORMAL" : 22,
369 | "POSITION" : 21,
370 | "TEXCOORD_0" : 23
371 | },
372 | "indices" : 20,
373 | "material" : 4
374 | }
375 | ]
376 | }
377 | ],
378 | "nodes" : [
379 | {
380 | "mesh" : 0,
381 | "name" : "node-0"
382 | }
383 | ],
384 | "scenes" : [
385 | {
386 | "name" : "scene-0",
387 | "nodes" : [ 0 ]
388 | }
389 | ]
390 | }
391 |
--------------------------------------------------------------------------------