├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── README.md
├── dist
├── sprite-extend-3d.esm.js
├── sprite-extend-3d.js
└── sprite-extend-3d.min.js
├── docs
├── CNAME
├── assets
│ ├── compressed
│ │ ├── astc-m-y.ktx
│ │ ├── etc-m-y.ktx
│ │ ├── etc1-m-y.ktx
│ │ ├── pvrtc-m-y.ktx
│ │ ├── s3tc-m-y.ktx
│ │ └── uv.jpg
│ ├── croissant.jpg
│ ├── croissant.json
│ ├── cube
│ │ ├── negx.jpg
│ │ ├── negy.jpg
│ │ ├── negz.jpg
│ │ ├── posx.jpg
│ │ ├── posy.jpg
│ │ └── posz.jpg
│ ├── fox.jpg
│ ├── fox.json
│ ├── girl.jpg
│ ├── girl.json
│ ├── gltf
│ │ └── old_scooter
│ │ │ ├── scene.bin
│ │ │ └── scene.gltf
│ ├── goat.json
│ ├── laputa.mp4
│ ├── matcap.jpg
│ ├── octopus.jpg
│ ├── octopus.json
│ └── pbr
│ │ ├── black.jpg
│ │ ├── car-ext-color.jpg
│ │ ├── car-ext-emissive.jpg
│ │ ├── car-ext-inner.json
│ │ ├── car-ext-normal.jpg
│ │ ├── car-ext-opacity.jpg
│ │ ├── car-ext-rmo.jpg
│ │ ├── car-ext.json
│ │ ├── car-int-color.jpg
│ │ ├── car-int-normal.jpg
│ │ ├── car-int-rmo.jpg
│ │ ├── car-int.json
│ │ ├── car-shadow.jpg
│ │ ├── car-shadow.png
│ │ ├── fragment100.glsl
│ │ ├── fragment300.glsl
│ │ ├── lut.png
│ │ ├── vertex100.glsl
│ │ ├── vertex300.glsl
│ │ ├── waterfall-diffuse-RGBM.png
│ │ ├── waterfall-specular-RGBM.png
│ │ └── white.jpg
├── basic.html
├── basic2.html
├── basic3.html
├── bindtime.html
├── box.html
├── camera.html
├── compressed-textures.html
├── cube-map.html
├── curves.html
├── d3-earth-2.html
├── d3-earth-3.html
├── d3-earth-4.html
├── d3-earth-5.html
├── d3-earth-6.html
├── d3-earth-7.html
├── d3-earth-plane.html
├── d3-earth.html
├── d3-github-contributions.html
├── d3_bargraph.html
├── flat-shading-matcap.html
├── fox-orbit.html
├── fox.html
├── gltf.html
├── gpgpu-particles.html
├── groups.html
├── high-mesh-count.html
├── instancing.html
├── js
│ ├── sprite-extend-3d.esm.js
│ ├── sprite-extend-3d.js
│ └── spritejs.js
├── lib
│ ├── earth.js
│ ├── map.js
│ ├── missile.js
│ ├── missile2.js
│ ├── missile3.js
│ ├── sky.js
│ └── utils.js
├── model.html
├── model2.html
├── normal-maps.html
├── particles.html
├── pbr.html
├── polyline.html
├── polylines.html
├── post-fluid-distortion.html
├── render-to-texture.html
├── rotations.html
├── shadow-maps.html
├── skinning.html
├── skydome.html
├── sort-tansparency.html
├── test.html
├── test2.html
├── test_blend.html
├── text.html
├── textures.html
├── wireframe-shader.html
└── wireframe.html
├── examples
├── assets
│ ├── compressed
│ │ ├── astc-m-y.ktx
│ │ ├── etc-m-y.ktx
│ │ ├── etc1-m-y.ktx
│ │ ├── pvrtc-m-y.ktx
│ │ ├── s3tc-m-y.ktx
│ │ └── uv.jpg
│ ├── croissant.jpg
│ ├── croissant.json
│ ├── cube
│ │ ├── negx.jpg
│ │ ├── negy.jpg
│ │ ├── negz.jpg
│ │ ├── posx.jpg
│ │ ├── posy.jpg
│ │ └── posz.jpg
│ ├── fox.jpg
│ ├── fox.json
│ ├── girl.jpg
│ ├── girl.json
│ ├── gltf
│ │ └── old_scooter
│ │ │ ├── scene.bin
│ │ │ └── scene.gltf
│ ├── goat.json
│ ├── laputa.mp4
│ ├── matcap.jpg
│ ├── octopus.jpg
│ ├── octopus.json
│ └── pbr
│ │ ├── black.jpg
│ │ ├── car-ext-color.jpg
│ │ ├── car-ext-emissive.jpg
│ │ ├── car-ext-inner.json
│ │ ├── car-ext-normal.jpg
│ │ ├── car-ext-opacity.jpg
│ │ ├── car-ext-rmo.jpg
│ │ ├── car-ext.json
│ │ ├── car-int-color.jpg
│ │ ├── car-int-normal.jpg
│ │ ├── car-int-rmo.jpg
│ │ ├── car-int.json
│ │ ├── car-shadow.jpg
│ │ ├── car-shadow.png
│ │ ├── fragment100.glsl
│ │ ├── fragment300.glsl
│ │ ├── lut.png
│ │ ├── vertex100.glsl
│ │ ├── vertex300.glsl
│ │ ├── waterfall-diffuse-RGBM.png
│ │ ├── waterfall-specular-RGBM.png
│ │ └── white.jpg
├── basic.html
├── basic2.html
├── basic3.html
├── basic4.html
├── bindtime.html
├── bloom-shading.html
├── bloom.html
├── box.html
├── box_colors.html
├── bump_mapping.html
├── camera.html
├── cannon.html
├── cannon_mousepick.html
├── cannon_pile.html
├── compressed-textures.html
├── cube-map.html
├── curves.html
├── d3-earth-2.html
├── d3-earth-3.html
├── d3-earth-4.html
├── d3-earth-5.html
├── d3-earth-6.html
├── d3-earth-7.html
├── d3-earth-plane.html
├── d3-earth.html
├── d3-github-contributions.html
├── d3_bargraph.html
├── emissive.html
├── flat-shading-matcap.html
├── fox-orbit.html
├── fox.html
├── globe_test.html
├── gltf.html
├── gpgpu-particles.html
├── groups.html
├── high-mesh-count.html
├── instancing.html
├── interleaved.html
├── interleaved2.html
├── js
│ ├── cannon.min.js
│ └── spritejs.js
├── jupiter.html
├── lib
│ ├── earth.js
│ ├── map.js
│ ├── missile.js
│ ├── missile2.js
│ ├── missile3.js
│ ├── sky.js
│ ├── sprite-extend-3d.esm.js
│ └── utils.js
├── lights.html
├── model.html
├── model2.html
├── normal-maps.html
├── normal-maps2.html
├── orbit_autoRotate.html
├── particles.html
├── path3d.html
├── pbr.html
├── polyline.html
├── polylines.html
├── post-fluid-distortion.html
├── render-to-texture.html
├── rotations.html
├── shadow-maps.html
├── skinning.html
├── skydome.html
├── sort-tansparency.html
├── sphere_ring.html
├── sphere_test.html
├── sun.html
├── test-esm.html
├── test.html
├── test2.html
├── test_blend.html
├── text.html
├── text2.html
├── textures.html
├── wireframe-shader.html
└── wireframe.html
├── lib
├── attribute
│ ├── camera.js
│ ├── cube.js
│ ├── cylinder.js
│ ├── mesh3d.js
│ ├── node3d.js
│ ├── path3d.js
│ ├── plane.js
│ ├── polyline3d.js
│ ├── sphere.js
│ └── torus.js
├── helper
│ ├── color-attribute.js
│ ├── curve.js
│ ├── geometry.js
│ ├── light.js
│ ├── parse-color.js
│ ├── shadow.js
│ └── texture-loader.js
├── index.js
├── node
│ ├── camera.js
│ ├── cube.js
│ ├── cylinder.js
│ ├── group3d.js
│ ├── layer3d.js
│ ├── mesh3d.js
│ ├── node3d.js
│ ├── path3d.js
│ ├── plane.js
│ ├── polyline3d.js
│ ├── render-target.js
│ ├── skin.js
│ ├── sphere.js
│ └── torus.js
└── shader
│ ├── base_geometry.frag
│ ├── base_geometry.vert
│ ├── dashline.frag
│ ├── dashline.vert
│ ├── geometry.frag
│ ├── geometry.vert
│ ├── geometry_normal_map_100.frag
│ ├── geometry_normal_map_100.vert
│ ├── geometry_normal_map_300.frag
│ ├── geometry_normal_map_300.vert
│ ├── geometry_with_shadow.frag
│ ├── geometry_with_shadow.vert
│ ├── index.js
│ ├── normal.frag
│ ├── normal.vert
│ ├── polyline.frag
│ ├── polyline.vert
│ ├── texture.frag
│ ├── texture.vert
│ ├── texture_cube.frag
│ ├── texture_cube.vert
│ ├── texture_normal_map_100.frag
│ ├── texture_normal_map_100.vert
│ ├── texture_normal_map_300.frag
│ ├── texture_normal_map_300.vert
│ ├── texture_with_shadow.frag
│ └── texture_with_shadow.vert
├── package.json
├── scripts
└── compile-shaders.js
├── src
├── attribute
│ ├── camera.js
│ ├── cube.js
│ ├── cylinder.js
│ ├── mesh3d.js
│ ├── node3d.js
│ ├── path3d.js
│ ├── plane.js
│ ├── polyline3d.js
│ ├── sphere.js
│ └── torus.js
├── helper
│ ├── color-attribute.js
│ ├── curve.js
│ ├── geometry.js
│ ├── light.js
│ ├── parse-color.js
│ ├── shadow.js
│ └── texture-loader.js
├── index.js
├── node
│ ├── camera.js
│ ├── cube.js
│ ├── cylinder.js
│ ├── group3d.js
│ ├── layer3d.js
│ ├── mesh3d.js
│ ├── node3d.js
│ ├── path3d.js
│ ├── plane.js
│ ├── polyline3d.js
│ ├── render-target.js
│ ├── skin.js
│ ├── sphere.js
│ └── torus.js
└── shader
│ ├── base_geometry.frag
│ ├── base_geometry.vert
│ ├── dashline.frag
│ ├── dashline.vert
│ ├── geometry.frag
│ ├── geometry.vert
│ ├── geometry_normal_map_100.frag
│ ├── geometry_normal_map_100.vert
│ ├── geometry_normal_map_300.frag
│ ├── geometry_normal_map_300.vert
│ ├── geometry_with_shadow.frag
│ ├── geometry_with_shadow.vert
│ ├── index.js
│ ├── normal.frag
│ ├── normal.vert
│ ├── polyline.frag
│ ├── polyline.vert
│ ├── texture.frag
│ ├── texture.vert
│ ├── texture_cube.frag
│ ├── texture_cube.vert
│ ├── texture_normal_map_100.frag
│ ├── texture_normal_map_100.vert
│ ├── texture_normal_map_300.frag
│ ├── texture_normal_map_300.vert
│ ├── texture_with_shadow.frag
│ └── texture_with_shadow.vert
├── tools
├── data.obj
├── girl.json
└── obj-converter.js
├── typings
└── sprite-extend-3d.d.ts
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "modules": false,
7 | "targets": {
8 | "chrome": "59"
9 | }
10 | }
11 | ]
12 | ],
13 | "plugins": [
14 | "@babel/plugin-proposal-class-properties"
15 | ]
16 | }
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/**/*.js
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const packageConfig = require('./package.json');
2 |
3 | function toCamelCase(str) {
4 | return str.replace(/-([a-z])/ig, (str, p1) => p1.toUpperCase());
5 | }
6 |
7 | const libName = toCamelCase(packageConfig.name);
8 |
9 | module.exports = {
10 | globals: {
11 | [libName]: libName,
12 | d3: 'd3',
13 | },
14 | extends: "eslint-config-sprite",
15 | plugins: ['html'],
16 | rules: {
17 | "complexity": ["warn", 25],
18 | 'import/prefer-default-export': 'off',
19 | "no-unused-vars": 'warn',
20 | },
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .docz
3 | node_modules
4 | yarn.lock
5 | package-lock.json
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | benchmark
2 | demos
3 | docs
4 | examples
5 | misc
6 | test
7 | tools
8 | coverage
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sprite extend 3D
2 |
3 | The 3d extension for spritejs.
4 |
5 | ## Usage
6 |
7 | ```html
8 |
9 |
10 | ```
11 |
12 | ```js
13 | const vertex = /* glsl */ `
14 | precision highp float;
15 | precision highp int;
16 |
17 | attribute vec2 uv;
18 | attribute vec3 position;
19 | attribute vec3 normal;
20 |
21 | uniform mat4 modelViewMatrix;
22 | uniform mat4 projectionMatrix;
23 | uniform mat3 normalMatrix;
24 |
25 | varying vec2 vUv;
26 | varying vec3 vNormal;
27 |
28 | void main() {
29 | vUv = uv;
30 | vNormal = normalize(normalMatrix * normal);
31 |
32 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
33 | }
34 | `;
35 |
36 | const fragment = /* glsl */ `
37 | precision highp float;
38 | precision highp int;
39 |
40 | uniform float uTime;
41 | uniform sampler2D tMap;
42 |
43 | varying vec2 vUv;
44 | varying vec3 vNormal;
45 |
46 | void main() {
47 | vec3 normal = normalize(vNormal);
48 | vec3 tex = texture2D(tMap, vUv).rgb;
49 |
50 | vec3 light = normalize(vec3(0.5, 1.0, -0.3));
51 | float shading = dot(normal, light) * 0.15;
52 | gl_FragColor.rgb = tex + shading;
53 | gl_FragColor.a = 1.0;
54 | }
55 | `;
56 |
57 | const {Scene} = spritejs;
58 | const {Mesh3d} = spritejs.ext3d;
59 | const container = document.getElementById('container');
60 | const scene = new Scene({
61 | container,
62 | displayRatio: 2,
63 | });
64 | const layer = scene.layer3d('fglayer', {
65 | camera: {
66 | fov: 35,
67 | },
68 | });
69 |
70 | layer.camera.attributes.pos = [8, 5, 15];
71 | layer.camera.lookAt([0, 1.5, 0]);
72 |
73 | (async function () {
74 | const texture = await layer.createTexture('https://p3.ssl.qhimg.com/t01d6c6c93fdddf1e42.jpg');
75 | const program = layer.createProgram({
76 | vertex,
77 | fragment,
78 | uniforms: {
79 | tMap: {value: texture},
80 | },
81 | });
82 | const model = await layer.loadModel('https://s5.ssl.qhres.com/static/1eb3e9b91a296abd.json');
83 | const fox = new Mesh3d(program);
84 | fox.setGeometry(model);
85 | layer.append(fox);
86 | fox.animate([
87 | {rotateY: 0},
88 | {rotateY: 360},
89 | ], {
90 | duration: 5000,
91 | iterations: Infinity,
92 | });
93 | }());
94 | ```
95 |
96 | For more details, see [here](https://spritejs.com/#/zh-cn/guide/3d).
97 |
98 | ## Roadmap
99 |
100 | - [x] Shared Geometry
101 | - [x] RenderTarget
102 | - [x] GPGPU
103 | - [x] Polyline 3D
104 | - [x] Cubic Bezier Curve 3D
105 | - [ ] GLTF Loader
106 | - [ ] Flowmap
107 | - [ ] Documentation
108 | - [ ] More examples
109 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | 3d.spritejs.org
2 |
--------------------------------------------------------------------------------
/docs/assets/compressed/astc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/astc-m-y.ktx
--------------------------------------------------------------------------------
/docs/assets/compressed/etc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/etc-m-y.ktx
--------------------------------------------------------------------------------
/docs/assets/compressed/etc1-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/etc1-m-y.ktx
--------------------------------------------------------------------------------
/docs/assets/compressed/pvrtc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/pvrtc-m-y.ktx
--------------------------------------------------------------------------------
/docs/assets/compressed/s3tc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/s3tc-m-y.ktx
--------------------------------------------------------------------------------
/docs/assets/compressed/uv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/compressed/uv.jpg
--------------------------------------------------------------------------------
/docs/assets/croissant.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/croissant.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/negx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/negx.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/negy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/negy.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/negz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/negz.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/posx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/posx.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/posy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/posy.jpg
--------------------------------------------------------------------------------
/docs/assets/cube/posz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/cube/posz.jpg
--------------------------------------------------------------------------------
/docs/assets/fox.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/fox.jpg
--------------------------------------------------------------------------------
/docs/assets/girl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/girl.jpg
--------------------------------------------------------------------------------
/docs/assets/gltf/old_scooter/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/gltf/old_scooter/scene.bin
--------------------------------------------------------------------------------
/docs/assets/laputa.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/laputa.mp4
--------------------------------------------------------------------------------
/docs/assets/matcap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/matcap.jpg
--------------------------------------------------------------------------------
/docs/assets/octopus.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/octopus.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/black.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/black.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-ext-color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-ext-color.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-ext-emissive.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-ext-emissive.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-ext-normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-ext-normal.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-ext-opacity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-ext-opacity.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-ext-rmo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-ext-rmo.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-int-color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-int-color.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-int-normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-int-normal.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-int-rmo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-int-rmo.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-shadow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-shadow.jpg
--------------------------------------------------------------------------------
/docs/assets/pbr/car-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/car-shadow.png
--------------------------------------------------------------------------------
/docs/assets/pbr/lut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/lut.png
--------------------------------------------------------------------------------
/docs/assets/pbr/vertex100.glsl:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec2 uv;
6 | attribute vec3 normal;
7 |
8 | uniform mat3 normalMatrix;
9 | uniform mat4 modelMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 |
13 | varying vec2 vUv;
14 | varying vec3 vNormal;
15 | varying vec3 vMPos;
16 |
17 | void main() {
18 | vUv = uv;
19 | vNormal = normalize(normalMatrix * normal);
20 | vMPos = (modelMatrix * vec4(position, 1.0)).xyz;
21 |
22 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
23 | }
--------------------------------------------------------------------------------
/docs/assets/pbr/vertex300.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 | precision highp int;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 | in vec3 normal;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelMatrix;
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 projectionMatrix;
13 |
14 | out vec2 vUv;
15 | out vec3 vNormal;
16 | out vec3 vMPos;
17 |
18 | void main() {
19 | vUv = uv;
20 | vNormal = normalize(normalMatrix * normal);
21 | vMPos = (modelMatrix * vec4(position, 1.0)).xyz;
22 |
23 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
24 | }
--------------------------------------------------------------------------------
/docs/assets/pbr/waterfall-diffuse-RGBM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/waterfall-diffuse-RGBM.png
--------------------------------------------------------------------------------
/docs/assets/pbr/waterfall-specular-RGBM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/waterfall-specular-RGBM.png
--------------------------------------------------------------------------------
/docs/assets/pbr/white.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/docs/assets/pbr/white.jpg
--------------------------------------------------------------------------------
/docs/basic2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/box.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
87 |
88 |
--------------------------------------------------------------------------------
/docs/compressed-textures.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 | Compressed Textures.
27 |
28 |
95 |
96 |
--------------------------------------------------------------------------------
/docs/cube-map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 | Cube Map. Texture by
Humus
27 |
28 |
83 |
84 |
--------------------------------------------------------------------------------
/docs/curves.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
105 |
106 |
--------------------------------------------------------------------------------
/docs/d3-earth-plane.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
88 |
89 |
--------------------------------------------------------------------------------
/docs/gltf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
53 |
54 |
--------------------------------------------------------------------------------
/docs/lib/earth.js:
--------------------------------------------------------------------------------
1 | const {shaders, Sphere} = spritejs.ext3d;
2 | const defaultEarthFragment = `precision highp float;
3 | precision highp int;
4 |
5 | varying vec3 vNormal;
6 | varying vec4 vColor;
7 |
8 | uniform vec4 directionalLight; //平行光
9 |
10 | uniform sampler2D tMap;
11 | varying vec2 vUv;
12 |
13 | varying float fCos;
14 |
15 | uniform vec4 pointLightColor; // 点光源颜色
16 | uniform vec4 ambientColor; // 环境光
17 |
18 | uniform vec2 uResolution;
19 |
20 | void main() {
21 | vec4 color = vColor;
22 | vec4 texColor = texture2D(tMap, vUv);
23 | vec2 st = gl_FragCoord.xy / uResolution;
24 |
25 | vec3 light = normalize(directionalLight.xyz);
26 | float shading = dot(vNormal, light) * directionalLight.w;
27 |
28 | float alpha = texColor.a;
29 | color.rgb = mix(texColor.rgb, color.rgb, 1.0 - alpha);
30 | color.a = texColor.a + (1.0 - texColor.a) * color.a;
31 |
32 | vec3 diffuse = pointLightColor.rgb * color.rgb * pointLightColor.a * fCos;// 计算点光源漫反射颜色
33 | vec3 ambient = ambientColor.rgb * color.rgb;// 计算环境光反射颜色
34 |
35 | color = vec4(diffuse + ambient, color.a);
36 |
37 | float d = distance(st, vec2(0.5));
38 |
39 | gl_FragColor.rgb = color.rgb + shading + 0.3 * pow((1.0 - d), 3.0);
40 | gl_FragColor.a = color.a;
41 | }
42 | `;
43 |
44 | const defaultEarthVertex = shaders.GEOMETRY_WITH_TEXTURE.vertex;
45 |
46 | export function createEarth(layer, {vertex = defaultEarthVertex, fragment = defaultEarthFragment, texture, ...attrs} = {}) {
47 | const program = layer.createProgram({
48 | fragment,
49 | vertex,
50 | // transparent: true,
51 | cullFace: null,
52 | texture,
53 | });
54 |
55 | attrs = Object.assign({
56 | widthSegments: 64,
57 | heightSegments: 32,
58 | }, attrs);
59 |
60 | const earth = new Sphere(program, attrs);
61 | layer.append(earth);
62 |
63 | return earth;
64 | }
--------------------------------------------------------------------------------
/docs/lib/sky.js:
--------------------------------------------------------------------------------
1 | const vertex = `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec2 uv;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 |
13 | varying vec2 vUv;
14 |
15 | void main() {
16 | vUv = uv;
17 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
18 | }
19 | `;
20 |
21 | const fragment = `
22 | precision highp float;
23 | precision highp int;
24 | varying vec2 vUv;
25 |
26 | highp float random(vec2 co)
27 | {
28 | highp float a = 12.9898;
29 | highp float b = 78.233;
30 | highp float c = 43758.5453;
31 | highp float dt= dot(co.xy ,vec2(a,b));
32 | highp float sn= mod(dt,3.14);
33 | return fract(sin(sn) * c);
34 | }
35 |
36 | // Value Noise by Inigo Quilez - iq/2013
37 | // https://www.shadertoy.com/view/lsf3WH
38 | highp float noise(vec2 st) {
39 | vec2 i = floor(st);
40 | vec2 f = fract(st);
41 | vec2 u = f * f * (3.0 - 2.0 * f);
42 | return mix( mix( random( i + vec2(0.0,0.0) ),
43 | random( i + vec2(1.0,0.0) ), u.x),
44 | mix( random( i + vec2(0.0,1.0) ),
45 | random( i + vec2(1.0,1.0) ), u.x), u.y);
46 | }
47 |
48 | void main() {
49 | gl_FragColor.rgb = vec3(1.0);
50 | gl_FragColor.a = step(0.99, noise(vUv * 1000.0));
51 | }
52 | `;
53 |
54 | export function createSky(layer) {
55 | const {Sphere} = spritejs.ext3d;
56 | const program = layer.createProgram({
57 | vertex,
58 | fragment,
59 | transparent: true,
60 | cullFace: null,
61 | });
62 | const skyBox = new Sphere(program, {
63 |
64 | });
65 | skyBox.attributes.scale = 50;
66 | layer.append(skyBox);
67 |
68 | return skyBox;
69 | }
--------------------------------------------------------------------------------
/docs/lib/utils.js:
--------------------------------------------------------------------------------
1 | const {Vec3} = spritejs.ext3d;
2 |
3 | /**
4 | * 将平面地图坐标转换为球面坐标
5 | * @param {*} u
6 | * @param {*} v
7 | * @param {*} radius
8 | */
9 | export function project(u, v, radius = 1) {
10 | u /= 1920;
11 | v /= 1000;
12 | const pLength = Math.PI * 2;
13 | const tLength = Math.PI;
14 | const x = -radius * Math.cos(u * pLength) * Math.sin(v * tLength);
15 | const y = radius * Math.cos(v * tLength);
16 | const z = radius * Math.sin(u * pLength) * Math.sin(v * tLength);
17 | return new Vec3(x, y, z);
18 | }
19 |
20 | /**
21 | * 将球面坐标转换为平面地图坐标
22 | * @param {*} x
23 | * @param {*} y
24 | * @param {*} z
25 | * @param {*} radius
26 | */
27 | export function unproject(x, y, z, radius = 1) {
28 | const pLength = Math.PI * 2;
29 | const tLength = Math.PI;
30 | const v = Math.acos(y / radius) / tLength; // const y = radius * Math.cos(v * tLength);
31 | let u = Math.atan2(-z, x) + Math.PI; // z / x = -1 * Math.tan(u * pLength);
32 | u /= pLength;
33 | return [u * 1920, v * 1000];
34 | }
35 |
36 | /**
37 | * 将经纬度转换为球面坐标
38 | * @param {*} latitude
39 | * @param {*} longitude
40 | * @param {*} projection
41 | */
42 | export function latlng_projection(projection, latitude, longitude, radius = 1) {
43 | const [u, v] = projection([longitude, latitude]);
44 | return project(u, v, radius);
45 | }
--------------------------------------------------------------------------------
/docs/model2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
97 |
98 |
--------------------------------------------------------------------------------
/docs/rotations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
61 |
62 |
--------------------------------------------------------------------------------
/docs/skydome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
28 |
61 |
62 |
--------------------------------------------------------------------------------
/docs/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/test2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
97 |
98 |
--------------------------------------------------------------------------------
/docs/test_blend.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
22 |
23 |
24 |
25 |
96 |
97 |
--------------------------------------------------------------------------------
/docs/text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
61 |
62 |
--------------------------------------------------------------------------------
/examples/assets/compressed/astc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/astc-m-y.ktx
--------------------------------------------------------------------------------
/examples/assets/compressed/etc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/etc-m-y.ktx
--------------------------------------------------------------------------------
/examples/assets/compressed/etc1-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/etc1-m-y.ktx
--------------------------------------------------------------------------------
/examples/assets/compressed/pvrtc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/pvrtc-m-y.ktx
--------------------------------------------------------------------------------
/examples/assets/compressed/s3tc-m-y.ktx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/s3tc-m-y.ktx
--------------------------------------------------------------------------------
/examples/assets/compressed/uv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/compressed/uv.jpg
--------------------------------------------------------------------------------
/examples/assets/croissant.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/croissant.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/negx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/negx.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/negy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/negy.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/negz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/negz.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/posx.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/posx.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/posy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/posy.jpg
--------------------------------------------------------------------------------
/examples/assets/cube/posz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/cube/posz.jpg
--------------------------------------------------------------------------------
/examples/assets/fox.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/fox.jpg
--------------------------------------------------------------------------------
/examples/assets/girl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/girl.jpg
--------------------------------------------------------------------------------
/examples/assets/gltf/old_scooter/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/gltf/old_scooter/scene.bin
--------------------------------------------------------------------------------
/examples/assets/laputa.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/laputa.mp4
--------------------------------------------------------------------------------
/examples/assets/matcap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/matcap.jpg
--------------------------------------------------------------------------------
/examples/assets/octopus.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/octopus.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/black.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/black.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-ext-color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-ext-color.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-ext-emissive.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-ext-emissive.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-ext-normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-ext-normal.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-ext-opacity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-ext-opacity.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-ext-rmo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-ext-rmo.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-int-color.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-int-color.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-int-normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-int-normal.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-int-rmo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-int-rmo.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-shadow.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-shadow.jpg
--------------------------------------------------------------------------------
/examples/assets/pbr/car-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/car-shadow.png
--------------------------------------------------------------------------------
/examples/assets/pbr/lut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/lut.png
--------------------------------------------------------------------------------
/examples/assets/pbr/vertex100.glsl:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec2 uv;
6 | attribute vec3 normal;
7 |
8 | uniform mat3 normalMatrix;
9 | uniform mat4 modelMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 |
13 | varying vec2 vUv;
14 | varying vec3 vNormal;
15 | varying vec3 vMPos;
16 |
17 | void main() {
18 | vUv = uv;
19 | vNormal = normalize(normalMatrix * normal);
20 | vMPos = (modelMatrix * vec4(position, 1.0)).xyz;
21 |
22 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
23 | }
--------------------------------------------------------------------------------
/examples/assets/pbr/vertex300.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 | precision highp int;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 | in vec3 normal;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelMatrix;
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 projectionMatrix;
13 |
14 | out vec2 vUv;
15 | out vec3 vNormal;
16 | out vec3 vMPos;
17 |
18 | void main() {
19 | vUv = uv;
20 | vNormal = normalize(normalMatrix * normal);
21 | vMPos = (modelMatrix * vec4(position, 1.0)).xyz;
22 |
23 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
24 | }
--------------------------------------------------------------------------------
/examples/assets/pbr/waterfall-diffuse-RGBM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/waterfall-diffuse-RGBM.png
--------------------------------------------------------------------------------
/examples/assets/pbr/waterfall-specular-RGBM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/waterfall-specular-RGBM.png
--------------------------------------------------------------------------------
/examples/assets/pbr/white.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/examples/assets/pbr/white.jpg
--------------------------------------------------------------------------------
/examples/basic4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
69 |
70 |
--------------------------------------------------------------------------------
/examples/box.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
87 |
88 |
--------------------------------------------------------------------------------
/examples/box_colors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
91 |
92 |
--------------------------------------------------------------------------------
/examples/compressed-textures.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 | Compressed Textures.
27 |
28 |
95 |
96 |
--------------------------------------------------------------------------------
/examples/cube-map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 | Cube Map. Texture by
Humus
27 |
28 |
83 |
84 |
--------------------------------------------------------------------------------
/examples/curves.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
105 |
106 |
--------------------------------------------------------------------------------
/examples/d3-earth-plane.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
95 |
96 |
--------------------------------------------------------------------------------
/examples/emissive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
99 |
100 |
--------------------------------------------------------------------------------
/examples/gltf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
53 |
54 |
--------------------------------------------------------------------------------
/examples/interleaved.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
15 |
16 |
17 |
18 |
117 |
118 |
--------------------------------------------------------------------------------
/examples/interleaved2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
15 |
16 |
17 |
18 |
138 |
139 |
--------------------------------------------------------------------------------
/examples/lib/sky.js:
--------------------------------------------------------------------------------
1 | const vertex = `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec2 uv;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 |
13 | varying vec2 vUv;
14 |
15 | void main() {
16 | vUv = uv;
17 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
18 | }
19 | `;
20 |
21 | const fragment = `
22 | precision highp float;
23 | precision highp int;
24 | varying vec2 vUv;
25 |
26 | highp float random(vec2 co)
27 | {
28 | highp float a = 12.9898;
29 | highp float b = 78.233;
30 | highp float c = 43758.5453;
31 | highp float dt= dot(co.xy ,vec2(a,b));
32 | highp float sn= mod(dt,3.14);
33 | return fract(sin(sn) * c);
34 | }
35 |
36 | // Value Noise by Inigo Quilez - iq/2013
37 | // https://www.shadertoy.com/view/lsf3WH
38 | highp float noise(vec2 st) {
39 | vec2 i = floor(st);
40 | vec2 f = fract(st);
41 | vec2 u = f * f * (3.0 - 2.0 * f);
42 | return mix( mix( random( i + vec2(0.0,0.0) ),
43 | random( i + vec2(1.0,0.0) ), u.x),
44 | mix( random( i + vec2(0.0,1.0) ),
45 | random( i + vec2(1.0,1.0) ), u.x), u.y);
46 | }
47 |
48 | void main() {
49 | gl_FragColor.rgb = vec3(1.0);
50 | gl_FragColor.a = step(0.99, noise(vUv * 1000.0));
51 | }
52 | `;
53 |
54 | export function createSky(layer) {
55 | const {Sphere} = spritejs.ext3d;
56 | const program = layer.createProgram({
57 | vertex,
58 | fragment,
59 | transparent: true,
60 | cullFace: null,
61 | });
62 | const skyBox = new Sphere(program, {
63 |
64 | });
65 | skyBox.attributes.scale = 50;
66 | layer.append(skyBox);
67 |
68 | return skyBox;
69 | }
--------------------------------------------------------------------------------
/examples/lib/utils.js:
--------------------------------------------------------------------------------
1 | const {Vec3} = spritejs.ext3d;
2 |
3 | /**
4 | * 将平面地图坐标转换为球面坐标
5 | * @param {*} u
6 | * @param {*} v
7 | * @param {*} radius
8 | */
9 | export function project(u, v, radius = 1) {
10 | u /= 1920;
11 | v /= 1000;
12 | const pLength = Math.PI * 2;
13 | const tLength = Math.PI;
14 | const x = -radius * Math.cos(u * pLength) * Math.sin(v * tLength);
15 | const y = radius * Math.cos(v * tLength);
16 | const z = radius * Math.sin(u * pLength) * Math.sin(v * tLength);
17 | return new Vec3(x, y, z);
18 | }
19 |
20 | /**
21 | * 将球面坐标转换为平面地图坐标
22 | * @param {*} x
23 | * @param {*} y
24 | * @param {*} z
25 | * @param {*} radius
26 | */
27 | export function unproject(x, y, z, radius = 1) {
28 | const pLength = Math.PI * 2;
29 | const tLength = Math.PI;
30 | const v = Math.acos(y / radius) / tLength; // const y = radius * Math.cos(v * tLength);
31 | let u = Math.atan2(-z, x) + Math.PI; // z / x = -1 * Math.tan(u * pLength);
32 | u /= pLength;
33 | return [u * 1920, v * 1000];
34 | }
35 |
36 | /**
37 | * 将经纬度转换为球面坐标
38 | * @param {*} latitude
39 | * @param {*} longitude
40 | * @param {*} projection
41 | */
42 | export function latlng_projection(projection, latitude, longitude, radius = 1) {
43 | const [u, v] = projection([longitude, latitude]);
44 | return project(u, v, radius);
45 | }
--------------------------------------------------------------------------------
/examples/lights.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
78 |
79 |
--------------------------------------------------------------------------------
/examples/model2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
97 |
98 |
--------------------------------------------------------------------------------
/examples/normal-maps2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
86 |
87 |
--------------------------------------------------------------------------------
/examples/orbit_autoRotate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
54 |
55 |
--------------------------------------------------------------------------------
/examples/path3d.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
109 |
110 |
--------------------------------------------------------------------------------
/examples/rotations.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
61 |
62 |
--------------------------------------------------------------------------------
/examples/skydome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
28 |
61 |
62 |
--------------------------------------------------------------------------------
/examples/sphere_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
80 |
81 |
--------------------------------------------------------------------------------
/examples/test-esm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ESM
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
81 |
82 |
--------------------------------------------------------------------------------
/examples/test2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
97 |
98 |
--------------------------------------------------------------------------------
/examples/test_blend.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
22 |
23 |
24 |
25 |
96 |
97 |
--------------------------------------------------------------------------------
/examples/text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
70 |
71 |
--------------------------------------------------------------------------------
/examples/text2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
84 |
85 |
--------------------------------------------------------------------------------
/lib/attribute/camera.js:
--------------------------------------------------------------------------------
1 | import Node3dAttr from './node3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class GameraAttr extends Node3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | near: 0.1,
10 | far: 100,
11 | fov: 45,
12 | aspect: 1,
13 | left: undefined,
14 | right: undefined,
15 | bottom: undefined,
16 | top: undefined,
17 | zoom: 1,
18 | mode: 'perspective' // perspective - 透视相机, orthographic - 正交投影相机
19 |
20 | });
21 | }
22 |
23 | get near() {
24 | return this[getAttribute]('near');
25 | }
26 |
27 | set near(value) {
28 | this[setAttribute]('near', value);
29 | }
30 |
31 | get far() {
32 | return this[getAttribute]('far');
33 | }
34 |
35 | set far(value) {
36 | this[setAttribute]('far', value);
37 | }
38 |
39 | get fov() {
40 | return this[getAttribute]('fov');
41 | }
42 |
43 | set fov(value) {
44 | this[setAttribute]('fov', value);
45 | }
46 |
47 | get aspect() {
48 | return this[getAttribute]('aspect');
49 | }
50 |
51 | set aspect(value) {
52 | this[setAttribute]('aspect', value);
53 | }
54 |
55 | get left() {
56 | return this[getAttribute]('left');
57 | }
58 |
59 | set left(value) {
60 | this[setAttribute]('left', value);
61 | }
62 |
63 | get right() {
64 | return this[getAttribute]('right');
65 | }
66 |
67 | set right(value) {
68 | this[setAttribute]('right', value);
69 | }
70 |
71 | get top() {
72 | return this[getAttribute]('top');
73 | }
74 |
75 | set top(value) {
76 | this[setAttribute]('top', value);
77 | }
78 |
79 | get bottom() {
80 | return this[getAttribute]('bottom');
81 | }
82 |
83 | set bottom(value) {
84 | this[setAttribute]('bottom', value);
85 | }
86 |
87 | get zoom() {
88 | return this[getAttribute]('zoom');
89 | }
90 |
91 | set zoom(value) {
92 | this[setAttribute]('zoom', value);
93 | }
94 |
95 | get mode() {
96 | return this[getAttribute]('mode');
97 | }
98 |
99 | set mode(value) {
100 | if (value && value !== 'perspective' && value !== 'orthographic') {
101 | throw new TypeError('Invalid camera mode.');
102 | }
103 |
104 | this[setAttribute]('mode', value);
105 | }
106 |
107 | }
--------------------------------------------------------------------------------
/lib/attribute/cube.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class CubeAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | width: 1,
10 | height: 1,
11 | depth: 1,
12 |
13 | /* size */
14 | widthSegments: 1,
15 | heightSegments: 1,
16 | depthSegments: 1,
17 |
18 | /* override */
19 | colorDivisor: 4
20 | });
21 | }
22 |
23 | get width() {
24 | return this[getAttribute]('width');
25 | }
26 |
27 | set width(value) {
28 | this[setAttribute]('width', value);
29 | }
30 |
31 | get height() {
32 | return this[getAttribute]('height');
33 | }
34 |
35 | set height(value) {
36 | this[setAttribute]('height', value);
37 | }
38 |
39 | get size() {
40 | return [this.width, this.height, this.depth];
41 | }
42 |
43 | set size(value) {
44 | if (!Array.isArray(value)) value = [value, value, value];
45 | this.width = value[0];
46 | this.height = value[1];
47 | this.depth = value[2];
48 | }
49 |
50 | get depth() {
51 | return this[getAttribute]('depth');
52 | }
53 |
54 | set depth(value) {
55 | this[setAttribute]('depth', value);
56 | }
57 |
58 | get widthSegments() {
59 | return this[getAttribute]('widthSegments');
60 | }
61 |
62 | set widthSegments(value) {
63 | this[setAttribute]('widthSegments', value);
64 | }
65 |
66 | get heightSegments() {
67 | return this[getAttribute]('heightSegments');
68 | }
69 |
70 | set heightSegments(value) {
71 | this[setAttribute]('heightSegments', value);
72 | }
73 |
74 | get depthSegments() {
75 | return this[getAttribute]('depthSegments');
76 | }
77 |
78 | set depthSegments(value) {
79 | this[setAttribute]('depthSegments', value);
80 | }
81 |
82 | }
--------------------------------------------------------------------------------
/lib/attribute/cylinder.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class CylinderAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | radiusTop: 0.5,
10 | radiusBottom: 0.5,
11 |
12 | /* radius */
13 | height: 1,
14 | radialSegments: 16,
15 | heightSegments: 1,
16 | openEnded: false,
17 | thetaStart: 0,
18 | thetaLength: Math.PI * 2
19 | });
20 | }
21 |
22 | get radiusTop() {
23 | return this[getAttribute]('radiusTop');
24 | }
25 |
26 | set radiusTop(value) {
27 | this[setAttribute]('radiusTop', value);
28 | }
29 |
30 | get radiusBottom() {
31 | return this[getAttribute]('radiusBottom');
32 | }
33 |
34 | set radiusBottom(value) {
35 | this[setAttribute]('radiusBottom', value);
36 | }
37 |
38 | get radius() {
39 | return [this.radiusTop, this.radiusBottom];
40 | }
41 |
42 | set radius(value) {
43 | if (!Array.isArray(value)) value = [value, value];
44 | this.radiusTop = value[0];
45 | this.radiusBottom = value[1];
46 | }
47 |
48 | get height() {
49 | return this[getAttribute]('height');
50 | }
51 |
52 | set height(value) {
53 | this[setAttribute]('height', value);
54 | }
55 |
56 | get radialSegments() {
57 | return this[getAttribute]('radialSegments');
58 | }
59 |
60 | set radialSegments(value) {
61 | this[setAttribute]('radialSegments', value);
62 | }
63 |
64 | get heightSegments() {
65 | return this[getAttribute]('heightSegments');
66 | }
67 |
68 | set heightSegments(value) {
69 | this[setAttribute]('heightSegments', value);
70 | }
71 |
72 | get openEnded() {
73 | return this[getAttribute]('openEnded');
74 | }
75 |
76 | set openEnded(value) {
77 | this[setAttribute]('openEnded', value);
78 | }
79 |
80 | get thetaStart() {
81 | return this[getAttribute]('thetaStart');
82 | }
83 |
84 | set thetaStart(value) {
85 | this[setAttribute]('thetaStart', value);
86 | }
87 |
88 | get thetaLength() {
89 | return this[getAttribute]('thetaLength');
90 | }
91 |
92 | set thetaLength(value) {
93 | this[setAttribute]('thetaLength', value);
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/lib/attribute/mesh3d.js:
--------------------------------------------------------------------------------
1 | import { Color } from 'spritejs';
2 | import Node3dAttr from './node3d';
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 | export default class Mesh3dAttr extends Node3dAttr {
7 | constructor(subject) {
8 | super(subject);
9 | this[setDefault]({
10 | mode: 'TRIANGLES',
11 | // POINTS, LINES, LINE_LOOP, LINE_STRIP, TRIANGLES
12 | colors: [0.5, 0.5, 0.5, 1],
13 | colorDivisor: 3,
14 | raycast: 'box' // box sphere none
15 |
16 | });
17 | }
18 |
19 | get colors() {
20 | return this[getAttribute]('colors');
21 | }
22 |
23 | set colors(value) {
24 | if (typeof value === 'string') {
25 | value = value.replace(/\s*,\s*/g, ',');
26 | let colors = value.split(/\s+/g);
27 | colors = colors.map(c => {
28 | return new Color(c);
29 | });
30 | value = colors.reduce((a, b) => [...a, ...b]);
31 | } else if (Array.isArray(value)) {
32 | if (typeof value[0] === 'string') {
33 | value = value.reduce((a, b) => {
34 | a.push(...new Color(b));
35 | return a;
36 | }, []);
37 | } else if (Array.isArray(value[0])) {
38 | value = value.reduce((a, b) => [...a, ...b]);
39 | }
40 | }
41 |
42 | this[setAttribute]('colors', value);
43 | }
44 |
45 | get colorDivisor() {
46 | return this[getAttribute]('colorDivisor');
47 | }
48 |
49 | set colorDivisor(value) {
50 | this[setAttribute]('colorDivisor', value);
51 | }
52 |
53 | get mode() {
54 | return this[getAttribute]('mode');
55 | }
56 |
57 | set mode(value) {
58 | if (typeof value === 'number' && value >= 0 && value < 7) {
59 | value = ['POINTS', 'LINES', 'LINE_LOOP', 'LINE_STRIP', 'TRIANGLES', 'TRIANGLE_STRIP', 'TRIANGLE_FAN'][value];
60 | }
61 |
62 | if (value && value !== 'TRIANGLES' && value !== 'POINTS' && value !== 'LINES' && value !== 'LINE_LOOP' && value !== 'LINE_STRIP' && value !== 'TRIANGLE_STRIP' && value !== 'TRIANGLE_FAN') {
63 | throw new TypeError('Invalid mode value.');
64 | }
65 |
66 | this[setAttribute]('mode', value);
67 | }
68 |
69 | get raycast() {
70 | return this[getAttribute]('raycast');
71 | }
72 |
73 | set raycast(value) {
74 | this[setAttribute]('raycast', value);
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/lib/attribute/plane.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class PlaneAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | width: 1,
10 | height: 1,
11 | widthSegments: 1,
12 | heightSegments: 1
13 | });
14 | }
15 |
16 | get width() {
17 | return this[getAttribute]('width');
18 | }
19 |
20 | set width(value) {
21 | this[setAttribute]('width', value);
22 | }
23 |
24 | get height() {
25 | return this[getAttribute]('height');
26 | }
27 |
28 | set height(value) {
29 | this[setAttribute]('height', value);
30 | }
31 |
32 | get widthSegments() {
33 | return this[getAttribute]('widthSegments');
34 | }
35 |
36 | set widthSegments(value) {
37 | this[setAttribute]('widthSegments', value);
38 | }
39 |
40 | get heightSegments() {
41 | return this[getAttribute]('heightSegments');
42 | }
43 |
44 | set heightSegments(value) {
45 | this[setAttribute]('heightSegments', value);
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/lib/attribute/polyline3d.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class PolylineAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | points: [],
10 | raycast: 'none'
11 | });
12 | }
13 |
14 | get points() {
15 | return this[getAttribute]('points');
16 | }
17 |
18 | set points(value) {
19 | if (Array.isArray(value)) {
20 | value = value.reduce((a, b) => {
21 | if (Array.isArray(b)) {
22 | return [...a, ...b];
23 | }
24 |
25 | return [...a, b];
26 | }, []);
27 | } // if(value) { // 要去掉重复的点
28 | // if(value.length % 3) throw new Error('Invalid points set');
29 | // const points = [value[0], value[1], value[2]];
30 | // for(let i = 3; i < value.length; i += 3) {
31 | // if(value[i] !== value[i - 3] || value[i + 1] !== value[i - 2] || value[i + 2] !== value[i - 1]) {
32 | // points.push(value[i], value[i + 1], value[i + 2]);
33 | // }
34 | // }
35 | // value = points;
36 | // }
37 |
38 |
39 | this[setAttribute]('points', value);
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/lib/attribute/sphere.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class SphereAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | radius: 0.5,
10 | widthSegments: 32,
11 | heightSegments: 16,
12 | phiStart: 0,
13 | phiLength: Math.PI * 2,
14 | thetaStart: 0,
15 | thetaLength: Math.PI,
16 | raycast: 'sphere'
17 | });
18 | }
19 |
20 | get radius() {
21 | return this[getAttribute]('radius');
22 | }
23 |
24 | set radius(value) {
25 | this[setAttribute]('radius', value);
26 | }
27 |
28 | get widthSegments() {
29 | return this[getAttribute]('widthSegments');
30 | }
31 |
32 | set widthSegments(value) {
33 | this[setAttribute]('widthSegments', value);
34 | }
35 |
36 | get heightSegments() {
37 | return this[getAttribute]('heightSegments');
38 | }
39 |
40 | set heightSegments(value) {
41 | this[setAttribute]('heightSegments', value);
42 | }
43 |
44 | get phiStart() {
45 | return this[getAttribute]('phiStart');
46 | }
47 |
48 | set phiStart(value) {
49 | this[setAttribute]('phiStart', value);
50 | }
51 |
52 | get phiLength() {
53 | return this[getAttribute]('phiLength');
54 | }
55 |
56 | set phiLength(value) {
57 | this[setAttribute]('phiLength', value);
58 | }
59 |
60 | get thetaStart() {
61 | return this[getAttribute]('thetaStart');
62 | }
63 |
64 | set thetaStart(value) {
65 | this[setAttribute]('thetaStart', value);
66 | }
67 |
68 | get thetaLength() {
69 | return this[getAttribute]('thetaLength');
70 | }
71 |
72 | set thetaLength(value) {
73 | this[setAttribute]('thetaLength', value);
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/lib/attribute/torus.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 | const setAttribute = Symbol.for('spritejs_setAttribute');
3 | const getAttribute = Symbol.for('spritejs_getAttribute');
4 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
5 | export default class TorusAttr extends Mesh3dAttr {
6 | constructor(subject) {
7 | super(subject);
8 | this[setDefault]({
9 | radius: 0.5,
10 | tube: 0.2,
11 | radialSegments: 8,
12 | tubularSegments: 6,
13 | arc: Math.PI * 2
14 | });
15 | }
16 |
17 | get radius() {
18 | return this[getAttribute]('radius');
19 | }
20 |
21 | set radius(value) {
22 | this[setAttribute]('radius', value);
23 | }
24 |
25 | get tube() {
26 | return this[getAttribute]('tube');
27 | }
28 |
29 | set tube(value) {
30 | this[setAttribute]('tube', value);
31 | }
32 |
33 | get radialSegments() {
34 | return this[getAttribute]('radialSegments');
35 | }
36 |
37 | set radialSegments(value) {
38 | this[setAttribute]('radialSegments', value);
39 | }
40 |
41 | get tubularSegments() {
42 | return this[getAttribute]('tubularSegments');
43 | }
44 |
45 | set tubularSegments(value) {
46 | this[setAttribute]('tubularSegments', value);
47 | }
48 |
49 | get arc() {
50 | return this[getAttribute]('arc');
51 | }
52 |
53 | set arc(value) {
54 | this[setAttribute]('arc', value);
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/lib/helper/color-attribute.js:
--------------------------------------------------------------------------------
1 | export function colorAttribute(node, geometry) {
2 | const updateColor = geometry.attributes.color;
3 | const positions = geometry.attributes.position.data;
4 | const size = geometry.attributes.position.size || 3;
5 | const len = positions.length / size;
6 | const color = updateColor ? updateColor.data : new Float32Array(4 * len);
7 | const colors = node.attributes.colors;
8 | const colorLen = colors.length / 4;
9 | const colorDivisor = node.attributes.colorDivisor;
10 |
11 | for (let i = 0; i < len; i++) {
12 | // const color = colors
13 | const idx = Math.floor(i / colorDivisor) % colorLen;
14 | color[4 * i] = colors[idx * 4];
15 | color[4 * i + 1] = colors[idx * 4 + 1];
16 | color[4 * i + 2] = colors[idx * 4 + 2];
17 | color[4 * i + 3] = colors[idx * 4 + 3];
18 | }
19 |
20 | if (updateColor) updateColor.needsUpdate = true;
21 | return {
22 | size: 4,
23 | data: color
24 | };
25 | }
--------------------------------------------------------------------------------
/lib/helper/curve.js:
--------------------------------------------------------------------------------
1 | import { Curve as _Curve, Vec3 } from 'ogl';
2 | export default class Curve extends _Curve {
3 | constructor({
4 | points,
5 | divisions,
6 | type
7 | } = {}) {
8 | if (Array.isArray(points) && points[0] && !(points[0] instanceof Vec3)) {
9 | points = points.map(p => new Vec3().copy(p));
10 | }
11 |
12 | super({
13 | points,
14 | divisions,
15 | type
16 | });
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/lib/helper/light.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { parseColor } from './parse-color';
4 | export default class Light {
5 | constructor({
6 | angle,
7 | direction,
8 | position,
9 | blur = 0,
10 | color = [1, 1, 1, 1],
11 | decay = [0, 0, 1]
12 | } = {}) {
13 | this.angle = angle;
14 | this.blur = blur;
15 | this.color = color ? parseColor(color) : undefined;
16 | this.decay = decay;
17 | this.direction = direction;
18 | this.position = position;
19 |
20 | if (this.position && this.direction && this.angle == null) {
21 | this.angle = Math.PI / 3;
22 | }
23 | }
24 |
25 | get type() {
26 | if (this.position && this.direction) return Light.SPOT_LIGHT;
27 | if (this.position) return Light.POINT_LIGHT;
28 | if (this.direction) return Light.DIRECTIONAL_LIGHT;
29 | throw new Error('unknown light');
30 | }
31 |
32 | }
33 |
34 | _defineProperty(Light, "DIRECTIONAL_LIGHT", 0);
35 |
36 | _defineProperty(Light, "POINT_LIGHT", 1);
37 |
38 | _defineProperty(Light, "SPOT_LIGHT", 2);
--------------------------------------------------------------------------------
/lib/helper/parse-color.js:
--------------------------------------------------------------------------------
1 | import { Color } from 'spritejs';
2 | export function parseColor(colors) {
3 | if (Array.isArray(colors)) {
4 | return colors.map(c => {
5 | if (typeof c === 'string') {
6 | return new Color(c);
7 | }
8 |
9 | return c;
10 | });
11 | }
12 |
13 | return typeof colors === 'string' ? new Color(colors) : colors;
14 | }
--------------------------------------------------------------------------------
/lib/helper/shadow.js:
--------------------------------------------------------------------------------
1 | import { Shadow as _Shadow } from 'ogl'; // https://github.com/oframe/ogl/blob/master/src/extras/Shadow.js
2 |
3 | export default class Shadow extends _Shadow {
4 | async add(node, opts = {}) {
5 | await node.model;
6 | opts.mesh = node.body;
7 | node.addEventListener('updatemesh', evt => {
8 | const oldMesh = evt.detail.oldMesh;
9 | this.castMeshes = this.castMeshes.filter(mesh => mesh !== oldMesh);
10 | this.add(node, opts);
11 | });
12 | super.add(opts);
13 | }
14 |
15 | remove(node) {
16 | const mesh = node.body;
17 |
18 | if (mesh) {
19 | const idx = this.castMeshes.indexOf(mesh);
20 |
21 | if (idx >= 0) {
22 | this.castMeshes.splice(idx, 1);
23 | return true;
24 | }
25 | }
26 |
27 | return false;
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/lib/helper/texture-loader.js:
--------------------------------------------------------------------------------
1 | import { TextureLoader as _TextureLoader } from 'ogl';
2 | export default class TextureLoader {
3 | static load(layer, opts) {
4 | const texture = _TextureLoader.load(layer.gl, opts);
5 |
6 | if (texture && texture.loaded && texture.loaded.then) {
7 | // load loadKTX
8 | texture.loaded.then(() => {
9 | layer.forceUpdate();
10 | });
11 | } else if (texture && texture.then) {
12 | // load Image
13 | texture.then(() => {
14 | layer.forceUpdate();
15 | });
16 | }
17 |
18 | return texture;
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | import { Raycast, GPGPU, Vec2, Vec3, Vec4, Mat3, Mat4, Quat, Euler, RenderTarget as FrameBuffer } from 'ogl';
2 | import Layer3d from './node/layer3d';
3 | import Mesh3d from './node/mesh3d';
4 | import Skin from './node/skin';
5 | import Sphere from './node/sphere';
6 | import Torus from './node/torus';
7 | import Camera from './node/camera';
8 | import Cube from './node/cube';
9 | import Curve from './helper/curve';
10 | import Plane from './node/plane';
11 | import Polyline3d from './node/polyline3d';
12 | import Cylinder from './node/cylinder';
13 | import Path3d from './node/path3d';
14 | import Group3d from './node/group3d';
15 | import RenderTarget from './node/render-target';
16 | import Shadow from './helper/shadow';
17 | import TextureLoader from './helper/texture-loader';
18 | import Geometry from './helper/geometry';
19 | import Light from './helper/light';
20 | import * as shaders from './shader';
21 | export { Layer3d, Sphere, Torus, Plane, Polyline3d, Camera, Cube, Cylinder, Path3d, Mesh3d, Skin, Group3d, RenderTarget, Shadow, Light, TextureLoader, Geometry, Curve, shaders, Vec2, Vec3, Vec4, Mat3, Mat4, Quat, Euler, GPGPU, Raycast, FrameBuffer };
--------------------------------------------------------------------------------
/lib/node/cube.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { registerNode } from 'spritejs';
4 | import { Box } from 'ogl';
5 | import Mesh3d from './mesh3d';
6 | import CubeAttr from '../attribute/cube';
7 | export default class Cube extends Mesh3d {
8 | /* override */
9 | onPropertyChange(key, newValue, oldValue) {
10 | super.onPropertyChange(key, newValue, oldValue);
11 |
12 | if (key === 'width' || key === 'height' || key === 'depth' || key === 'widthSegments' || key === 'heightSegments' || key === 'depthSegments') {
13 | if (newValue !== oldValue) {
14 | this.updateMesh();
15 | }
16 | }
17 | }
18 | /* override */
19 |
20 |
21 | remesh() {
22 | const gl = this.program.gl;
23 | const {
24 | width,
25 | height,
26 | depth,
27 | widthSegments,
28 | heightSegments,
29 | depthSegments
30 | } = this.attributes;
31 | const geometry = new Box(gl, {
32 | width,
33 | height,
34 | depth,
35 | widthSegments,
36 | heightSegments,
37 | depthSegments
38 | });
39 | this.setGeometry(geometry);
40 | }
41 |
42 | }
43 |
44 | _defineProperty(Cube, "Attr", CubeAttr);
45 |
46 | registerNode(Cube, 'cube');
--------------------------------------------------------------------------------
/lib/node/cylinder.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { registerNode } from 'spritejs';
4 | import { Cylinder as _Cylinder } from 'ogl';
5 | import CylinderAttr from '../attribute/cylinder';
6 | import Mesh3d from './mesh3d';
7 | export default class Cylinder extends Mesh3d {
8 | /* override */
9 | onPropertyChange(key, newValue, oldValue) {
10 | super.onPropertyChange(key, newValue, oldValue);
11 |
12 | if (key === 'radiusTop' || key === 'radiusBottom' || key === 'height' || key === 'radialSegments' || key === 'heightSegments' || key === 'openEnded' || key === 'thetaStart' || key === 'thetaLength') {
13 | if (newValue !== oldValue) {
14 | this.updateMesh();
15 | }
16 | }
17 | }
18 | /* override */
19 |
20 |
21 | remesh() {
22 | const gl = this.program.gl;
23 | const {
24 | radiusTop,
25 | radiusBottom,
26 | height,
27 | radialSegments,
28 | heightSegments,
29 | openEnded,
30 | thetaStart,
31 | thetaLength
32 | } = this.attributes;
33 | const geometry = new _Cylinder(gl, {
34 | radiusTop,
35 | radiusBottom,
36 | height,
37 | radialSegments,
38 | heightSegments,
39 | openEnded,
40 | thetaStart,
41 | thetaLength
42 | });
43 | this.setGeometry(geometry);
44 | }
45 |
46 | }
47 |
48 | _defineProperty(Cylinder, "Attr", CylinderAttr);
49 |
50 | registerNode(Cylinder, 'cylinder');
--------------------------------------------------------------------------------
/lib/node/plane.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { registerNode } from 'spritejs';
4 | import { Plane as _Plane } from 'ogl';
5 | import PlaneAttr from '../attribute/plane';
6 | import Mesh3d from './mesh3d';
7 | export default class Plane extends Mesh3d {
8 | /* override */
9 | onPropertyChange(key, newValue, oldValue) {
10 | super.onPropertyChange(key, newValue, oldValue);
11 |
12 | if (key === 'width' || key === 'height' || key === 'widthSegments' || key === 'heightSegments') {
13 | if (newValue !== oldValue) {
14 | this.updateMesh();
15 | }
16 | }
17 | }
18 | /* override */
19 |
20 |
21 | remesh() {
22 | const gl = this.program.gl;
23 | const {
24 | width,
25 | height,
26 | widthSegments,
27 | heightSegments
28 | } = this.attributes;
29 | const geometry = new _Plane(gl, {
30 | width,
31 | height,
32 | widthSegments,
33 | heightSegments
34 | });
35 | this.setGeometry(geometry);
36 | }
37 |
38 | }
39 |
40 | _defineProperty(Plane, "Attr", PlaneAttr);
41 |
42 | registerNode(Plane, 'plane');
--------------------------------------------------------------------------------
/lib/node/sphere.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { registerNode } from 'spritejs';
4 | import { Sphere as _Sphere } from 'ogl';
5 | import SphereAttr from '../attribute/sphere';
6 | import Mesh3d from './mesh3d';
7 | export default class Sphere extends Mesh3d {
8 | /* override */
9 | onPropertyChange(key, newValue, oldValue) {
10 | super.onPropertyChange(key, newValue, oldValue);
11 |
12 | if (key === 'radius' || key === 'widthSegments' || key === 'heightSegments' || key === 'phiStart' || key === 'phiLength' || key === 'thetaStart' || key === 'thetaLength') {
13 | if (newValue !== oldValue) {
14 | this.updateMesh();
15 | }
16 | }
17 | }
18 | /* override */
19 |
20 |
21 | remesh() {
22 | const gl = this.program.gl;
23 | const {
24 | radius,
25 | widthSegments,
26 | heightSegments,
27 | phiStart,
28 | phiLength,
29 | thetaStart,
30 | thetaLength
31 | } = this.attributes;
32 | const geometry = new _Sphere(gl, {
33 | radius,
34 | widthSegments,
35 | heightSegments,
36 | phiStart,
37 | phiLength,
38 | thetaStart,
39 | thetaLength
40 | });
41 | this.setGeometry(geometry);
42 | }
43 |
44 | }
45 |
46 | _defineProperty(Sphere, "Attr", SphereAttr);
47 |
48 | registerNode(Sphere, 'sphere');
--------------------------------------------------------------------------------
/lib/node/torus.js:
--------------------------------------------------------------------------------
1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2 |
3 | import { registerNode } from 'spritejs';
4 | import { Torus as _Torus } from 'ogl';
5 | import TorusAttr from '../attribute/torus';
6 | import Mesh3d from './mesh3d';
7 | export default class Torus extends Mesh3d {
8 | /* override */
9 | onPropertyChange(key, newValue, oldValue) {
10 | super.onPropertyChange(key, newValue, oldValue);
11 |
12 | if (key === 'radius' || key === 'tube' || key === 'radialSegments' || key === 'tubularSegments' || key === 'arc') {
13 | if (newValue !== oldValue) {
14 | this.updateMesh();
15 | }
16 | }
17 | }
18 | /* override */
19 |
20 |
21 | remesh() {
22 | const gl = this.program.gl;
23 | const {
24 | radius,
25 | tube,
26 | radialSegments,
27 | tubularSegments,
28 | arc
29 | } = this.attributes;
30 | const geometry = new _Torus(gl, {
31 | radius,
32 | tube,
33 | radialSegments,
34 | tubularSegments,
35 | arc
36 | });
37 | this.setGeometry(geometry);
38 | }
39 |
40 | }
41 |
42 | _defineProperty(Torus, "Attr", TorusAttr);
43 |
44 | registerNode(Torus, 'torus');
--------------------------------------------------------------------------------
/lib/shader/base_geometry.frag:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | varying vec4 vColor;
6 |
7 | void main() {
8 | gl_FragColor = vColor;
9 | }
10 | `;
--------------------------------------------------------------------------------
/lib/shader/base_geometry.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec4 color;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 |
11 | varying vec4 vColor;
12 |
13 | void main() {
14 | vColor = color;
15 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);;
16 | }
17 | `;
--------------------------------------------------------------------------------
/lib/shader/dashline.frag:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 |
4 | uniform float uTotalLength;
5 | uniform float uDashLength;
6 | uniform float uDashOffset;
7 |
8 | varying vec4 vColor;
9 | varying vec2 vUv;
10 | varying float fSeg;
11 |
12 | void main() {
13 | float f = fract((uDashOffset + fSeg) / (2.0 * uDashLength));
14 | f = 1.0 - step(0.5, f);
15 | gl_FragColor = vColor * f;
16 | }
17 | `;
--------------------------------------------------------------------------------
/lib/shader/dashline.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | attribute vec3 position;
4 | attribute vec3 next;
5 | attribute vec3 prev;
6 | attribute vec2 uv;
7 | attribute float side;
8 | attribute vec4 color;
9 | attribute float seg;
10 |
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 projectionMatrix;
13 | uniform vec2 uResolution;
14 | uniform float uDPR;
15 | uniform float uThickness;
16 | uniform float uMiter;
17 |
18 | varying vec2 vUv;
19 | varying vec4 vColor;
20 | varying float fSeg;
21 |
22 | vec4 getPosition() {
23 | mat4 mvp = projectionMatrix * modelViewMatrix;
24 | vec4 current = mvp * vec4(position, 1);
25 | vec4 nextPos = mvp * vec4(next, 1);
26 | vec4 prevPos = mvp * vec4(prev, 1);
27 | vec2 aspect = vec2(uResolution.x / uResolution.y, 1);
28 | vec2 currentScreen = current.xy / current.w * aspect;
29 | vec2 nextScreen = nextPos.xy / nextPos.w * aspect;
30 | vec2 prevScreen = prevPos.xy / prevPos.w * aspect;
31 |
32 | vec2 dir1 = normalize(currentScreen - prevScreen);
33 | vec2 dir2 = normalize(nextScreen - currentScreen);
34 | vec2 dir = normalize(dir1 + dir2);
35 |
36 | vec2 normal = vec2(-dir.y, dir.x);
37 | normal /= mix(1.0, max(0.3, dot(normal, vec2(-dir1.y, dir1.x))), uMiter);
38 | normal /= aspect;
39 | float pixelWidthRatio = 1.0 / (uResolution.y / uDPR);
40 | float pixelWidth = current.w * pixelWidthRatio;
41 | normal *= pixelWidth * uThickness;
42 | current.xy -= normal * side;
43 | return current;
44 | }
45 |
46 | void main() {
47 | vUv = uv;
48 | gl_Position = getPosition();
49 | vColor = color;
50 | fSeg = seg;
51 | }
52 | `;
--------------------------------------------------------------------------------
/lib/shader/geometry.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 viewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 | uniform vec3 cameraPosition;
14 |
15 | varying vec3 vNormal;
16 | varying vec4 vColor;
17 | varying vec4 vPos;
18 | varying vec3 vCameraPos;
19 |
20 | void main() {
21 | vNormal = normalize(normalMatrix * normal);
22 | vPos = modelViewMatrix * vec4(position, 1.0);;
23 | vColor = color;
24 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
25 | gl_Position = projectionMatrix * vPos;
26 | }
27 | `;
--------------------------------------------------------------------------------
/lib/shader/geometry_normal_map_100.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec2 uv;
7 | attribute vec3 normal;
8 | attribute vec4 color;
9 |
10 | uniform mat3 normalMatrix;
11 | uniform mat4 modelMatrix;
12 | uniform mat4 modelViewMatrix;
13 | uniform mat4 viewMatrix;
14 | uniform mat4 projectionMatrix;
15 | uniform vec3 cameraPosition;
16 |
17 | varying vec2 vUv;
18 | varying vec3 vNormal;
19 | varying vec4 vColor;
20 | varying vec4 vPos;
21 | varying vec3 vCameraPos;
22 |
23 | void main() {
24 | vUv = uv;
25 | vNormal = normalize(normalMatrix * normal);
26 | vColor = color;
27 | vPos = modelViewMatrix * vec4(position, 1.0);
28 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
29 |
30 | gl_Position = projectionMatrix * vPos;
31 | }
32 | `;
--------------------------------------------------------------------------------
/lib/shader/geometry_normal_map_300.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | #version 300 es
3 | precision highp float;
4 | precision highp int;
5 |
6 | in vec3 position;
7 | in vec2 uv;
8 | in vec3 normal;
9 | in vec4 color;
10 |
11 | uniform mat3 normalMatrix;
12 | uniform mat4 modelMatrix;
13 | uniform mat4 modelViewMatrix;
14 | uniform mat4 viewMatrix;
15 | uniform mat4 projectionMatrix;
16 | uniform vec3 cameraPosition;
17 |
18 | out vec2 vUv;
19 | out vec3 vNormal;
20 | out vec4 vColor;
21 | out vec4 vPos;
22 | out vec3 vCameraPos;
23 |
24 | void main() {
25 | vUv = uv;
26 | vNormal = normalize(normalMatrix * normal);
27 | vColor = color;
28 | vPos = modelViewMatrix * vec4(position, 1.0);
29 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
30 |
31 | gl_Position = projectionMatrix * vPos;
32 | }
33 | `;
--------------------------------------------------------------------------------
/lib/shader/geometry_with_shadow.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 |
9 | uniform mat4 modelMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 viewMatrix;
12 | uniform mat4 projectionMatrix;
13 | uniform mat3 normalMatrix;
14 |
15 | uniform mat4 shadowViewMatrix;
16 | uniform mat4 shadowProjectionMatrix;
17 | uniform vec3 cameraPosition;
18 |
19 | varying vec3 vNormal;
20 | varying vec4 vColor;
21 | varying vec4 vLightNDC;
22 | varying vec4 vPos;
23 | varying vec3 vCameraPos;
24 |
25 | // Matrix to shift range from -1->1 to 0->1
26 | const mat4 depthScaleMatrix = mat4(
27 | 0.5, 0, 0, 0,
28 | 0, 0.5, 0, 0,
29 | 0, 0, 0.5, 0,
30 | 0.5, 0.5, 0.5, 1
31 | );
32 |
33 | void main() {
34 | vNormal = normalize(normalMatrix * normal);
35 | vPos = modelViewMatrix * vec4(position, 1.0);
36 | vColor = color;
37 | vLightNDC = depthScaleMatrix * shadowProjectionMatrix * shadowViewMatrix * modelMatrix * vec4(position, 1.0);
38 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
39 | gl_Position = projectionMatrix * vPos;
40 | }
41 | `;
--------------------------------------------------------------------------------
/lib/shader/normal.frag:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | varying vec3 vNormal;
6 |
7 | void main() {
8 | gl_FragColor.rgb = normalize(vNormal);
9 | gl_FragColor.a = 1.0;
10 | }
11 | `;
--------------------------------------------------------------------------------
/lib/shader/normal.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 |
8 | uniform mat3 normalMatrix;
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 projectionMatrix;
11 |
12 | varying vec3 vNormal;
13 |
14 | void main() {
15 | vNormal = normalize(normalMatrix * normal);
16 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
17 | }
18 | `;
--------------------------------------------------------------------------------
/lib/shader/polyline.frag:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 |
4 | varying vec4 vColor;
5 |
6 | void main() {
7 | gl_FragColor = vColor;
8 | }
9 | `;
--------------------------------------------------------------------------------
/lib/shader/polyline.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | attribute vec3 position;
4 | attribute vec3 next;
5 | attribute vec3 prev;
6 | attribute float side;
7 | attribute vec4 color;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 projectionMatrix;
11 | uniform vec2 uResolution;
12 | uniform float uDPR;
13 | uniform float uThickness;
14 | uniform float uMiter;
15 |
16 | varying vec4 vColor;
17 |
18 | vec4 getPosition() {
19 | mat4 mvp = projectionMatrix * modelViewMatrix;
20 | vec4 current = mvp * vec4(position, 1);
21 | vec4 nextPos = mvp * vec4(next, 1);
22 | vec4 prevPos = mvp * vec4(prev, 1);
23 | vec2 aspect = vec2(uResolution.x / uResolution.y, 1);
24 | vec2 currentScreen = current.xy / current.w * aspect;
25 | vec2 nextScreen = nextPos.xy / nextPos.w * aspect;
26 | vec2 prevScreen = prevPos.xy / prevPos.w * aspect;
27 |
28 | vec2 dir1 = normalize(currentScreen - prevScreen);
29 | vec2 dir2 = normalize(nextScreen - currentScreen);
30 | vec2 dir = normalize(dir1 + dir2);
31 |
32 | vec2 normal = vec2(-dir.y, dir.x);
33 | normal /= mix(1.0, max(0.3, dot(normal, vec2(-dir1.y, dir1.x))), uMiter);
34 | normal /= aspect;
35 | float pixelWidthRatio = 1.0 / (uResolution.y / uDPR);
36 | float pixelWidth = current.w * pixelWidthRatio;
37 | normal *= pixelWidth * uThickness;
38 | current.xy -= normal * side;
39 | return current;
40 | }
41 |
42 | void main() {
43 | gl_Position = getPosition();
44 | vColor = color;
45 | }
46 | `;
--------------------------------------------------------------------------------
/lib/shader/texture.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 | attribute vec2 uv;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 viewMatrix;
12 | uniform mat4 projectionMatrix;
13 | uniform mat3 normalMatrix;
14 | uniform vec3 cameraPosition;
15 |
16 | varying vec3 vNormal;
17 | varying vec4 vColor;
18 | varying vec2 vUv;
19 | varying vec4 vPos;
20 | varying vec3 vCameraPos;
21 |
22 | void main() {
23 | vNormal = normalize(normalMatrix * normal);
24 | vPos = modelViewMatrix * vec4(position, 1.0);
25 | vColor = color;
26 | vUv = uv;
27 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
28 | gl_Position = projectionMatrix * vPos;
29 | }
30 | `;
--------------------------------------------------------------------------------
/lib/shader/texture_cube.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 viewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 | uniform vec3 cameraPosition;
14 |
15 | varying vec3 vNormal;
16 | varying vec3 vDir;
17 | varying vec4 vColor;
18 | varying vec4 vPos;
19 | varying vec3 vCameraPos;
20 |
21 | void main() {
22 | vNormal = normalize(normalMatrix * normal);
23 | vPos = modelViewMatrix * vec4(position, 1.0);
24 | vDir = normalize(position);
25 | vColor = color;
26 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
27 | gl_Position = projectionMatrix * vPos;
28 | }
29 | `;
--------------------------------------------------------------------------------
/lib/shader/texture_normal_map_100.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec2 uv;
7 | attribute vec3 normal;
8 | attribute vec4 color;
9 |
10 | uniform mat3 normalMatrix;
11 | uniform mat4 modelMatrix;
12 | uniform mat4 modelViewMatrix;
13 | uniform mat4 viewMatrix;
14 | uniform mat4 projectionMatrix;
15 | uniform vec3 cameraPosition;
16 |
17 | varying vec2 vUv;
18 | varying vec3 vNormal;
19 | varying vec4 vColor;
20 | varying vec4 vPos;
21 | varying vec3 vCameraPos;
22 |
23 | void main() {
24 | vUv = uv;
25 | vNormal = normalize(normalMatrix * normal);
26 | vColor = color;
27 | vPos = modelViewMatrix * vec4(position, 1.0);
28 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
29 |
30 | gl_Position = projectionMatrix * vPos;
31 | }
32 | `;
--------------------------------------------------------------------------------
/lib/shader/texture_normal_map_300.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | #version 300 es
3 | precision highp float;
4 | precision highp int;
5 |
6 | in vec3 position;
7 | in vec2 uv;
8 | in vec3 normal;
9 | in vec4 color;
10 |
11 | uniform mat3 normalMatrix;
12 | uniform mat4 modelMatrix;
13 | uniform mat4 modelViewMatrix;
14 | uniform mat4 viewMatrix;
15 | uniform mat4 projectionMatrix;
16 | uniform vec3 cameraPosition;
17 |
18 | out vec2 vUv;
19 | out vec3 vNormal;
20 | out vec4 vColor;
21 | out vec4 vPos;
22 | out vec3 vCameraPos;
23 |
24 | void main() {
25 | vUv = uv;
26 | vNormal = normalize(normalMatrix * normal);
27 | vColor = color;
28 | vPos = modelViewMatrix * vec4(position, 1.0);
29 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
30 |
31 | gl_Position = projectionMatrix * vPos;
32 | }
33 | `;
--------------------------------------------------------------------------------
/lib/shader/texture_with_shadow.vert:
--------------------------------------------------------------------------------
1 | export default `
2 | precision highp float;
3 | precision highp int;
4 |
5 | attribute vec3 position;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 | attribute vec2 uv;
9 |
10 | uniform mat4 modelMatrix;
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 viewMatrix;
13 | uniform mat4 projectionMatrix;
14 | uniform mat3 normalMatrix;
15 | uniform vec3 cameraPosition;
16 |
17 | varying vec3 vNormal;
18 | varying vec2 vUv;
19 | varying vec4 vColor;
20 | varying vec4 vLightNDC;
21 | varying vec4 vPos;
22 | varying vec3 vCameraPos;
23 |
24 | uniform mat4 shadowViewMatrix;
25 | uniform mat4 shadowProjectionMatrix;
26 |
27 | // Matrix to shift range from -1->1 to 0->1
28 | const mat4 depthScaleMatrix = mat4(
29 | 0.5, 0, 0, 0,
30 | 0, 0.5, 0, 0,
31 | 0, 0, 0.5, 0,
32 | 0.5, 0.5, 0.5, 1
33 | );
34 |
35 | void main() {
36 | vNormal = normalize(normalMatrix * normal);
37 | vPos = modelViewMatrix * vec4(position, 1.0);
38 | vColor = color;
39 | vUv = uv;
40 | vLightNDC = depthScaleMatrix * shadowProjectionMatrix * shadowViewMatrix * modelMatrix * vec4(position, 1.0);
41 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
42 | gl_Position = projectionMatrix * vPos;
43 | }
44 | `;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sprite-extend-3d",
3 | "version": "0.14.7",
4 | "description": "The 3d part of spritejs v3.",
5 | "main": "dist/sprite-extend-3d.js",
6 | "module": "lib/index.js",
7 | "typings": "typings/sprite-extend-3d.js",
8 | "scripts": {
9 | "start": "webpack-dev-server --env.server=examples --watch-poll",
10 | "compile": "rm -rf lib/* && babel src -d lib && node ./scripts/compile-shaders.js",
11 | "spritejs:update": "cp ./node_modules/spritejs/dist/spritejs.es.js ./examples/js/spritejs.js",
12 | "build": "webpack --env.mode=none & webpack --env.mode=production & webpack --env.mode=none --env.module && cp ./dist/sprite-extend-3d.esm.js ./examples/lib",
13 | "build:dev": "webpack --env.mode=none",
14 | "docs": "rm -rf ./docs && cp -R ./examples ./docs && cp -R ./dist/* ./docs/js/ && echo '3d.spritejs.org' > ./docs/CNAME",
15 | "prepublishOnly": "npm run compile && npm run build",
16 | "test": "echo \"Error: no test specified\" && exit 1"
17 | },
18 | "keywords": [],
19 | "author": "akira-cn",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "@babel/cli": "^7.4.4",
23 | "@babel/core": "^7.4.5",
24 | "@babel/plugin-proposal-class-properties": "^7.4.4",
25 | "@babel/plugin-transform-runtime": "^7.4.4",
26 | "@babel/preset-env": "^7.4.5",
27 | "@purtuga/esm-webpack-plugin": "^1.2.1",
28 | "babel-eslint": "^10.0.1",
29 | "babel-loader": "^8.0.6",
30 | "eslint": "^5.16.0",
31 | "eslint-config-sprite": "^1.0.6",
32 | "eslint-plugin-html": "^5.0.5",
33 | "raw-loader": "^4.0.0",
34 | "webgl-obj-loader": "^2.0.6",
35 | "webpack": "^4.33.0",
36 | "webpack-cli": "^3.3.4",
37 | "webpack-dev-server": "^3.11.0"
38 | },
39 | "dependencies": {
40 | "@babel/runtime": "^7.4.5",
41 | "ogl": "0.0.76",
42 | "spritejs": "^3.7.21"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/scripts/compile-shaders.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 |
5 | const sourceDir = path.resolve(__dirname, '../src/shader');
6 | const destDir = path.resolve(__dirname, '../lib/shader');
7 |
8 | fs.readdir(sourceDir, (err, files) => {
9 | files.forEach((file) => {
10 | if(/\.(vert|frag)/.test(file)) {
11 | const sourcePath = path.resolve(sourceDir, file);
12 | const content = fs.readFileSync(sourcePath, {encoding: 'utf-8'});
13 | const destPath = path.resolve(destDir, file);
14 | fs.writeFileSync(destPath, `export default \`
15 | ${content}
16 | \`;`);
17 | }
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/attribute/camera.js:
--------------------------------------------------------------------------------
1 | import Node3dAttr from './node3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class GameraAttr extends Node3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | near: 0.1,
12 | far: 100,
13 | fov: 45,
14 | aspect: 1,
15 | left: undefined,
16 | right: undefined,
17 | bottom: undefined,
18 | top: undefined,
19 | zoom: 1,
20 | mode: 'perspective', // perspective - 透视相机, orthographic - 正交投影相机
21 | });
22 | }
23 |
24 | get near() {
25 | return this[getAttribute]('near');
26 | }
27 |
28 | set near(value) {
29 | this[setAttribute]('near', value);
30 | }
31 |
32 | get far() {
33 | return this[getAttribute]('far');
34 | }
35 |
36 | set far(value) {
37 | this[setAttribute]('far', value);
38 | }
39 |
40 | get fov() {
41 | return this[getAttribute]('fov');
42 | }
43 |
44 | set fov(value) {
45 | this[setAttribute]('fov', value);
46 | }
47 |
48 | get aspect() {
49 | return this[getAttribute]('aspect');
50 | }
51 |
52 | set aspect(value) {
53 | this[setAttribute]('aspect', value);
54 | }
55 |
56 | get left() {
57 | return this[getAttribute]('left');
58 | }
59 |
60 | set left(value) {
61 | this[setAttribute]('left', value);
62 | }
63 |
64 | get right() {
65 | return this[getAttribute]('right');
66 | }
67 |
68 | set right(value) {
69 | this[setAttribute]('right', value);
70 | }
71 |
72 | get top() {
73 | return this[getAttribute]('top');
74 | }
75 |
76 | set top(value) {
77 | this[setAttribute]('top', value);
78 | }
79 |
80 | get bottom() {
81 | return this[getAttribute]('bottom');
82 | }
83 |
84 | set bottom(value) {
85 | this[setAttribute]('bottom', value);
86 | }
87 |
88 | get zoom() {
89 | return this[getAttribute]('zoom');
90 | }
91 |
92 | set zoom(value) {
93 | this[setAttribute]('zoom', value);
94 | }
95 |
96 | get mode() {
97 | return this[getAttribute]('mode');
98 | }
99 |
100 | set mode(value) {
101 | if(value && value !== 'perspective' && value !== 'orthographic') {
102 | throw new TypeError('Invalid camera mode.');
103 | }
104 | this[setAttribute]('mode', value);
105 | }
106 | }
--------------------------------------------------------------------------------
/src/attribute/cube.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class CubeAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | width: 1,
12 | height: 1,
13 | depth: 1,
14 | /* size */
15 | widthSegments: 1,
16 | heightSegments: 1,
17 | depthSegments: 1,
18 | /* override */
19 | colorDivisor: 4,
20 | });
21 | }
22 |
23 | get width() {
24 | return this[getAttribute]('width');
25 | }
26 |
27 | set width(value) {
28 | this[setAttribute]('width', value);
29 | }
30 |
31 | get height() {
32 | return this[getAttribute]('height');
33 | }
34 |
35 | set height(value) {
36 | this[setAttribute]('height', value);
37 | }
38 |
39 | get size() {
40 | return [this.width, this.height, this.depth];
41 | }
42 |
43 | set size(value) {
44 | if(!Array.isArray(value)) value = [value, value, value];
45 | this.width = value[0];
46 | this.height = value[1];
47 | this.depth = value[2];
48 | }
49 |
50 | get depth() {
51 | return this[getAttribute]('depth');
52 | }
53 |
54 | set depth(value) {
55 | this[setAttribute]('depth', value);
56 | }
57 |
58 | get widthSegments() {
59 | return this[getAttribute]('widthSegments');
60 | }
61 |
62 | set widthSegments(value) {
63 | this[setAttribute]('widthSegments', value);
64 | }
65 |
66 | get heightSegments() {
67 | return this[getAttribute]('heightSegments');
68 | }
69 |
70 | set heightSegments(value) {
71 | this[setAttribute]('heightSegments', value);
72 | }
73 |
74 | get depthSegments() {
75 | return this[getAttribute]('depthSegments');
76 | }
77 |
78 | set depthSegments(value) {
79 | this[setAttribute]('depthSegments', value);
80 | }
81 | }
--------------------------------------------------------------------------------
/src/attribute/cylinder.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class CylinderAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | radiusTop: 0.5,
12 | radiusBottom: 0.5,
13 | /* radius */
14 | height: 1,
15 | radialSegments: 16,
16 | heightSegments: 1,
17 | openEnded: false,
18 | thetaStart: 0,
19 | thetaLength: Math.PI * 2,
20 | });
21 | }
22 |
23 | get radiusTop() {
24 | return this[getAttribute]('radiusTop');
25 | }
26 |
27 | set radiusTop(value) {
28 | this[setAttribute]('radiusTop', value);
29 | }
30 |
31 | get radiusBottom() {
32 | return this[getAttribute]('radiusBottom');
33 | }
34 |
35 | set radiusBottom(value) {
36 | this[setAttribute]('radiusBottom', value);
37 | }
38 |
39 | get radius() {
40 | return [this.radiusTop, this.radiusBottom];
41 | }
42 |
43 | set radius(value) {
44 | if(!Array.isArray(value)) value = [value, value];
45 | this.radiusTop = value[0];
46 | this.radiusBottom = value[1];
47 | }
48 |
49 | get height() {
50 | return this[getAttribute]('height');
51 | }
52 |
53 | set height(value) {
54 | this[setAttribute]('height', value);
55 | }
56 |
57 | get radialSegments() {
58 | return this[getAttribute]('radialSegments');
59 | }
60 |
61 | set radialSegments(value) {
62 | this[setAttribute]('radialSegments', value);
63 | }
64 |
65 | get heightSegments() {
66 | return this[getAttribute]('heightSegments');
67 | }
68 |
69 | set heightSegments(value) {
70 | this[setAttribute]('heightSegments', value);
71 | }
72 |
73 | get openEnded() {
74 | return this[getAttribute]('openEnded');
75 | }
76 |
77 | set openEnded(value) {
78 | this[setAttribute]('openEnded', value);
79 | }
80 |
81 | get thetaStart() {
82 | return this[getAttribute]('thetaStart');
83 | }
84 |
85 | set thetaStart(value) {
86 | this[setAttribute]('thetaStart', value);
87 | }
88 |
89 | get thetaLength() {
90 | return this[getAttribute]('thetaLength');
91 | }
92 |
93 | set thetaLength(value) {
94 | this[setAttribute]('thetaLength', value);
95 | }
96 | }
--------------------------------------------------------------------------------
/src/attribute/mesh3d.js:
--------------------------------------------------------------------------------
1 | import {Color} from 'spritejs';
2 | import Node3dAttr from './node3d';
3 |
4 | const setAttribute = Symbol.for('spritejs_setAttribute');
5 | const getAttribute = Symbol.for('spritejs_getAttribute');
6 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
7 |
8 | export default class Mesh3dAttr extends Node3dAttr {
9 | constructor(subject) {
10 | super(subject);
11 | this[setDefault]({
12 | mode: 'TRIANGLES', // POINTS, LINES, LINE_LOOP, LINE_STRIP, TRIANGLES
13 | colors: [0.5, 0.5, 0.5, 1],
14 | colorDivisor: 3,
15 | raycast: 'box', // box sphere none
16 | });
17 | }
18 |
19 | get colors() {
20 | return this[getAttribute]('colors');
21 | }
22 |
23 | set colors(value) {
24 | if(typeof value === 'string') {
25 | value = value.replace(/\s*,\s*/g, ',');
26 | let colors = value.split(/\s+/g);
27 | colors = colors.map((c) => {
28 | return new Color(c);
29 | });
30 | value = colors.reduce((a, b) => [...a, ...b]);
31 | } else if(Array.isArray(value)) {
32 | if(typeof value[0] === 'string') {
33 | value = value.reduce((a, b) => {
34 | a.push(...(new Color(b)));
35 | return a;
36 | }, []);
37 | } else if(Array.isArray(value[0])) {
38 | value = value.reduce((a, b) => [...a, ...b]);
39 | }
40 | }
41 | this[setAttribute]('colors', value);
42 | }
43 |
44 | get colorDivisor() {
45 | return this[getAttribute]('colorDivisor');
46 | }
47 |
48 | set colorDivisor(value) {
49 | this[setAttribute]('colorDivisor', value);
50 | }
51 |
52 | get mode() {
53 | return this[getAttribute]('mode');
54 | }
55 |
56 | set mode(value) {
57 | if(typeof value === 'number' && value >= 0 && value < 7) {
58 | value = ['POINTS', 'LINES', 'LINE_LOOP', 'LINE_STRIP', 'TRIANGLES', 'TRIANGLE_STRIP', 'TRIANGLE_FAN'][value];
59 | }
60 | if(value && value !== 'TRIANGLES' && value !== 'POINTS' && value !== 'LINES' && value !== 'LINE_LOOP' && value !== 'LINE_STRIP'
61 | && value !== 'TRIANGLE_STRIP' && value !== 'TRIANGLE_FAN') {
62 | throw new TypeError('Invalid mode value.');
63 | }
64 | this[setAttribute]('mode', value);
65 | }
66 |
67 | get raycast() {
68 | return this[getAttribute]('raycast');
69 | }
70 |
71 | set raycast(value) {
72 | this[setAttribute]('raycast', value);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/attribute/plane.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class PlaneAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | width: 1,
12 | height: 1,
13 | widthSegments: 1,
14 | heightSegments: 1,
15 | });
16 | }
17 |
18 | get width() {
19 | return this[getAttribute]('width');
20 | }
21 |
22 | set width(value) {
23 | this[setAttribute]('width', value);
24 | }
25 |
26 | get height() {
27 | return this[getAttribute]('height');
28 | }
29 |
30 | set height(value) {
31 | this[setAttribute]('height', value);
32 | }
33 |
34 | get widthSegments() {
35 | return this[getAttribute]('widthSegments');
36 | }
37 |
38 | set widthSegments(value) {
39 | this[setAttribute]('widthSegments', value);
40 | }
41 |
42 | get heightSegments() {
43 | return this[getAttribute]('heightSegments');
44 | }
45 |
46 | set heightSegments(value) {
47 | this[setAttribute]('heightSegments', value);
48 | }
49 | }
--------------------------------------------------------------------------------
/src/attribute/polyline3d.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class PolylineAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | points: [],
12 | raycast: 'none',
13 | });
14 | }
15 |
16 | get points() {
17 | return this[getAttribute]('points');
18 | }
19 |
20 | set points(value) {
21 | if(Array.isArray(value)) {
22 | value = value.reduce((a, b) => {
23 | if(Array.isArray(b)) {
24 | return [...a, ...b];
25 | }
26 | return [...a, b];
27 | }, []);
28 | }
29 | // if(value) { // 要去掉重复的点
30 | // if(value.length % 3) throw new Error('Invalid points set');
31 | // const points = [value[0], value[1], value[2]];
32 | // for(let i = 3; i < value.length; i += 3) {
33 | // if(value[i] !== value[i - 3] || value[i + 1] !== value[i - 2] || value[i + 2] !== value[i - 1]) {
34 | // points.push(value[i], value[i + 1], value[i + 2]);
35 | // }
36 | // }
37 | // value = points;
38 | // }
39 | this[setAttribute]('points', value);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/attribute/sphere.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class SphereAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | radius: 0.5,
12 | widthSegments: 32,
13 | heightSegments: 16,
14 | phiStart: 0,
15 | phiLength: Math.PI * 2,
16 | thetaStart: 0,
17 | thetaLength: Math.PI,
18 | raycast: 'sphere',
19 | });
20 | }
21 |
22 | get radius() {
23 | return this[getAttribute]('radius');
24 | }
25 |
26 | set radius(value) {
27 | this[setAttribute]('radius', value);
28 | }
29 |
30 | get widthSegments() {
31 | return this[getAttribute]('widthSegments');
32 | }
33 |
34 | set widthSegments(value) {
35 | this[setAttribute]('widthSegments', value);
36 | }
37 |
38 | get heightSegments() {
39 | return this[getAttribute]('heightSegments');
40 | }
41 |
42 | set heightSegments(value) {
43 | this[setAttribute]('heightSegments', value);
44 | }
45 |
46 | get phiStart() {
47 | return this[getAttribute]('phiStart');
48 | }
49 |
50 | set phiStart(value) {
51 | this[setAttribute]('phiStart', value);
52 | }
53 |
54 | get phiLength() {
55 | return this[getAttribute]('phiLength');
56 | }
57 |
58 | set phiLength(value) {
59 | this[setAttribute]('phiLength', value);
60 | }
61 |
62 | get thetaStart() {
63 | return this[getAttribute]('thetaStart');
64 | }
65 |
66 | set thetaStart(value) {
67 | this[setAttribute]('thetaStart', value);
68 | }
69 |
70 | get thetaLength() {
71 | return this[getAttribute]('thetaLength');
72 | }
73 |
74 | set thetaLength(value) {
75 | this[setAttribute]('thetaLength', value);
76 | }
77 | }
--------------------------------------------------------------------------------
/src/attribute/torus.js:
--------------------------------------------------------------------------------
1 | import Mesh3dAttr from './mesh3d';
2 |
3 | const setAttribute = Symbol.for('spritejs_setAttribute');
4 | const getAttribute = Symbol.for('spritejs_getAttribute');
5 | const setDefault = Symbol.for('spritejs_setAttributeDefault');
6 |
7 | export default class TorusAttr extends Mesh3dAttr {
8 | constructor(subject) {
9 | super(subject);
10 | this[setDefault]({
11 | radius: 0.5,
12 | tube: 0.2,
13 | radialSegments: 8,
14 | tubularSegments: 6,
15 | arc: Math.PI * 2,
16 | });
17 | }
18 |
19 | get radius() {
20 | return this[getAttribute]('radius');
21 | }
22 |
23 | set radius(value) {
24 | this[setAttribute]('radius', value);
25 | }
26 |
27 | get tube() {
28 | return this[getAttribute]('tube');
29 | }
30 |
31 | set tube(value) {
32 | this[setAttribute]('tube', value);
33 | }
34 |
35 | get radialSegments() {
36 | return this[getAttribute]('radialSegments');
37 | }
38 |
39 | set radialSegments(value) {
40 | this[setAttribute]('radialSegments', value);
41 | }
42 |
43 | get tubularSegments() {
44 | return this[getAttribute]('tubularSegments');
45 | }
46 |
47 | set tubularSegments(value) {
48 | this[setAttribute]('tubularSegments', value);
49 | }
50 |
51 | get arc() {
52 | return this[getAttribute]('arc');
53 | }
54 |
55 | set arc(value) {
56 | this[setAttribute]('arc', value);
57 | }
58 | }
--------------------------------------------------------------------------------
/src/helper/color-attribute.js:
--------------------------------------------------------------------------------
1 | export function colorAttribute(node, geometry) {
2 | const updateColor = geometry.attributes.color;
3 |
4 | const positions = geometry.attributes.position.data;
5 | const size = geometry.attributes.position.size || 3;
6 | const len = positions.length / size;
7 |
8 | const color = updateColor ? updateColor.data : new Float32Array(4 * len);
9 | const colors = node.attributes.colors;
10 | const colorLen = colors.length / 4;
11 | const colorDivisor = node.attributes.colorDivisor;
12 |
13 | for(let i = 0; i < len; i++) {
14 | // const color = colors
15 | const idx = Math.floor(i / colorDivisor) % colorLen;
16 | color[4 * i] = colors[idx * 4];
17 | color[4 * i + 1] = colors[idx * 4 + 1];
18 | color[4 * i + 2] = colors[idx * 4 + 2];
19 | color[4 * i + 3] = colors[idx * 4 + 3];
20 | }
21 |
22 | if(updateColor) updateColor.needsUpdate = true;
23 |
24 | return {size: 4, data: color};
25 | }
--------------------------------------------------------------------------------
/src/helper/curve.js:
--------------------------------------------------------------------------------
1 | import {Curve as _Curve, Vec3} from 'ogl';
2 |
3 | export default class Curve extends _Curve {
4 | constructor({points, divisions, type} = {}) {
5 | if(Array.isArray(points) && points[0] && !(points[0] instanceof Vec3)) {
6 | points = points.map(p => new Vec3().copy(p));
7 | }
8 | super({points, divisions, type});
9 | }
10 | }
--------------------------------------------------------------------------------
/src/helper/light.js:
--------------------------------------------------------------------------------
1 | import {parseColor} from './parse-color';
2 |
3 | export default class Light {
4 | static DIRECTIONAL_LIGHT = 0;
5 |
6 | static POINT_LIGHT = 1;
7 |
8 | static SPOT_LIGHT = 2;
9 |
10 | constructor({angle, direction, position, blur = 0, color = [1, 1, 1, 1], decay = [0, 0, 1]} = {}) {
11 | this.angle = angle;
12 | this.blur = blur;
13 | this.color = color ? parseColor(color) : undefined;
14 | this.decay = decay;
15 | this.direction = direction;
16 | this.position = position;
17 | if(this.position && this.direction && this.angle == null) {
18 | this.angle = Math.PI / 3;
19 | }
20 | }
21 |
22 | get type() {
23 | if(this.position && this.direction) return Light.SPOT_LIGHT;
24 | if(this.position) return Light.POINT_LIGHT;
25 | if(this.direction) return Light.DIRECTIONAL_LIGHT;
26 | throw new Error('unknown light');
27 | }
28 | }
--------------------------------------------------------------------------------
/src/helper/parse-color.js:
--------------------------------------------------------------------------------
1 | import {Color} from 'spritejs';
2 |
3 | export function parseColor(colors) {
4 | if(Array.isArray(colors)) {
5 | return colors.map((c) => {
6 | if(typeof c === 'string') {
7 | return new Color(c);
8 | }
9 | return c;
10 | });
11 | }
12 | return typeof colors === 'string' ? new Color(colors) : colors;
13 | }
--------------------------------------------------------------------------------
/src/helper/shadow.js:
--------------------------------------------------------------------------------
1 | import {Shadow as _Shadow} from 'ogl';
2 |
3 | // https://github.com/oframe/ogl/blob/master/src/extras/Shadow.js
4 | export default class Shadow extends _Shadow {
5 | async add(node, opts = {}) {
6 | await node.model;
7 | opts.mesh = node.body;
8 | node.addEventListener('updatemesh', (evt) => {
9 | const oldMesh = evt.detail.oldMesh;
10 | this.castMeshes = this.castMeshes.filter(mesh => mesh !== oldMesh);
11 | this.add(node, opts);
12 | });
13 | super.add(opts);
14 | }
15 |
16 | remove(node) {
17 | const mesh = node.body;
18 | if(mesh) {
19 | const idx = this.castMeshes.indexOf(mesh);
20 | if(idx >= 0) {
21 | this.castMeshes.splice(idx, 1);
22 | return true;
23 | }
24 | }
25 | return false;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/helper/texture-loader.js:
--------------------------------------------------------------------------------
1 | import {TextureLoader as _TextureLoader} from 'ogl';
2 |
3 | export default class TextureLoader {
4 | static load(layer, opts) {
5 | const texture = _TextureLoader.load(layer.gl, opts);
6 | if(texture && texture.loaded && texture.loaded.then) {
7 | // load loadKTX
8 | texture.loaded.then(() => {
9 | layer.forceUpdate();
10 | });
11 | } else if(texture && texture.then) {
12 | // load Image
13 | texture.then(() => {
14 | layer.forceUpdate();
15 | });
16 | }
17 | return texture;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import {Raycast, GPGPU, Vec2, Vec3, Vec4, Mat3, Mat4, Quat, Euler, RenderTarget as FrameBuffer} from 'ogl';
2 | import Layer3d from './node/layer3d';
3 | import Mesh3d from './node/mesh3d';
4 | import Skin from './node/skin';
5 | import Sphere from './node/sphere';
6 | import Torus from './node/torus';
7 | import Camera from './node/camera';
8 | import Cube from './node/cube';
9 | import Curve from './helper/curve';
10 | import Plane from './node/plane';
11 | import Polyline3d from './node/polyline3d';
12 | import Cylinder from './node/cylinder';
13 | import Path3d from './node/path3d';
14 | import Group3d from './node/group3d';
15 | import RenderTarget from './node/render-target';
16 | import Shadow from './helper/shadow';
17 | import TextureLoader from './helper/texture-loader';
18 | import Geometry from './helper/geometry';
19 | import Light from './helper/light';
20 | import * as shaders from './shader';
21 |
22 | export {
23 | Layer3d,
24 | Sphere,
25 | Torus,
26 | Plane,
27 | Polyline3d,
28 | Camera,
29 | Cube,
30 | Cylinder,
31 | Path3d,
32 | Mesh3d,
33 | Skin,
34 | Group3d,
35 | RenderTarget,
36 | Shadow,
37 | Light,
38 | TextureLoader,
39 | Geometry,
40 | Curve,
41 | shaders,
42 | Vec2,
43 | Vec3,
44 | Vec4,
45 | Mat3,
46 | Mat4,
47 | Quat,
48 | Euler,
49 | GPGPU,
50 | Raycast,
51 | FrameBuffer,
52 | };
--------------------------------------------------------------------------------
/src/node/cube.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Box} from 'ogl';
3 | import Mesh3d from './mesh3d';
4 | import CubeAttr from '../attribute/cube';
5 |
6 | export default class Cube extends Mesh3d {
7 | static Attr = CubeAttr;
8 |
9 | /* override */
10 | onPropertyChange(key, newValue, oldValue) {
11 | super.onPropertyChange(key, newValue, oldValue);
12 | if(key === 'width'
13 | || key === 'height'
14 | || key === 'depth'
15 | || key === 'widthSegments'
16 | || key === 'heightSegments'
17 | || key === 'depthSegments') {
18 | if(newValue !== oldValue) {
19 | this.updateMesh();
20 | }
21 | }
22 | }
23 |
24 | /* override */
25 | remesh() {
26 | const gl = this.program.gl;
27 | const {width, height, depth, widthSegments, heightSegments, depthSegments} = this.attributes;
28 | const geometry = new Box(gl, {
29 | width,
30 | height,
31 | depth,
32 | widthSegments,
33 | heightSegments,
34 | depthSegments});
35 | this.setGeometry(geometry);
36 | }
37 | }
38 |
39 | registerNode(Cube, 'cube');
--------------------------------------------------------------------------------
/src/node/cylinder.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Cylinder as _Cylinder} from 'ogl';
3 | import CylinderAttr from '../attribute/cylinder';
4 | import Mesh3d from './mesh3d';
5 |
6 | export default class Cylinder extends Mesh3d {
7 | static Attr = CylinderAttr;
8 |
9 | /* override */
10 | onPropertyChange(key, newValue, oldValue) {
11 | super.onPropertyChange(key, newValue, oldValue);
12 | if(key === 'radiusTop'
13 | || key === 'radiusBottom'
14 | || key === 'height'
15 | || key === 'radialSegments'
16 | || key === 'heightSegments'
17 | || key === 'openEnded'
18 | || key === 'thetaStart'
19 | || key === 'thetaLength') {
20 | if(newValue !== oldValue) {
21 | this.updateMesh();
22 | }
23 | }
24 | }
25 |
26 | /* override */
27 | remesh() {
28 | const gl = this.program.gl;
29 | const {radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength} = this.attributes;
30 |
31 | const geometry = new _Cylinder(gl, {
32 | radiusTop,
33 | radiusBottom,
34 | height,
35 | radialSegments,
36 | heightSegments,
37 | openEnded,
38 | thetaStart,
39 | thetaLength});
40 | this.setGeometry(geometry);
41 | }
42 | }
43 |
44 | registerNode(Cylinder, 'cylinder');
--------------------------------------------------------------------------------
/src/node/plane.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Plane as _Plane} from 'ogl';
3 | import PlaneAttr from '../attribute/plane';
4 | import Mesh3d from './mesh3d';
5 |
6 | export default class Plane extends Mesh3d {
7 | static Attr = PlaneAttr;
8 |
9 | /* override */
10 | onPropertyChange(key, newValue, oldValue) {
11 | super.onPropertyChange(key, newValue, oldValue);
12 | if(key === 'width'
13 | || key === 'height'
14 | || key === 'widthSegments'
15 | || key === 'heightSegments') {
16 | if(newValue !== oldValue) {
17 | this.updateMesh();
18 | }
19 | }
20 | }
21 |
22 | /* override */
23 | remesh() {
24 | const gl = this.program.gl;
25 | const {width, height, widthSegments, heightSegments} = this.attributes;
26 |
27 | const geometry = new _Plane(gl, {
28 | width,
29 | height,
30 | widthSegments,
31 | heightSegments});
32 | this.setGeometry(geometry);
33 | }
34 | }
35 |
36 | registerNode(Plane, 'plane');
--------------------------------------------------------------------------------
/src/node/render-target.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {RenderTarget as _RenderTarget} from 'ogl';
3 | import Group3d from './group3d';
4 | import Camera from './camera';
5 |
6 | const _target = Symbol('target');
7 | const _buffer = Symbol('buffer');
8 |
9 | export default class RenderTarget extends Group3d {
10 | constructor(gl, {
11 | width = gl.canvas.width,
12 | height = gl.canvas.height,
13 | target = gl.FRAMEBUFFER,
14 | color = 1, // number of color attachments
15 | depth = true,
16 | stencil = false,
17 | depthTexture = false, // note - stencil breaks
18 | wrapS = gl.CLAMP_TO_EDGE,
19 | wrapT = gl.CLAMP_TO_EDGE,
20 | minFilter = gl.LINEAR,
21 | magFilter = minFilter,
22 | type = gl.UNSIGNED_BYTE,
23 | format = gl.RGBA,
24 | internalFormat = format,
25 | unpackAlignment,
26 | premultiplyAlpha,
27 | camera: cameraOptions,
28 | buffer = false,
29 | ...attrs} = {}) {
30 | super(attrs);
31 |
32 | const options = {width,
33 | height,
34 | target,
35 | color,
36 | depth,
37 | stencil,
38 | depthTexture,
39 | wrapS,
40 | wrapT,
41 | minFilter,
42 | magFilter,
43 | type,
44 | format,
45 | internalFormat,
46 | unpackAlignment,
47 | premultiplyAlpha};
48 |
49 | this.options = options;
50 | this[_target] = new _RenderTarget(gl, options);
51 |
52 | if(buffer) {
53 | this[_buffer] = new _RenderTarget(gl, this.options);
54 | }
55 |
56 | if(cameraOptions) {
57 | const camera = new Camera(gl, cameraOptions);
58 | camera.connect(this, 0);
59 | this.camera = camera;
60 | }
61 | }
62 |
63 | get texture() {
64 | return this[_buffer] ? this[_buffer].texture : this[_target].texture;
65 | }
66 |
67 | renderBy(layer, {root = this, ...options} = {}) {
68 | const camera = this.camera ? this.camera.body : null;
69 | const target = this[_target];
70 |
71 | this.dispatchEvent({type: 'beforerender', detail: {scene: root, camera, renderer: layer}});
72 |
73 | layer.renderer.render({scene: root.body, camera, target, ...options});
74 | this.dispatchEvent({type: 'afterrender', detail: {scene: root, camera, renderer: layer}});
75 | return this[_target].texture;
76 | }
77 |
78 | swap() {
79 | if(this[_buffer] == null) {
80 | throw new Error('No buffer to swap. You must set buffer option to true when creating the renderTarget object.');
81 | }
82 | [this[_target], this[_buffer]] = [this[_buffer], this[_target]];
83 | }
84 | }
85 |
86 | registerNode(RenderTarget, 'rendertarget');
--------------------------------------------------------------------------------
/src/node/skin.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Skin as _Skin} from 'ogl';
3 | import Mesh3d from './mesh3d';
4 |
5 | const _rig = Symbol('rig');
6 | const _animations = [];
7 |
8 | function initAnimation(body, animationFrames) {
9 | const animation = body.addAnimation(animationFrames.data);
10 | const node = body._node;
11 | const elapsed = animationFrames.elapsed || 0;
12 | if(elapsed) {
13 | animation.elapsed = elapsed;
14 | body.update();
15 | node.forceUpdate();
16 | }
17 | Object.defineProperties(animationFrames, {
18 | animation: {
19 | get() {
20 | return animation;
21 | },
22 | enumerable: true,
23 | },
24 | elapsed: {
25 | get() {
26 | return animation.elapsed;
27 | },
28 | set(value) {
29 | animation.elapsed = value;
30 | body.update();
31 | node.forceUpdate();
32 | },
33 | enumerable: true,
34 | },
35 | });
36 | return animationFrames;
37 | }
38 |
39 | export default class Skin extends Mesh3d {
40 | constructor(program, {model, ...attrs} = {}) {
41 | super(program, {model, ...attrs});
42 | this[_animations] = [];
43 | }
44 |
45 | get bones() {
46 | if(this[_rig]) {
47 | return this[_rig].bones;
48 | }
49 | return null;
50 | }
51 |
52 | /* override */
53 | _createMesh({geometry, program}) {
54 | const rig = this[_rig];
55 | return new _Skin(program.gl, {rig, geometry, program});
56 | }
57 |
58 | addAnimation(animationData) {
59 | const animationFrames = {data: animationData};
60 |
61 | const body = this.body;
62 | if(body.addAnimation) {
63 | initAnimation(body, animationFrames);
64 | }
65 |
66 | this[_animations].push(animationFrames);
67 | return animationFrames;
68 | }
69 |
70 | /* override */
71 | setGeometry(model = this.model) {
72 | const rig = model.rig;
73 | this[_rig] = rig;
74 | delete model.rig;
75 | super.setGeometry(model);
76 | model.rig = rig;
77 | if(model !== this.geometry) {
78 | this.geometry.rig = rig;
79 | }
80 | this[_animations].forEach((frames) => {
81 | if(!frames.animation) {
82 | initAnimation(this.body, frames);
83 | }
84 | });
85 | }
86 | }
87 |
88 | registerNode(Skin, 'skin');
--------------------------------------------------------------------------------
/src/node/sphere.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Sphere as _Sphere} from 'ogl';
3 | import SphereAttr from '../attribute/sphere';
4 | import Mesh3d from './mesh3d';
5 |
6 | export default class Sphere extends Mesh3d {
7 | static Attr = SphereAttr;
8 |
9 | /* override */
10 | onPropertyChange(key, newValue, oldValue) {
11 | super.onPropertyChange(key, newValue, oldValue);
12 | if(key === 'radius'
13 | || key === 'widthSegments'
14 | || key === 'heightSegments'
15 | || key === 'phiStart'
16 | || key === 'phiLength'
17 | || key === 'thetaStart'
18 | || key === 'thetaLength') {
19 | if(newValue !== oldValue) {
20 | this.updateMesh();
21 | }
22 | }
23 | }
24 |
25 | /* override */
26 | remesh() {
27 | const gl = this.program.gl;
28 | const {radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength} = this.attributes;
29 |
30 | const geometry = new _Sphere(gl, {
31 | radius,
32 | widthSegments,
33 | heightSegments,
34 | phiStart,
35 | phiLength,
36 | thetaStart,
37 | thetaLength});
38 |
39 | this.setGeometry(geometry);
40 | }
41 | }
42 |
43 | registerNode(Sphere, 'sphere');
--------------------------------------------------------------------------------
/src/node/torus.js:
--------------------------------------------------------------------------------
1 | import {registerNode} from 'spritejs';
2 | import {Torus as _Torus} from 'ogl';
3 | import TorusAttr from '../attribute/torus';
4 | import Mesh3d from './mesh3d';
5 |
6 | export default class Torus extends Mesh3d {
7 | static Attr = TorusAttr;
8 |
9 | /* override */
10 | onPropertyChange(key, newValue, oldValue) {
11 | super.onPropertyChange(key, newValue, oldValue);
12 | if(key === 'radius'
13 | || key === 'tube'
14 | || key === 'radialSegments'
15 | || key === 'tubularSegments'
16 | || key === 'arc') {
17 | if(newValue !== oldValue) {
18 | this.updateMesh();
19 | }
20 | }
21 | }
22 |
23 | /* override */
24 | remesh() {
25 | const gl = this.program.gl;
26 | const {radius, tube, radialSegments, tubularSegments, arc} = this.attributes;
27 |
28 | const geometry = new _Torus(gl, {
29 | radius,
30 | tube,
31 | radialSegments,
32 | tubularSegments,
33 | arc});
34 |
35 | this.setGeometry(geometry);
36 | }
37 | }
38 |
39 | registerNode(Torus, 'torus');
--------------------------------------------------------------------------------
/src/shader/base_geometry.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | varying vec4 vColor;
5 |
6 | void main() {
7 | gl_FragColor = vColor;
8 | }
--------------------------------------------------------------------------------
/src/shader/base_geometry.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec4 color;
6 |
7 | uniform mat4 modelViewMatrix;
8 | uniform mat4 projectionMatrix;
9 |
10 | varying vec4 vColor;
11 |
12 | void main() {
13 | vColor = color;
14 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);;
15 | }
--------------------------------------------------------------------------------
/src/shader/dashline.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform float uTotalLength;
4 | uniform float uDashLength;
5 | uniform float uDashOffset;
6 |
7 | varying vec4 vColor;
8 | varying vec2 vUv;
9 | varying float fSeg;
10 |
11 | void main() {
12 | float f = fract((uDashOffset + fSeg) / (2.0 * uDashLength));
13 | f = 1.0 - step(0.5, f);
14 | gl_FragColor = vColor * f;
15 | }
--------------------------------------------------------------------------------
/src/shader/dashline.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | attribute vec3 position;
3 | attribute vec3 next;
4 | attribute vec3 prev;
5 | attribute vec2 uv;
6 | attribute float side;
7 | attribute vec4 color;
8 | attribute float seg;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform vec2 uResolution;
13 | uniform float uDPR;
14 | uniform float uThickness;
15 | uniform float uMiter;
16 |
17 | varying vec2 vUv;
18 | varying vec4 vColor;
19 | varying float fSeg;
20 |
21 | vec4 getPosition() {
22 | mat4 mvp = projectionMatrix * modelViewMatrix;
23 | vec4 current = mvp * vec4(position, 1);
24 | vec4 nextPos = mvp * vec4(next, 1);
25 | vec4 prevPos = mvp * vec4(prev, 1);
26 | vec2 aspect = vec2(uResolution.x / uResolution.y, 1);
27 | vec2 currentScreen = current.xy / current.w * aspect;
28 | vec2 nextScreen = nextPos.xy / nextPos.w * aspect;
29 | vec2 prevScreen = prevPos.xy / prevPos.w * aspect;
30 |
31 | vec2 dir1 = normalize(currentScreen - prevScreen);
32 | vec2 dir2 = normalize(nextScreen - currentScreen);
33 | vec2 dir = normalize(dir1 + dir2);
34 |
35 | vec2 normal = vec2(-dir.y, dir.x);
36 | normal /= mix(1.0, max(0.3, dot(normal, vec2(-dir1.y, dir1.x))), uMiter);
37 | normal /= aspect;
38 | float pixelWidthRatio = 1.0 / (uResolution.y / uDPR);
39 | float pixelWidth = current.w * pixelWidthRatio;
40 | normal *= pixelWidth * uThickness;
41 | current.xy -= normal * side;
42 | return current;
43 | }
44 |
45 | void main() {
46 | vUv = uv;
47 | gl_Position = getPosition();
48 | vColor = color;
49 | fSeg = seg;
50 | }
--------------------------------------------------------------------------------
/src/shader/geometry.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 | attribute vec4 color;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 viewMatrix;
10 | uniform mat4 projectionMatrix;
11 | uniform mat3 normalMatrix;
12 | uniform vec3 cameraPosition;
13 |
14 | varying vec3 vNormal;
15 | varying vec4 vColor;
16 | varying vec4 vPos;
17 | varying vec3 vCameraPos;
18 |
19 | void main() {
20 | vNormal = normalize(normalMatrix * normal);
21 | vPos = modelViewMatrix * vec4(position, 1.0);;
22 | vColor = color;
23 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
24 | gl_Position = projectionMatrix * vPos;
25 | }
--------------------------------------------------------------------------------
/src/shader/geometry_normal_map_100.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec2 uv;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelMatrix;
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 viewMatrix;
13 | uniform mat4 projectionMatrix;
14 | uniform vec3 cameraPosition;
15 |
16 | varying vec2 vUv;
17 | varying vec3 vNormal;
18 | varying vec4 vColor;
19 | varying vec4 vPos;
20 | varying vec3 vCameraPos;
21 |
22 | void main() {
23 | vUv = uv;
24 | vNormal = normalize(normalMatrix * normal);
25 | vColor = color;
26 | vPos = modelViewMatrix * vec4(position, 1.0);
27 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
28 |
29 | gl_Position = projectionMatrix * vPos;
30 | }
--------------------------------------------------------------------------------
/src/shader/geometry_normal_map_300.vert:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 | precision highp int;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 | in vec3 normal;
8 | in vec4 color;
9 |
10 | uniform mat3 normalMatrix;
11 | uniform mat4 modelMatrix;
12 | uniform mat4 modelViewMatrix;
13 | uniform mat4 viewMatrix;
14 | uniform mat4 projectionMatrix;
15 | uniform vec3 cameraPosition;
16 |
17 | out vec2 vUv;
18 | out vec3 vNormal;
19 | out vec4 vColor;
20 | out vec4 vPos;
21 | out vec3 vCameraPos;
22 |
23 | void main() {
24 | vUv = uv;
25 | vNormal = normalize(normalMatrix * normal);
26 | vColor = color;
27 | vPos = modelViewMatrix * vec4(position, 1.0);
28 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
29 |
30 | gl_Position = projectionMatrix * vPos;
31 | }
--------------------------------------------------------------------------------
/src/shader/geometry_with_shadow.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 | attribute vec4 color;
7 |
8 | uniform mat4 modelMatrix;
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 viewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 |
14 | uniform mat4 shadowViewMatrix;
15 | uniform mat4 shadowProjectionMatrix;
16 | uniform vec3 cameraPosition;
17 |
18 | varying vec3 vNormal;
19 | varying vec4 vColor;
20 | varying vec4 vLightNDC;
21 | varying vec4 vPos;
22 | varying vec3 vCameraPos;
23 |
24 | // Matrix to shift range from -1->1 to 0->1
25 | const mat4 depthScaleMatrix = mat4(
26 | 0.5, 0, 0, 0,
27 | 0, 0.5, 0, 0,
28 | 0, 0, 0.5, 0,
29 | 0.5, 0.5, 0.5, 1
30 | );
31 |
32 | void main() {
33 | vNormal = normalize(normalMatrix * normal);
34 | vPos = modelViewMatrix * vec4(position, 1.0);
35 | vColor = color;
36 | vLightNDC = depthScaleMatrix * shadowProjectionMatrix * shadowViewMatrix * modelMatrix * vec4(position, 1.0);
37 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
38 | gl_Position = projectionMatrix * vPos;
39 | }
--------------------------------------------------------------------------------
/src/shader/normal.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | varying vec3 vNormal;
5 |
6 | void main() {
7 | gl_FragColor.rgb = normalize(vNormal);
8 | gl_FragColor.a = 1.0;
9 | }
--------------------------------------------------------------------------------
/src/shader/normal.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 |
7 | uniform mat3 normalMatrix;
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 |
11 | varying vec3 vNormal;
12 |
13 | void main() {
14 | vNormal = normalize(normalMatrix * normal);
15 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/shader/polyline.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | varying vec4 vColor;
4 |
5 | void main() {
6 | gl_FragColor = vColor;
7 | }
--------------------------------------------------------------------------------
/src/shader/polyline.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | attribute vec3 position;
3 | attribute vec3 next;
4 | attribute vec3 prev;
5 | attribute float side;
6 | attribute vec4 color;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform vec2 uResolution;
11 | uniform float uDPR;
12 | uniform float uThickness;
13 | uniform float uMiter;
14 |
15 | varying vec4 vColor;
16 |
17 | vec4 getPosition() {
18 | mat4 mvp = projectionMatrix * modelViewMatrix;
19 | vec4 current = mvp * vec4(position, 1);
20 | vec4 nextPos = mvp * vec4(next, 1);
21 | vec4 prevPos = mvp * vec4(prev, 1);
22 | vec2 aspect = vec2(uResolution.x / uResolution.y, 1);
23 | vec2 currentScreen = current.xy / current.w * aspect;
24 | vec2 nextScreen = nextPos.xy / nextPos.w * aspect;
25 | vec2 prevScreen = prevPos.xy / prevPos.w * aspect;
26 |
27 | vec2 dir1 = normalize(currentScreen - prevScreen);
28 | vec2 dir2 = normalize(nextScreen - currentScreen);
29 | vec2 dir = normalize(dir1 + dir2);
30 |
31 | vec2 normal = vec2(-dir.y, dir.x);
32 | normal /= mix(1.0, max(0.3, dot(normal, vec2(-dir1.y, dir1.x))), uMiter);
33 | normal /= aspect;
34 | float pixelWidthRatio = 1.0 / (uResolution.y / uDPR);
35 | float pixelWidth = current.w * pixelWidthRatio;
36 | normal *= pixelWidth * uThickness;
37 | current.xy -= normal * side;
38 | return current;
39 | }
40 |
41 | void main() {
42 | gl_Position = getPosition();
43 | vColor = color;
44 | }
--------------------------------------------------------------------------------
/src/shader/texture.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 | attribute vec4 color;
7 | attribute vec2 uv;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 viewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 | uniform vec3 cameraPosition;
14 |
15 | varying vec3 vNormal;
16 | varying vec4 vColor;
17 | varying vec2 vUv;
18 | varying vec4 vPos;
19 | varying vec3 vCameraPos;
20 |
21 | void main() {
22 | vNormal = normalize(normalMatrix * normal);
23 | vPos = modelViewMatrix * vec4(position, 1.0);
24 | vColor = color;
25 | vUv = uv;
26 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
27 | gl_Position = projectionMatrix * vPos;
28 | }
--------------------------------------------------------------------------------
/src/shader/texture_cube.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 | attribute vec4 color;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 viewMatrix;
10 | uniform mat4 projectionMatrix;
11 | uniform mat3 normalMatrix;
12 | uniform vec3 cameraPosition;
13 |
14 | varying vec3 vNormal;
15 | varying vec3 vDir;
16 | varying vec4 vColor;
17 | varying vec4 vPos;
18 | varying vec3 vCameraPos;
19 |
20 | void main() {
21 | vNormal = normalize(normalMatrix * normal);
22 | vPos = modelViewMatrix * vec4(position, 1.0);
23 | vDir = normalize(position);
24 | vColor = color;
25 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
26 | gl_Position = projectionMatrix * vPos;
27 | }
--------------------------------------------------------------------------------
/src/shader/texture_normal_map_100.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec2 uv;
6 | attribute vec3 normal;
7 | attribute vec4 color;
8 |
9 | uniform mat3 normalMatrix;
10 | uniform mat4 modelMatrix;
11 | uniform mat4 modelViewMatrix;
12 | uniform mat4 viewMatrix;
13 | uniform mat4 projectionMatrix;
14 | uniform vec3 cameraPosition;
15 |
16 | varying vec2 vUv;
17 | varying vec3 vNormal;
18 | varying vec4 vColor;
19 | varying vec4 vPos;
20 | varying vec3 vCameraPos;
21 |
22 | void main() {
23 | vUv = uv;
24 | vNormal = normalize(normalMatrix * normal);
25 | vColor = color;
26 | vPos = modelViewMatrix * vec4(position, 1.0);
27 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
28 |
29 | gl_Position = projectionMatrix * vPos;
30 | }
--------------------------------------------------------------------------------
/src/shader/texture_normal_map_300.vert:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 | precision highp int;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 | in vec3 normal;
8 | in vec4 color;
9 |
10 | uniform mat3 normalMatrix;
11 | uniform mat4 modelMatrix;
12 | uniform mat4 modelViewMatrix;
13 | uniform mat4 viewMatrix;
14 | uniform mat4 projectionMatrix;
15 | uniform vec3 cameraPosition;
16 |
17 | out vec2 vUv;
18 | out vec3 vNormal;
19 | out vec4 vColor;
20 | out vec4 vPos;
21 | out vec3 vCameraPos;
22 |
23 | void main() {
24 | vUv = uv;
25 | vNormal = normalize(normalMatrix * normal);
26 | vColor = color;
27 | vPos = modelViewMatrix * vec4(position, 1.0);
28 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
29 |
30 | gl_Position = projectionMatrix * vPos;
31 | }
--------------------------------------------------------------------------------
/src/shader/texture_with_shadow.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 | precision highp int;
3 |
4 | attribute vec3 position;
5 | attribute vec3 normal;
6 | attribute vec4 color;
7 | attribute vec2 uv;
8 |
9 | uniform mat4 modelMatrix;
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 viewMatrix;
12 | uniform mat4 projectionMatrix;
13 | uniform mat3 normalMatrix;
14 | uniform vec3 cameraPosition;
15 |
16 | varying vec3 vNormal;
17 | varying vec2 vUv;
18 | varying vec4 vColor;
19 | varying vec4 vLightNDC;
20 | varying vec4 vPos;
21 | varying vec3 vCameraPos;
22 |
23 | uniform mat4 shadowViewMatrix;
24 | uniform mat4 shadowProjectionMatrix;
25 |
26 | // Matrix to shift range from -1->1 to 0->1
27 | const mat4 depthScaleMatrix = mat4(
28 | 0.5, 0, 0, 0,
29 | 0, 0.5, 0, 0,
30 | 0, 0, 0.5, 0,
31 | 0.5, 0.5, 0.5, 1
32 | );
33 |
34 | void main() {
35 | vNormal = normalize(normalMatrix * normal);
36 | vPos = modelViewMatrix * vec4(position, 1.0);
37 | vColor = color;
38 | vUv = uv;
39 | vLightNDC = depthScaleMatrix * shadowProjectionMatrix * shadowViewMatrix * modelMatrix * vec4(position, 1.0);
40 | vCameraPos = (viewMatrix * vec4(cameraPosition, 1.0)).xyz;
41 | gl_Position = projectionMatrix * vPos;
42 | }
--------------------------------------------------------------------------------
/tools/data.obj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spritejs/sprite-extend-3d/1918e184c6a0effcad497e693772274b51e76231/tools/data.obj
--------------------------------------------------------------------------------
/tools/obj-converter.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const OBJ = require('webgl-obj-loader');
3 |
4 | const meshPath = './data.obj';
5 | const opt = {encoding: 'utf8'};
6 |
7 | fs.readFile(meshPath, opt, (err, data) => {
8 | if(err) return console.error(err);
9 | const mesh = new OBJ.Mesh(data);
10 | // console.log(JSON.stringify(mesh));
11 | // console.log(Object.keys(mesh));
12 | const geometry = {
13 | position: mesh.vertices,
14 | index: mesh.indices,
15 | normal: mesh.vertexNormals,
16 | uv: mesh.textures,
17 | };
18 | let min = Infinity;
19 | let max = -Infinity;
20 | for(let i = 0; i < geometry.position.length; i++) {
21 | const n = geometry.position[i];
22 | if(n < min) min = n;
23 | if(n > max) max = n;
24 | }
25 | const bound = Math.max(Math.abs(min), Math.abs(max)) / 3.0;
26 | for(let i = 0; i < geometry.position.length; i++) {
27 | geometry.position[i] /= bound;
28 | }
29 | fs.writeFileSync('./girl.json', JSON.stringify(geometry));
30 | });
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const EsmWebpackPlugin = require('@purtuga/esm-webpack-plugin');
2 | const webpack = require('webpack');
3 | const path = require('path');
4 | const fs = require('fs');
5 | const packageConfig = require('./package.json');
6 |
7 | module.exports = function (env = {}) {
8 | let filename = env.module ? `${packageConfig.name}.esm` : `${packageConfig.name}`;
9 | if(env.mode === 'production') filename = `${filename}.min`;
10 | const output = {
11 | path: path.resolve(__dirname, env.outputPath || 'dist'),
12 | filename: `${filename}.js`,
13 | publicPath: '/js/',
14 | library: env.module ? 'ext3d' : {
15 | commonjs: 'sprite-extend-3d',
16 | amd: 'sprite-extend-3d',
17 | root: ['spritejs', 'ext3d'],
18 | },
19 | libraryTarget: env.module ? 'var' : 'umd',
20 | globalObject: 'this',
21 | };
22 |
23 | let babelConf;
24 |
25 | const babelRC = './.babelrc';
26 | if(fs.existsSync(babelRC)) {
27 | babelConf = JSON.parse(fs.readFileSync(babelRC));
28 | babelConf.babelrc = false;
29 | }
30 |
31 | const plugins = [];
32 |
33 | if(env.mode === 'development') {
34 | plugins.push(new webpack.HotModuleReplacementPlugin({
35 | multiStep: true,
36 | }));
37 | }
38 |
39 | if(env.module) {
40 | plugins.push(new EsmWebpackPlugin());
41 | plugins.push(new webpack.BannerPlugin({
42 | banner: "import * as spritejs from 'https://unpkg.com/spritejs/dist/spritejs.esm.js';",
43 | raw: true,
44 | }));
45 | }
46 |
47 | return {
48 | mode: env.mode || 'none',
49 | entry: './src/index',
50 | output,
51 | // resolve: {
52 | //
53 | // },
54 |
55 | module: {
56 | rules: [
57 | {
58 | test: /\.js$/,
59 | exclude: /node_modules\/(?!ogl).*/,
60 | use: {
61 | loader: 'babel-loader',
62 | options: babelConf,
63 | },
64 | },
65 | {
66 | test: /\.(frag|vert|glsl)$/,
67 | use: {
68 | loader: 'raw-loader',
69 | options: {},
70 | },
71 | },
72 | ],
73 |
74 | /* Advanced module configuration (click to show) */
75 | },
76 |
77 | externals: {
78 | spritejs: 'spritejs',
79 | },
80 | // Don't follow/bundle these modules, but request them at runtime from the environment
81 |
82 | stats: 'errors-only',
83 | // lets you precisely control what bundle information gets displayed
84 |
85 | devServer: {
86 | contentBase: path.join(__dirname, env.server || '.'),
87 | compress: true,
88 | port: 3000,
89 | hot: true,
90 | // ...
91 | },
92 |
93 | plugins,
94 | // list of additional plugins
95 |
96 | /* Advanced configuration (click to show) */
97 | };
98 | };
99 |
--------------------------------------------------------------------------------