Jelajahi Sumber

Upload project.

Simon 5 tahun lalu
induk
melakukan
c222f41b6c
14 mengubah file dengan 790 tambahan dan 0 penghapusan
  1. 9 0
      base.css
  2. 12 0
      index.html
  3. 366 0
      main.js
  4. TEMPAT SAMPAH
      resources/fire.jpg
  5. TEMPAT SAMPAH
      resources/fire.png
  6. TEMPAT SAMPAH
      resources/negx.jpg
  7. TEMPAT SAMPAH
      resources/negy.jpg
  8. TEMPAT SAMPAH
      resources/negz.jpg
  9. TEMPAT SAMPAH
      resources/posx.jpg
  10. TEMPAT SAMPAH
      resources/posy.jpg
  11. TEMPAT SAMPAH
      resources/posz.jpg
  12. 13 0
      resources/readme.txt
  13. TEMPAT SAMPAH
      resources/rocket/Rocket_Ship_01.bin
  14. 390 0
      resources/rocket/Rocket_Ship_01.gltf

+ 9 - 0
base.css

@@ -0,0 +1,9 @@
+body {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  background: #000000;
+  margin: 0;
+  padding: 0;
+  overscroll-behavior: none;
+}

+ 12 - 0
index.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Basic 3D World</title>
+  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+  <link rel="stylesheet" type="text/css" href="base.css">
+</head>
+<body>
+  <script src="./main.js" type="module">
+  </script>
+</body>
+</html>

+ 366 - 0
main.js

