├── src
├── react-app-env.d.ts
├── state.tsx
├── Logo.tsx
├── index.tsx
├── index.css
├── Sun.tsx
├── App.tsx
├── PostProcessing.tsx
├── Scene.tsx
├── Planet.tsx
└── vfx
│ ├── Nebula.tsx
│ └── AsteroidBelt.tsx
├── public
├── favicon.ico
├── logo192.png
├── logo512.png
├── robots.txt
├── textures
│ ├── smoke.png
│ ├── spark1.png
│ ├── lensdirt.jpg
│ ├── particle.png
│ └── skybox
│ │ ├── back.png
│ │ ├── left.png
│ │ ├── top.png
│ │ ├── bottom.png
│ │ ├── front.png
│ │ └── right.png
├── models
│ ├── asteroid03.bin
│ ├── ImphenziaPalette01-256-GradientX4.png
│ ├── ImphenziaPalette01-256-GradientX4-Emission.png
│ └── asteroid03.gltf
├── manifest.json
└── index.html
├── vercel.json
├── .editorconfig
├── .gitignore
├── tsconfig.json
├── README.md
└── package.json
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/textures/smoke.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/smoke.png
--------------------------------------------------------------------------------
/public/textures/spark1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/spark1.png
--------------------------------------------------------------------------------
/public/models/asteroid03.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/models/asteroid03.bin
--------------------------------------------------------------------------------
/public/textures/lensdirt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/lensdirt.jpg
--------------------------------------------------------------------------------
/public/textures/particle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/particle.png
--------------------------------------------------------------------------------
/public/textures/skybox/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/back.png
--------------------------------------------------------------------------------
/public/textures/skybox/left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/left.png
--------------------------------------------------------------------------------
/public/textures/skybox/top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/top.png
--------------------------------------------------------------------------------
/public/textures/skybox/bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/bottom.png
--------------------------------------------------------------------------------
/public/textures/skybox/front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/front.png
--------------------------------------------------------------------------------
/public/textures/skybox/right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/textures/skybox/right.png
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "rewrites": [{ "source": "/(.*)", "destination": "/" }],
3 | "github": {
4 | "silent": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/public/models/ImphenziaPalette01-256-GradientX4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/models/ImphenziaPalette01-256-GradientX4.png
--------------------------------------------------------------------------------
/src/state.tsx:
--------------------------------------------------------------------------------
1 | import { makeStore } from "statery"
2 | import { Mesh } from "three"
3 |
4 | export const store = makeStore({
5 | sun: null as Mesh | null
6 | })
7 |
--------------------------------------------------------------------------------
/public/models/ImphenziaPalette01-256-GradientX4-Emission.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hmans/space-scene-sandbox/HEAD/public/models/ImphenziaPalette01-256-GradientX4-Emission.png
--------------------------------------------------------------------------------
/src/Logo.tsx:
--------------------------------------------------------------------------------
1 | export const Logo = () => (
2 |
7 | )
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | tab_width = 2
8 | end_of_line = lf
9 | charset = utf-8
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
13 | [*.md]
14 | trim_trailing_whitespace = false
15 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App";
4 | import "./index.css";
5 |
6 | const root = ReactDOM.createRoot(
7 | document.getElementById("root") as HTMLElement
8 | );
9 | root.render(
10 |
11 |
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100vh;
4 | width: 100vw;
5 | margin: 0;
6 | padding: 0;
7 | overflow: hidden;
8 | }
9 |
10 | body {
11 | background-color: #000;
12 | }
13 |
14 | div#root {
15 | height: 100%;
16 | width: 100%;
17 | overflow: hidden;
18 | }
19 |
20 | div#logo {
21 | position: fixed;
22 | bottom: 30px;
23 | left: 30px;
24 | color: white;
25 | font: 50px/1 sans-serif;
26 | text-shadow: 4px 2px 3px rgba(0, 0, 0, 0.8);
27 | z-index: 1;
28 | }
29 |
30 | a {
31 | color: inherit;
32 | font: inherit;
33 | text-decoration: none;
34 | }
35 |
--------------------------------------------------------------------------------
/src/Sun.tsx:
--------------------------------------------------------------------------------
1 | import { MeshProps } from "@react-three/fiber"
2 | import { bitmask, Layers } from "render-composer"
3 | import { Color } from "three"
4 | import { store } from "./state"
5 |
6 | export const Sun = (props: MeshProps) => {
7 | return (
8 | store.set({ sun })} {...props}>
9 |
13 |
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { Loader } from "@react-three/drei"
2 | import { Suspense } from "react"
3 | import * as RC from "render-composer"
4 | import { Logo } from "./Logo"
5 | import { PostProcessing } from "./PostProcessing"
6 | import { Scene } from "./Scene"
7 |
8 | export default function App() {
9 | return (
10 | <>
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | >
22 | )
23 | }
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/src/PostProcessing.tsx:
--------------------------------------------------------------------------------
1 | import { useTexture } from "@react-three/drei"
2 | import { useControls } from "leva"
3 | import * as RC from "render-composer"
4 | import { useStore } from "statery"
5 | import { store } from "./state"
6 |
7 | export const PostProcessing = () => {
8 | const { sun } = useStore(store)
9 | const texture = useTexture("/textures/lensdirt.jpg")
10 |
11 | const controls = useControls("Post Processing", {
12 | smaa: true,
13 | bloom: true,
14 | godRays: true,
15 | lensDirt: true
16 | })
17 |
18 | return (
19 |
20 | {controls.smaa && }
21 | {controls.bloom && (
22 |
27 | )}
28 | {controls.godRays && sun && }
29 | {controls.lensDirt && }
30 |
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/src/Scene.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | Environment,
3 | OrbitControls,
4 | PerspectiveCamera
5 | } from "@react-three/drei"
6 | import { bitmask, Layers } from "render-composer"
7 | import { Planet } from "./Planet"
8 | import { Sun } from "./Sun"
9 |
10 | export const Scene = () => {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | {/* Environment */}
20 |
31 |
32 | {/* Lights */}
33 |
37 |
38 | )
39 | }
40 |
--------------------------------------------------------------------------------
/src/Planet.tsx:
--------------------------------------------------------------------------------
1 | import { GroupProps } from "@react-three/fiber"
2 | import { composable, Layer, modules } from "material-composer-r3f"
3 | import { Fresnel, Vec3 } from "shader-composer"
4 | import { Color } from "three"
5 | import { AsteroidBelt } from "./vfx/AsteroidBelt"
6 | import { Nebula } from "./vfx/Nebula"
7 |
8 | export const Planet = (props: GroupProps) => {
9 | return (
10 |
11 | {/* The actual planet */}
12 |
13 |
14 |
15 |
16 | {/* Base color of the planet */}
17 |
18 |
19 | {/* Fresnel effect */}
20 |
21 |
22 |
23 |
24 |
25 |
26 | {/* Some funky clouds! */}
27 |
36 |
37 | {/* The asteroid belt. */}
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SPACE SCENE SANDBOX
2 |
3 | ## Introduction
4 |
5 | This is a small demo scene built with the help of Three.js, React, React-Three-Fiber, and a couple of libraries from my own Open Source project, [The Composer Suite](https://github.com/hmans/composer-suite), a collection of libraries for building games in the browser.
6 |
7 | Notably, the asteroid rings and the "space fog" around the planet are built with the help of Shader Composer (build shaders with JavaScript), Material Composer (create Three.js materials from shader modules), and VFX Composer (a high-performance particles system engine that uses the other two libraries under the hood.)
8 |
9 | ## Running the demo
10 |
11 | The running demo can be seen here in all its glory:
12 |
13 | - https://space-scene-sandbox.vercel.app/
14 |
15 | If you want to hack around in the code and instantly see the results, you can launch it in one of the many code sandbox services out there. Please note that these can be a little finicky, with one often working better than the others at any given time. Give it a try:
16 |
17 | - [Open in StackBlitz](https://stackblitz.com/github/hmans/space-scene-sandbox)
18 | - [Open in CodeSandbox](https://codesandbox.io/s/github/hmans/space-scene-sandbox)
19 | - [Open in CodeSandbox Projects](https://codesandbox.io/p/github/hmans/space-scene-sandbox)
20 |
21 | Alternatively, feel free to just clone this repository and run:
22 |
23 | ```sh
24 | npm install
25 | npm start
26 | ```
27 |
28 | ## Want more?
29 |
30 | Do drop by the [Composer Suite repository](https://github.com/hmans/composer-suite) and my [Twitter account](https://twitter.com/hmans) if you want to stay up to date. Please also consider [a sponsorship](https://github.com/sponsors/hmans); my lovely sponsors help me keep the lights on and the code flowing.
31 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "asteroid-ring-sandbox",
3 | "version": "0.1.0",
4 | "private": true,
5 | "prettier": {
6 | "trailingComma": "none",
7 | "tabWidth": 2,
8 | "useTabs": false,
9 | "semi": false,
10 | "singleQuote": false,
11 | "arrowParens": "always"
12 | },
13 | "dependencies": {
14 | "@react-three/drei": "^9.31.1",
15 | "@react-three/fiber": "^8.7.4",
16 | "@testing-library/jest-dom": "^5.16.5",
17 | "@testing-library/react": "^13.4.0",
18 | "@testing-library/user-event": "^13.5.0",
19 | "@types/jest": "^27.5.2",
20 | "@types/node": "^16.11.59",
21 | "@types/react": "^18.0.20",
22 | "@types/react-dom": "^18.0.6",
23 | "fp-ts": "^2.12.3",
24 | "leva": "^0.9.31",
25 | "material-composer": "^0.2.2",
26 | "material-composer-r3f": "^0.2.3",
27 | "postprocessing": "^6.28.7",
28 | "react": "^18.2.0",
29 | "react-dom": "^18.2.0",
30 | "react-scripts": "5.0.1",
31 | "render-composer": "^0.2.2",
32 | "shader-composer": "^0.4.4",
33 | "shader-composer-r3f": "^0.4.0",
34 | "statery": "^0.6.2",
35 | "three": "^0.144.0",
36 | "typescript": "^4.8.3",
37 | "vfx-composer": "^0.2.4",
38 | "vfx-composer-r3f": "^0.2.4"
39 | },
40 | "scripts": {
41 | "start": "react-scripts start",
42 | "build": "react-scripts build",
43 | "test": "react-scripts test",
44 | "eject": "react-scripts eject"
45 | },
46 | "eslintConfig": {
47 | "extends": [
48 | "react-app",
49 | "react-app/jest"
50 | ]
51 | },
52 | "browserslist": {
53 | "production": [
54 | ">0.2%",
55 | "not dead",
56 | "not op_mini all"
57 | ],
58 | "development": [
59 | "last 1 chrome version",
60 | "last 1 firefox version",
61 | "last 1 safari version"
62 | ]
63 | },
64 | "devDependencies": {
65 | "@types/three": "^0.144.0"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/vfx/Nebula.tsx:
--------------------------------------------------------------------------------
1 | import { useTexture } from "@react-three/drei"
2 | import { GroupProps } from "@react-three/fiber"
3 | import { pipe } from "fp-ts/function"
4 | import { composable, modules } from "material-composer-r3f"
5 | import { bitmask, Layers, useRenderPipeline } from "render-composer"
6 | import {
7 | Add,
8 | Float,
9 | GlobalTime,
10 | Input,
11 | InstanceID,
12 | Mul,
13 | Rotation3DZ,
14 | ScaleAndOffset,
15 | Sub,
16 | Vec3
17 | } from "shader-composer"
18 | import { useUniformUnit } from "shader-composer-r3f"
19 | import { Random } from "shader-composer-toybox"
20 | import { Color } from "three"
21 | import { Emitter, Particles } from "vfx-composer-r3f"
22 |
23 | export type NebulaProps = {
24 | dimensions?: Input<"vec3">
25 | amount?: number
26 | rotationSpeed?: Input<"float">
27 | minSize?: Input<"float">
28 | maxSize?: Input<"float">
29 | opacity?: Input<"float">
30 | color?: Input<"vec3">
31 | } & GroupProps
32 |
33 | export const Nebula = ({
34 | amount = 25,
35 | dimensions = Vec3([10, 10, 10]),
36 | rotationSpeed = 0.03,
37 | minSize = 2,
38 | maxSize = 8,
39 | opacity = 0.5,
40 | color = new Color("#ccc"),
41 | ...props
42 | }: NebulaProps) => {
43 | const texture = useTexture("/textures/smoke.png")
44 |
45 | const { depth } = useRenderPipeline()
46 |
47 | const u_depth = useUniformUnit("sampler2D", depth)
48 |
49 | const InstanceRandom = (offset: Input<"float">) =>
50 | Random(Add(Mul(Float(InstanceID), 1.23), offset))
51 |
52 | return (
53 |
54 |
55 |
56 |
57 |
62 | {/* Apply a random rotation */}
63 |
66 |
67 | {/* Rotate over time */}
68 | ScaleAndOffset(v, 2, -1),
72 | (v) => Mul(v, rotationSpeed),
73 | (v) => Mul(v, GlobalTime),
74 | Rotation3DZ
75 | )}
76 | />
77 |
78 |
79 |
80 |
87 |
88 | Sub(v, Vec3([0.5, 0.5, 0.5])),
92 | (v) => Mul(v, dimensions)
93 | )}
94 | space="local"
95 | />
96 |
97 | {/* Color and alpha */}
98 | Mul(c, color)} />
99 | Mul(a, opacity)} />
100 |
101 | {/* Soft particles */}
102 |
103 |
104 |
105 |
106 |
107 |
108 | )
109 | }
110 |
--------------------------------------------------------------------------------
/src/vfx/AsteroidBelt.tsx:
--------------------------------------------------------------------------------
1 | import { useGLTF } from "@react-three/drei"
2 | import { GroupProps } from "@react-three/fiber"
3 | import { pipe } from "fp-ts/lib/function"
4 | import { composable, modules } from "material-composer-r3f"
5 | import {
6 | $,
7 | Add,
8 | GlobalTime,
9 | Input,
10 | InstanceID,
11 | Mat3,
12 | Mul,
13 | Pow,
14 | RotateY,
15 | Rotation3D,
16 | ScaleAndOffset,
17 | Vec3
18 | } from "shader-composer"
19 | import { Random } from "shader-composer-toybox"
20 | import { DoubleSide, Material, Mesh } from "three"
21 | import { Emitter, Particles } from "vfx-composer-r3f"
22 |
23 | export const AsteroidBelt = (props: GroupProps) => (
24 |
25 |
26 |
27 |
28 | )
29 |
30 | const SmallAsteroids = ({ amount = 10_000 }: { amount?: number }) => {
31 | const random = (offset: Input<"float">) =>
32 | Random($`${offset} + float(${InstanceID}) * 1.1005`)
33 |
34 | return (
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | )
47 | }
48 |
49 | const LargeAsteroids = ({ amount = 10_000 }: { amount?: number }) => {
50 | /* Load our asteroid model. */
51 | const gltf = useGLTF("/models/asteroid03.gltf")
52 | const mesh = gltf.scene.children[0] as Mesh
53 |
54 | /* A small helper that will return pseudo-random numbers based off of
55 | the instance ID. */
56 | const random = (offset: Input<"float">) =>
57 | Random($`${offset} + float(${InstanceID}) * 7.3`)
58 |
59 | /* Determine the instance's rotation axis. */
60 | const rotationAxis = ScaleAndOffset(
61 | Vec3([random(12), random(84), random(1)]),
62 | 2,
63 | -1
64 | )
65 |
66 | return (
67 |
68 | {/* We can hook into the material loaded from the GLTF. \o/ */}
69 |
70 | {/* Rotation */}
71 |
75 |
76 | {/* Scale */}
77 |
78 |
79 | {/* Common Belt modules */}
80 |
81 |
82 |
83 | {/* Emit all asteroids all at once. */}
84 |
85 |
86 | )
87 | }
88 |
89 | type BeltProps = {
90 | width?: Input<"float">
91 | height?: Input<"float">
92 | distance?: Input<"float">
93 | }
94 |
95 | const BeltModules = ({ width = 40, distance = 15, height = 5 }: BeltProps) => {
96 | const random = (offset: Input<"float">) =>
97 | Random($`${offset} + float(${InstanceID}) * 1.1005`)
98 |
99 | const offset = Vec3([
100 | Add(Mul(random(0.2), width), distance),
101 | ScaleAndOffset(random(0.3), height, Mul(height, -0.5)),
102 | 0
103 | ])
104 |
105 | const speed = ScaleAndOffset(Pow(random(0.25), 3), 0.05, 0.01)
106 |
107 | return (
108 | RotateY(v, Mul(random(0.4), Math.PI * 2)),
112 | (v) => RotateY(v, Mul(GlobalTime, speed))
113 | )}
114 | />
115 | )
116 | }
117 |
118 | const RotateOverTime = ({
119 | axis = Vec3([0, 0, 1]),
120 | speed = 1
121 | }: {
122 | axis: Input<"vec3">
123 | speed?: Input<"float">
124 | }) => (
125 |
126 | )
127 |
--------------------------------------------------------------------------------
/public/models/asteroid03.gltf:
--------------------------------------------------------------------------------
1 | {
2 | "asset" : {
3 | "generator" : "Khronos glTF Blender I/O v1.7.33",
4 | "version" : "2.0"
5 | },
6 | "scene" : 0,
7 | "scenes" : [
8 | {
9 | "name" : "Scene",
10 | "nodes" : [
11 | 0
12 | ]
13 | }
14 | ],
15 | "nodes" : [
16 | {
17 | "mesh" : 0,
18 | "name" : "Cube"
19 | }
20 | ],
21 | "materials" : [
22 | {
23 | "doubleSided" : true,
24 | "emissiveFactor" : [
25 | 1,
26 | 1,
27 | 1
28 | ],
29 | "emissiveTexture" : {
30 | "index" : 0
31 | },
32 | "name" : "Rock",
33 | "pbrMetallicRoughness" : {
34 | "baseColorTexture" : {
35 | "index" : 1
36 | },
37 | "metallicFactor" : 0,
38 | "roughnessFactor" : 0.9205992221832275
39 | }
40 | }
41 | ],
42 | "meshes" : [
43 | {
44 | "name" : "Cube",
45 | "primitives" : [
46 | {
47 | "attributes" : {
48 | "POSITION" : 0,
49 | "NORMAL" : 1,
50 | "TEXCOORD_0" : 2
51 | },
52 | "indices" : 3,
53 | "material" : 0
54 | }
55 | ]
56 | }
57 | ],
58 | "textures" : [
59 | {
60 | "sampler" : 0,
61 | "source" : 0
62 | },
63 | {
64 | "sampler" : 0,
65 | "source" : 1
66 | }
67 | ],
68 | "images" : [
69 | {
70 | "mimeType" : "image/png",
71 | "name" : "ImphenziaPalette01-256-GradientX4-Emission",
72 | "uri" : "ImphenziaPalette01-256-GradientX4-Emission.png"
73 | },
74 | {
75 | "mimeType" : "image/png",
76 | "name" : "ImphenziaPalette01-256-GradientX4",
77 | "uri" : "ImphenziaPalette01-256-GradientX4.png"
78 | }
79 | ],
80 | "accessors" : [
81 | {
82 | "bufferView" : 0,
83 | "componentType" : 5126,
84 | "count" : 222,
85 | "max" : [
86 | 1.5393568277359009,
87 | 1.4672664403915405,
88 | 1.903890609741211
89 | ],
90 | "min" : [
91 | -1.393629550933838,
92 | -1.146217703819275,
93 | -1.6278616189956665
94 | ],
95 | "type" : "VEC3"
96 | },
97 | {
98 | "bufferView" : 1,
99 | "componentType" : 5126,
100 | "count" : 222,
101 | "type" : "VEC3"
102 | },
103 | {
104 | "bufferView" : 2,
105 | "componentType" : 5126,
106 | "count" : 222,
107 | "type" : "VEC2"
108 | },
109 | {
110 | "bufferView" : 3,
111 | "componentType" : 5123,
112 | "count" : 258,
113 | "type" : "SCALAR"
114 | }
115 | ],
116 | "bufferViews" : [
117 | {
118 | "buffer" : 0,
119 | "byteLength" : 2664,
120 | "byteOffset" : 0
121 | },
122 | {
123 | "buffer" : 0,
124 | "byteLength" : 2664,
125 | "byteOffset" : 2664
126 | },
127 | {
128 | "buffer" : 0,
129 | "byteLength" : 1776,
130 | "byteOffset" : 5328
131 | },
132 | {
133 | "buffer" : 0,
134 | "byteLength" : 516,
135 | "byteOffset" : 7104
136 | }
137 | ],
138 | "samplers" : [
139 | {
140 | "magFilter" : 9728,
141 | "minFilter" : 9984
142 | }
143 | ],
144 | "buffers" : [
145 | {
146 | "byteLength" : 7620,
147 | "uri" : "asteroid03.bin"
148 | }
149 | ]
150 | }
151 |
--------------------------------------------------------------------------------