@@ -0,0 +1,366 @@
+import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
+
+import {GLTFLoader} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/GLTFLoader.js';
+import {OrbitControls} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/controls/OrbitControls.js';
+
+
+const _VS = `
+uniform float pointMultiplier;
+
+attribute float size;
+attribute float angle;
+attribute vec4 colour;
+
+varying vec4 vColour;
+varying vec2 vAngle;
+
+void main() {
+  vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
+
+  gl_Position = projectionMatrix * mvPosition;
+  gl_PointSize = size * pointMultiplier / gl_Position.w;
+
+  vAngle = vec2(cos(angle), sin(angle));
+  vColour = colour;
+}`;
+
+const _FS = `
+
+uniform sampler2D diffuseTexture;
+
+varying vec4 vColour;
+varying vec2 vAngle;
+
+void main() {
+  vec2 coords = (gl_PointCoord - 0.5) * mat2(vAngle.x, vAngle.y, -vAngle.y, vAngle.x) + 0.5;
+  gl_FragColor = texture2D(diffuseTexture, coords) * vColour;
+}`;
+
+
+class LinearSpline {
+  constructor(lerp) {
+    this._points = [];
+    this._lerp = lerp;
+  }
+
+  AddPoint(t, d) {
+    this._points.push([t, d]);
+  }
+
+  Get(t) {
+    let p1 = 0;
+
+    for (let i = 0; i < this._points.length; i++) {
+      if (this._points[i][0] >= t) {
+        break;
+      }
+      p1 = i;
+    }
+
+    const p2 = Math.min(this._points.length - 1, p1 + 1);
+
+    if (p1 == p2) {
+      return this._points[p1][1];
+    }
+
+    return this._lerp(
+        (t - this._points[p1][0]) / (
+            this._points[p2][0] - this._points[p1][0]),
+        this._points[p1][1], this._points[p2][1]);
+  }
+}
+
+
+class ParticleSystem {
+  constructor(params) {
+    const uniforms = {
+        diffuseTexture: {
+            value: new THREE.TextureLoader().load('./resources/fire.png')
+        },
+        pointMultiplier: {
+            value: window.innerHeight / (2.0 * Math.tan(0.5 * 60.0 * Math.PI / 180.0))
+        }
+    };
+
+    this._material = new THREE.ShaderMaterial({
+        uniforms: uniforms,
+        vertexShader: _VS,
+        fragmentShader: _FS,
+        blending: THREE.AdditiveBlending,
+        depthTest: true,
+        depthWrite: false,
+        transparent: true,
+        vertexColors: true
+    });
+
+    this._camera = params.camera;
+    this._particles = [];
+
+    this._geometry = new THREE.BufferGeometry();
+    this._geometry.setAttribute('position', new THREE.Float32BufferAttribute([], 3));
+    this._geometry.setAttribute('size', new THREE.Float32BufferAttribute([], 1));
+    this._geometry.setAttribute('colour', new THREE.Float32BufferAttribute([], 4));
+    this._geometry.setAttribute('angle', new THREE.Float32BufferAttribute([], 1));
+
+    this._points = new THREE.Points(this._geometry, this._material);
+
+    params.parent.add(this._points);
+
+    this._alphaSpline = new LinearSpline((t, a, b) => {
+      return a + t * (b - a);
+    });
+    this._alphaSpline.AddPoint(0.0, 0.0);
+    this._alphaSpline.AddPoint(0.1, 1.0);
+    this._alphaSpline.AddPoint(0.6, 1.0);
+    this._alphaSpline.AddPoint(1.0, 0.0);
+
+    this._colourSpline = new LinearSpline((t, a, b) => {
+      const c = a.clone();
+      return c.lerp(b, t);
+    });
+    this._colourSpline.AddPoint(0.0, new THREE.Color(0xFFFF80));
+    this._colourSpline.AddPoint(1.0, new THREE.Color(0xFF8080));
+
+    this._sizeSpline = new LinearSpline((t, a, b) => {
+      return a + t * (b - a);
+    });
+    this._sizeSpline.AddPoint(0.0, 1.0);
+    this._sizeSpline.AddPoint(0.5, 5.0);
+    this._sizeSpline.AddPoint(1.0, 1.0);
+
+    document.addEventListener('keyup', (e) => this._onKeyUp(e), false);
+  
+    this._UpdateGeometry();
+  }
+
+  _onKeyUp(event) {
+    switch(event.keyCode) {
+      case 32: // SPACE
+        this._AddParticles();
+        break;
+    }
+  }
+
+  _AddParticles(timeElapsed) {
+    if (!this.gdfsghk) {
+      this.gdfsghk = 0.0;
+    }
+    this.gdfsghk += timeElapsed;
+    const n = Math.floor(this.gdfsghk * 75.0);
+    this.gdfsghk -= n / 75.0;
+
+    for (let i = 0; i < n; i++) {
+      const life = (Math.random() * 0.75 + 0.25) * 10.0;
+      this._particles.push({
+          position: new THREE.Vector3(
+              (Math.random() * 2 - 1) * 1.0,
+              (Math.random() * 2 - 1) * 1.0,
+              (Math.random() * 2 - 1) * 1.0),
+          size: (Math.random() * 0.5 + 0.5) * 4.0,
+          colour: new THREE.Color(),
+          alpha: 1.0,
+          life: life,
+          maxLife: life,
+          rotation: Math.random() * 2.0 * Math.PI,
+          velocity: new THREE.Vector3(0, -15, 0),
+      });
+    }
+  }
+
+  _UpdateGeometry() {
+    const positions = [];
+    const sizes = [];
+    const colours = [];
+    const angles = [];
+
+    for (let p of this._particles) {
+      positions.push(p.position.x, p.position.y, p.position.z);
+      colours.push(p.colour.r, p.colour.g, p.colour.b, p.alpha);
+      sizes.push(p.currentSize);
+      angles.push(p.rotation);
+    }
+
+    this._geometry.setAttribute(
+        'position', new THREE.Float32BufferAttribute(positions, 3));
+    this._geometry.setAttribute(
+        'size', new THREE.Float32BufferAttribute(sizes, 1));
+    this._geometry.setAttribute(
+        'colour', new THREE.Float32BufferAttribute(colours, 4));
+    this._geometry.setAttribute(
+        'angle', new THREE.Float32BufferAttribute(angles, 1));
+  
+    this._geometry.attributes.position.needsUpdate = true;
+    this._geometry.attributes.size.needsUpdate = true;
+    this._geometry.attributes.colour.needsUpdate = true;
+    this._geometry.attributes.angle.needsUpdate = true;
+  }
+
+  _UpdateParticles(timeElapsed) {
+    for (let p of this._particles) {
+      p.life -= timeElapsed;
+    }
+
+    this._particles = this._particles.filter(p => {
+      return p.life > 0.0;
+    });
+
+    for (let p of this._particles) {
+      const t = 1.0 - p.life / p.maxLife;
+
+      p.rotation += timeElapsed * 0.5;
+      p.alpha = this._alphaSpline.Get(t);
+      p.currentSize = p.size * this._sizeSpline.Get(t);
+      p.colour.copy(this._colourSpline.Get(t));
+
+      p.position.add(p.velocity.clone().multiplyScalar(timeElapsed));
+
+      const drag = p.velocity.clone();
+      drag.multiplyScalar(timeElapsed * 0.1);
+      drag.x = Math.sign(p.velocity.x) * Math.min(Math.abs(drag.x), Math.abs(p.velocity.x));
+      drag.y = Math.sign(p.velocity.y) * Math.min(Math.abs(drag.y), Math.abs(p.velocity.y));
+      drag.z = Math.sign(p.velocity.z) * Math.min(Math.abs(drag.z), Math.abs(p.velocity.z));
+      p.velocity.sub(drag);
+    }
+
+    this._particles.sort((a, b) => {
+      const d1 = this._camera.position.distanceTo(a.position);
+      const d2 = this._camera.position.distanceTo(b.position);
+
+      if (d1 > d2) {
+        return -1;
+      }
+
+      if (d1 < d2) {
+        return 1;
+      }
+
+      return 0;
+    });
+  }
+
+  Step(timeElapsed) {
+    this._AddParticles(timeElapsed);
+    this._UpdateParticles(timeElapsed);
+    this._UpdateGeometry();
+  }
+}
+
+class ParticleSystemDemo {
+  constructor() {
+    this._Initialize();
+  }
+
+  _Initialize() {
+    this._threejs = new THREE.WebGLRenderer({
+      antialias: true,
+    });
+    this._threejs.shadowMap.enabled = true;
+    this._threejs.shadowMap.type = THREE.PCFSoftShadowMap;
+    this._threejs.setPixelRatio(window.devicePixelRatio);
+    this._threejs.setSize(window.innerWidth, window.innerHeight);
+
+    document.body.appendChild(this._threejs.domElement);
+
+    window.addEventListener('resize', () => {
+      this._OnWindowResize();
+    }, false);
+
+    const fov = 60;
+    const aspect = 1920 / 1080;
+    const near = 1.0;
+    const far = 1000.0;
+    this._camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+    this._camera.position.set(25, 10, 0);
+
+    this._scene = new THREE.Scene();
+
+    let light = new THREE.DirectionalLight(0xFFFFFF, 1.0);
+    light.position.set(20, 100, 10);
+    light.target.position.set(0, 0, 0);
+    light.castShadow = true;
+    light.shadow.bias = -0.001;
+    light.shadow.mapSize.width = 2048;
+    light.shadow.mapSize.height = 2048;
+    light.shadow.camera.near = 0.1;
+    light.shadow.camera.far = 500.0;
+    light.shadow.camera.near = 0.5;
+    light.shadow.camera.far = 500.0;
+    light.shadow.camera.left = 100;
+    light.shadow.camera.right = -100;
+    light.shadow.camera.top = 100;
+    light.shadow.camera.bottom = -100;
+    this._scene.add(light);
+
+    light = new THREE.AmbientLight(0x101010);
+    this._scene.add(light);
+
+    const controls = new OrbitControls(
+      this._camera, this._threejs.domElement);
+    controls.target.set(0, 0, 0);
+    controls.update();
+
+    const loader = new THREE.CubeTextureLoader();
+    const texture = loader.load([
+        './resources/posx.jpg',
+        './resources/negx.jpg',
+        './resources/posy.jpg',
+        './resources/negy.jpg',
+        './resources/posz.jpg',
+        './resources/negz.jpg',
+    ]);
+    this._scene.background = texture;
+
+    this._particles = new ParticleSystem({
+        parent: this._scene,
+        camera: this._camera,
+    });
+
+    this._LoadModel();
+
+    this._previousRAF = null;
+    this._RAF();
+  }
+
+  _LoadModel() {
+    const loader = new GLTFLoader();
+    loader.load('./resources/rocket/Rocket_Ship_01.gltf', (gltf) => {
+      gltf.scene.traverse(c => {
+        c.castShadow = true;
+      });
+      this._scene.add(gltf.scene);
+    });
+  }
+
+  _OnWindowResize() {
+    this._camera.aspect = window.innerWidth / window.innerHeight;
+    this._camera.updateProjectionMatrix();
+    this._threejs.setSize(window.innerWidth, window.innerHeight);
+  }
+
+  _RAF() {
+    requestAnimationFrame((t) => {
+      if (this._previousRAF === null) {
+        this._previousRAF = t;
+      }
+
+      this._RAF();
+
+      this._threejs.render(this._scene, this._camera);
+      this._Step(t - this._previousRAF);
+      this._previousRAF = t;
+    });
+  }
+
+  _Step(timeElapsed) {
+    const timeElapsedS = timeElapsed * 0.001;
+
+    this._particles.Step(timeElapsedS);
+  }
+}
+
+
+let _APP = null;
+
+window.addEventListener('DOMContentLoaded', () => {
+  _APP = new ParticleSystemDemo();
+});

TEMPAT SAMPAH
resources/fire.jpg


TEMPAT SAMPAH
resources/fire.png


TEMPAT SAMPAH
resources/negx.jpg


TEMPAT SAMPAH
resources/negy.jpg


TEMPAT SAMPAH
resources/negz.jpg


TEMPAT SAMPAH
resources/posx.jpg


TEMPAT SAMPAH
resources/posy.jpg


TEMPAT SAMPAH
resources/posz.jpg


+ 13 - 0
resources/readme.txt

@@ -0,0 +1,13 @@
+Author
+======
+
+This is the work of Emil Persson, aka Humus.
+http://www.humus.name
+
+
+
+License
+=======
+
+This work is licensed under a Creative Commons Attribution 3.0 Unported License.
+http://creativecommons.org/licenses/by/3.0/

TEMPAT SAMPAH
resources/rocket/Rocket_Ship_01.bin


+ 390 - 0
resources/rocket/Rocket_Ship_01.gltf

@@ -0,0 +1,390 @@
+{
+   "accessors" : [
+      {
+         "bufferView" : 0,
+         "componentType" : 5123,
+         "count" : 624,
+         "max" : [ 623 ],
+         "min" : [ 0 ],
+         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
+         "type" : "SCALAR"
+      },
+      {
+         "bufferView" : 2,
+         "componentType" : 5126,
+         "count" : 624,
+         "max" : [ 3.294547080993652, 9.564169883728027, 3.294547080993652 ],
+         "min" : [ -3.294547080993652, 0, -3.294547080993652 ],
+         "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 7488,
+         "componentType" : 5126,
+         "count" : 624,
+         "max" : [ 1, 0.7847999930381775, 1 ],
+         "min" : [ -1, -0.9914000034332275, -1 ],
+         "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 1,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0 ],
+         "min" : [ 0, 0 ],
+         "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
+         "type" : "VEC2"
+      },
+      {
+         "bufferView" : 3,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0, 0, 0 ],
+         "min" : [ 0, 0, 0, 0 ],
+         "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
+         "type" : "VEC4"
+      },
+      {
+         "bufferView" : 0,
+         "byteOffset" : 1248,
+         "componentType" : 5123,
+         "count" : 240,
+         "max" : [ 239 ],
+         "min" : [ 0 ],
+         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
+         "type" : "SCALAR"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 14976,
+         "componentType" : 5126,
+         "count" : 240,
+         "max" : [ 1.958153963088989, 6.53810977935791, 1.958153963088989 ],
+         "min" : [ -1.958153963088989, 0, -1.958153963088989 ],
+         "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 17856,
+         "componentType" : 5126,
+         "count" : 240,
+         "max" : [ 0.9232000112533569, 0.1186000034213066, 0.9232000112533569 ],
+         "min" : [ -0.9232000112533569, -1, -0.9232000112533569 ],
+         "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 1,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0 ],
+         "min" : [ 0, 0 ],
+         "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
+         "type" : "VEC2"
+      },
+      {
+         "bufferView" : 3,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0, 0, 0 ],
+         "min" : [ 0, 0, 0, 0 ],
+         "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
+         "type" : "VEC4"
+      },
+      {
+         "bufferView" : 0,
+         "byteOffset" : 1728,
+         "componentType" : 5123,
+         "count" : 1056,
+         "max" : [ 1055 ],
+         "min" : [ 0 ],
+         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
+         "type" : "SCALAR"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 20736,
+         "componentType" : 5126,
+         "count" : 1056,
+         "max" : [ 2.062674045562744, 6.647388935089111, 2.062674045562744 ],
+         "min" : [ -2.062674045562744, 0, -2.062674045562744 ],
+         "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 33408,
+         "componentType" : 5126,
+         "count" : 1056,
+         "max" : [ 1, 1, 1 ],
+         "min" : [ -1, -1, -1 ],
+         "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 1,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0 ],
+         "min" : [ 0, 0 ],
+         "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
+         "type" : "VEC2"
+      },
+      {
+         "bufferView" : 3,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0, 0, 0 ],
+         "min" : [ 0, 0, 0, 0 ],
+         "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
+         "type" : "VEC4"
+      },
+      {
+         "bufferView" : 0,
+         "byteOffset" : 3840,
+         "componentType" : 5123,
+         "count" : 480,
+         "max" : [ 479 ],
+         "min" : [ 0 ],
+         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
+         "type" : "SCALAR"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 46080,
+         "componentType" : 5126,
+         "count" : 480,
+         "max" : [ 0.8525949716567993, 9.915228843688965, 0.8525949716567993 ],
+         "min" : [ -0.8525949716567993, 0, -0.8525949716567993 ],
+         "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 51840,
+         "componentType" : 5126,
+         "count" : 480,
+         "max" : [ 0.9239000082015991, 0.9775999784469604, 0.9239000082015991 ],
+         "min" : [ -0.9239000082015991, -1, -0.9239000082015991 ],
+         "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 1,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0 ],
+         "min" : [ 0, 0 ],
+         "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
+         "type" : "VEC2"
+      },
+      {
+         "bufferView" : 3,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0, 0, 0 ],
+         "min" : [ 0, 0, 0, 0 ],
+         "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
+         "type" : "VEC4"
+      },
+      {
+         "bufferView" : 0,
+         "byteOffset" : 4800,
+         "componentType" : 5123,
+         "count" : 96,
+         "max" : [ 95 ],
+         "min" : [ 0 ],
+         "name" : "buffer-0-accessor-indices-buffer-0-mesh-0",
+         "type" : "SCALAR"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 57600,
+         "componentType" : 5126,
+         "count" : 96,
+         "max" : [ 1.929389953613281, 5.365962982177734, 1.92612898349762 ],
+         "min" : [ -1.929389953613281, 0, -1.92612898349762 ],
+         "name" : "buffer-0-accessor-position-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 2,
+         "byteOffset" : 58752,
+         "componentType" : 5126,
+         "count" : 96,
+         "max" : [ 1, 0, 1 ],
+         "min" : [ -1, 0, -1 ],
+         "name" : "buffer-0-accessor-normal-buffer-0-mesh-0",
+         "type" : "VEC3"
+      },
+      {
+         "bufferView" : 1,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0 ],
+         "min" : [ 0, 0 ],
+         "name" : "buffer-0-accessor-texcoord-buffer-0-mesh-0",
+         "type" : "VEC2"
+      },
+      {
+         "bufferView" : 3,
+         "componentType" : 5126,
+         "count" : 0,
+         "max" : [ 0, 0, 0, 0 ],
+         "min" : [ 0, 0, 0, 0 ],
+         "name" : "buffer-0-accessor-color-buffer-0-mesh-0",
+         "type" : "VEC4"
+      }
+   ],
+   "asset" : {
+      "generator" : "Obj2GltfConverter",
+      "version" : "2.0"
+   },
+   "bufferViews" : [
+      {
+         "buffer" : 0,
+         "byteLength" : 4992,
+         "byteStride" : 0,
+         "name" : "buffer-0-bufferview-ushort",
+         "target" : 34963
+      },
+      {
+         "buffer" : 0,
+         "byteLength" : 1,
+         "name" : "buffer-0-bufferview-vec2"
+      },
+      {
+         "buffer" : 0,
+         "byteLength" : 59904,
+         "byteOffset" : 4992,
+         "byteStride" : 12,
+         "name" : "buffer-0-bufferview-vec3",
+         "target" : 34962
+      },
+      {
+         "buffer" : 0,
+         "byteLength" : 1,
+         "name" : "buffer-0-bufferview-vec4"
+      }
+   ],
+   "buffers" : [
+      {
+         "byteLength" : 64896,
+         "name" : "buffer-0",
+         "uri" : "Rocket_Ship_01.bin"
+      }
+   ],
+   "materials" : [
+      {
+         "doubleSided" : true,
+         "name" : "F44336",
+         "pbrMetallicRoughness" : {
+            "baseColorFactor" : [ 0.956863, 0.262745, 0.211765, 1 ],
+            "metallicFactor" : 0,
+            "roughnessFactor" : 0.7448017359246658
+         }
+      },
+      {
+         "doubleSided" : true,
+         "name" : "FFFFFF",
+         "pbrMetallicRoughness" : {
+            "metallicFactor" : 0,
+            "roughnessFactor" : 0.7448017359246658
+         }
+      },
+      {
+         "doubleSided" : true,
+         "name" : "455A64",
+         "pbrMetallicRoughness" : {
+            "baseColorFactor" : [ 0.270588, 0.352941, 0.392157, 1 ],
+            "metallicFactor" : 0,
+            "roughnessFactor" : 0.7448017359246658
+         }
+      },
+      {
+         "doubleSided" : true,
+         "name" : "78909C",
+         "pbrMetallicRoughness" : {
+            "baseColorFactor" : [ 0.470588, 0.564706, 0.611765, 1 ],
+            "metallicFactor" : 0,
+            "roughnessFactor" : 0.7448017359246658
+         }
+      },
+      {
+         "doubleSided" : true,
+         "name" : "80DEEA",
+         "pbrMetallicRoughness" : {
+            "baseColorFactor" : [ 0.501961, 0.870588, 0.917647, 1 ],
+            "metallicFactor" : 0,
+            "roughnessFactor" : 0.7448017359246658
+         }
+      }
+   ],
+   "meshes" : [
+      {
+         "name" : "buffer-0-mesh-0",
+         "primitives" : [
+            {
+               "attributes" : {
+                  "NORMAL" : 2,
+                  "POSITION" : 1,
+                  "TEXCOORD_0" : 3
+               },
+               "indices" : 0,
+               "material" : 0
+            },
+            {
+               "attributes" : {
+                  "NORMAL" : 7,
+                  "POSITION" : 6,
+                  "TEXCOORD_0" : 8
+               },
+               "indices" : 5,
+               "material" : 1
+            },
+            {
+               "attributes" : {
+                  "NORMAL" : 12,
+                  "POSITION" : 11,
+                  "TEXCOORD_0" : 13
+               },
+               "indices" : 10,
+               "material" : 2
+            },
+            {
+               "attributes" : {
+                  "NORMAL" : 17,
+                  "POSITION" : 16,
+                  "TEXCOORD_0" : 18
+               },
+               "indices" : 15,
+               "material" : 3
+            },
+            {
+               "attributes" : {
+                  "NORMAL" : 22,
+                  "POSITION" : 21,
+                  "TEXCOORD_0" : 23
+               },
+               "indices" : 20,
+               "material" : 4
+            }
+         ]
+      }
+   ],
+   "nodes" : [
+      {
+         "mesh" : 0,
+         "name" : "node-0"
+      }
+   ],
+   "scenes" : [
+      {
+         "name" : "scene-0",
+         "nodes" : [ 0 ]
+      }
+   ]
+}