@damienmortini/three 0.1.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/copyExamples.js +15 -0
- package/ecs/THREEView.js +31 -0
- package/examples/loaders/BasisTextureLoader.js +783 -0
- package/examples/loaders/DRACOLoader.js +587 -0
- package/examples/loaders/GLTFLoader.js +4237 -0
- package/examples/objects/Lensflare.js +389 -0
- package/examples/utils/BufferGeometryUtils.js +943 -0
- package/gpgpu/THREEGPGPUSystem.js +175 -0
- package/loader/THREELoader.js +112 -0
- package/loader/meshoptimizerdecoder/THREE.EXT_meshopt_compression.js +41 -0
- package/loader/meshoptimizerdecoder/meshopt_decoder.js +129 -0
- package/material/THREEBaseMaterial.js +68 -0
- package/material/THREEPBRMaterial.js +107 -0
- package/material/THREEShaderMaterial.js +95 -0
- package/object/THREELine.js +113 -0
- package/object/THREEMotionVectorObject.js +284 -0
- package/object/THREERibbon.js +49 -0
- package/object/THREESky.js +279 -0
- package/object/THREESprite.js +96 -0
- package/object/THREESpriteAnimation.js +103 -0
- package/object/THREEText.js +240 -0
- package/package.json +33 -0
- package/renderer/THREERenderer.js +121 -0
- package/renderer/THREEStereoRenderer.js +60 -0
- package/renderer/THREEWebGLRenderTarget2D.js +63 -0
- package/shader/THREEBaseShader.js +33 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Mesh, OrthographicCamera, PlaneBufferGeometry, DataTexture, RGBAFormat, FloatType, WebGLRenderer, WebGLRenderTarget, Scene, NearestFilter, RGBFormat, HalfFloatType, MathUtils } from '../../../three/src/Three.js'
|
|
2
|
+
|
|
3
|
+
import THREEShaderMaterial from '../material/THREEShaderMaterial.js'
|
|
4
|
+
import DatatextureShader from '../../core/shader/DataTextureShader.js'
|
|
5
|
+
import Float16 from '../../core/math/Float16.js'
|
|
6
|
+
|
|
7
|
+
let DEBUG_RENDERER
|
|
8
|
+
|
|
9
|
+
export default class THREEGPGPUSystem {
|
|
10
|
+
constructor({
|
|
11
|
+
data,
|
|
12
|
+
renderer,
|
|
13
|
+
uniforms = {},
|
|
14
|
+
stride = 1,
|
|
15
|
+
fragmentChunks = [],
|
|
16
|
+
format = RGBAFormat,
|
|
17
|
+
debug = false,
|
|
18
|
+
}) {
|
|
19
|
+
this._renderer = renderer
|
|
20
|
+
this._stride = stride
|
|
21
|
+
|
|
22
|
+
const channels = format === RGBFormat ? 3 : 4
|
|
23
|
+
const dataSize = data.length / channels / stride
|
|
24
|
+
const width = MathUtils.ceilPowerOfTwo(Math.sqrt(dataSize))
|
|
25
|
+
this._dataTextureWidth = width * stride
|
|
26
|
+
this._dataTextureHeight = MathUtils.ceilPowerOfTwo(dataSize / width)
|
|
27
|
+
|
|
28
|
+
this.debug = debug
|
|
29
|
+
|
|
30
|
+
const finalData = new Float32Array(this._dataTextureWidth * this._dataTextureHeight * channels)
|
|
31
|
+
finalData.set(data)
|
|
32
|
+
let dataTexture
|
|
33
|
+
// if (renderer.capabilities.isWebGL2) {
|
|
34
|
+
dataTexture = new DataTexture(finalData, this._dataTextureWidth, this._dataTextureHeight, format, FloatType)
|
|
35
|
+
// } else {
|
|
36
|
+
// dataTexture = new DataTexture(Float16.fromFloat32Array(finalData), this._dataTextureWidth, this._dataTextureHeight, format, HalfFloatType);
|
|
37
|
+
// }
|
|
38
|
+
dataTexture.needsUpdate = true
|
|
39
|
+
|
|
40
|
+
this.camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1)
|
|
41
|
+
this.scene = new Scene()
|
|
42
|
+
|
|
43
|
+
this._webglRenderTargetIn = new WebGLRenderTarget(this._dataTextureWidth, this._dataTextureHeight, {
|
|
44
|
+
minFilter: NearestFilter,
|
|
45
|
+
magFilter: NearestFilter,
|
|
46
|
+
format,
|
|
47
|
+
stencilBuffer: false,
|
|
48
|
+
depthBuffer: false,
|
|
49
|
+
type: renderer.capabilities.isWebGL2 ? FloatType : HalfFloatType, // Half float for iOS
|
|
50
|
+
})
|
|
51
|
+
this._webglRenderTargetIn.texture.generateMipmaps = false
|
|
52
|
+
this._webglRenderTargetOut = this._webglRenderTargetIn.clone()
|
|
53
|
+
|
|
54
|
+
this._quad = new Mesh(new PlaneBufferGeometry(2, 2), new THREEShaderMaterial({
|
|
55
|
+
uniforms: {
|
|
56
|
+
dataTexture,
|
|
57
|
+
...uniforms,
|
|
58
|
+
},
|
|
59
|
+
fragment: `
|
|
60
|
+
void main() {
|
|
61
|
+
gl_FragColor = vec4(0.);
|
|
62
|
+
}
|
|
63
|
+
`,
|
|
64
|
+
vertexChunks: [
|
|
65
|
+
['start',
|
|
66
|
+
'out vec2 vUV;',
|
|
67
|
+
],
|
|
68
|
+
['main',
|
|
69
|
+
'vUV = uv;',
|
|
70
|
+
],
|
|
71
|
+
],
|
|
72
|
+
fragmentChunks: [
|
|
73
|
+
...fragmentChunks,
|
|
74
|
+
['start', `
|
|
75
|
+
#define DATA_TEXTURE_WIDTH ${this.dataTextureWidth.toFixed(1)}
|
|
76
|
+
#define DATA_TEXTURE_HEIGHT ${this.dataTextureHeight.toFixed(1)}
|
|
77
|
+
|
|
78
|
+
uniform highp sampler2D dataTexture;
|
|
79
|
+
|
|
80
|
+
in vec2 vUV;
|
|
81
|
+
|
|
82
|
+
${DatatextureShader.getTextureDataChunkFromUV()}
|
|
83
|
+
|
|
84
|
+
vec4 getDataChunk(int chunkIndex) {
|
|
85
|
+
return getTextureDataChunkFromUV(dataTexture, vUV, chunkIndex, ${stride}, vec2(DATA_TEXTURE_WIDTH, DATA_TEXTURE_HEIGHT));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
int getDataIndex() {
|
|
89
|
+
vec2 dataPosition = floor(vUV * vec2(DATA_TEXTURE_WIDTH / float(${stride}), DATA_TEXTURE_HEIGHT));
|
|
90
|
+
return int(dataPosition.x + dataPosition.y * DATA_TEXTURE_WIDTH / float(${stride}));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
int getChunkIndex() {
|
|
94
|
+
return int(mod(vUV * DATA_TEXTURE_WIDTH, float(${stride})));
|
|
95
|
+
}
|
|
96
|
+
`],
|
|
97
|
+
],
|
|
98
|
+
}))
|
|
99
|
+
this.scene.add(this._quad)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get onBeforeRender() {
|
|
103
|
+
return this._quad.onBeforeRender
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
set onBeforeRender(value) {
|
|
107
|
+
this._quad.onBeforeRender = value
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get material() {
|
|
111
|
+
return this._quad.material
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get dataTextureWidth() {
|
|
115
|
+
return this._dataTextureWidth
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get dataTextureHeight() {
|
|
119
|
+
return this._dataTextureHeight
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get dataTextureSize() {
|
|
123
|
+
return [this._dataTextureWidth, this._dataTextureHeight]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get dataTexture() {
|
|
127
|
+
return this._quad.material.dataTexture
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get stride() {
|
|
131
|
+
return this._stride
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
get debug() {
|
|
135
|
+
return this._debug
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
set debug(value) {
|
|
139
|
+
this._debug = value
|
|
140
|
+
if (this._debug && !DEBUG_RENDERER) {
|
|
141
|
+
DEBUG_RENDERER = new WebGLRenderer()
|
|
142
|
+
document.body.appendChild(DEBUG_RENDERER.domElement)
|
|
143
|
+
DEBUG_RENDERER.setSize(this._dataTextureWidth, this._dataTextureHeight, false)
|
|
144
|
+
DEBUG_RENDERER.domElement.style.position = 'absolute'
|
|
145
|
+
DEBUG_RENDERER.domElement.style.bottom = '0'
|
|
146
|
+
DEBUG_RENDERER.domElement.style.left = '0'
|
|
147
|
+
DEBUG_RENDERER.domElement.style.width = '100%'
|
|
148
|
+
DEBUG_RENDERER.domElement.style.height = '25%'
|
|
149
|
+
DEBUG_RENDERER.domElement.style.imageRendering = 'pixelated'
|
|
150
|
+
}
|
|
151
|
+
if (DEBUG_RENDERER) {
|
|
152
|
+
DEBUG_RENDERER.domElement.hidden = !this._debug
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
update() {
|
|
157
|
+
const savedRendertarget = this._renderer.getRenderTarget()
|
|
158
|
+
|
|
159
|
+
this._renderer.setRenderTarget(this._webglRenderTargetOut)
|
|
160
|
+
this._renderer.render(this.scene, this.camera)
|
|
161
|
+
|
|
162
|
+
if (this.debug) {
|
|
163
|
+
DEBUG_RENDERER.setRenderTarget(this._webglRenderTargetOut)
|
|
164
|
+
DEBUG_RENDERER.render(this.scene, this.camera)
|
|
165
|
+
DEBUG_RENDERER.setRenderTarget(null)
|
|
166
|
+
DEBUG_RENDERER.render(this.scene, this.camera)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
[this._webglRenderTargetIn, this._webglRenderTargetOut] = [this._webglRenderTargetOut, this._webglRenderTargetIn]
|
|
170
|
+
|
|
171
|
+
this._quad.material.dataTexture = this._webglRenderTargetIn.texture
|
|
172
|
+
|
|
173
|
+
this._renderer.setRenderTarget(savedRendertarget)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Loader } from '../../core/util/Loader.js'
|
|
2
|
+
import { WebGLRenderer } from '../../../three/src/renderers/WebGLRenderer.js'
|
|
3
|
+
import { TextureLoader } from '../../../three/src/loaders/TextureLoader.js'
|
|
4
|
+
|
|
5
|
+
import { BasisTextureLoader } from '../examples/loaders/BasisTextureLoader.js'
|
|
6
|
+
import { DRACOLoader } from '../examples/loaders/DRACOLoader.js'
|
|
7
|
+
import { GLTFLoader } from '../examples/loaders/GLTFLoader.js'
|
|
8
|
+
import { Mesh } from '../../../three/src/objects/Mesh.js'
|
|
9
|
+
import { Line } from '../../../three/src/objects/Line.js'
|
|
10
|
+
import { LineSegments } from '../../../three/src/objects/LineSegments.js'
|
|
11
|
+
import { Vector3 } from '../../../three/src/math/Vector3.js'
|
|
12
|
+
|
|
13
|
+
function computeSceneGeometry(data, scale, offset) {
|
|
14
|
+
const hasOffset = offset.lengthSq() !== 0
|
|
15
|
+
data.traverse((object3D) => {
|
|
16
|
+
if (hasOffset) {
|
|
17
|
+
if (object3D instanceof Mesh || object3D instanceof Line || object3D instanceof LineSegments) {
|
|
18
|
+
object3D.geometry.translate(offset.x, offset.y, offset.z)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (scale !== 1) {
|
|
22
|
+
if (object3D instanceof Mesh || object3D instanceof Line || object3D instanceof LineSegments) {
|
|
23
|
+
object3D.geometry.scale(scale, scale, scale)
|
|
24
|
+
}
|
|
25
|
+
object3D.position.multiplyScalar(scale)
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let gltfLoader
|
|
31
|
+
let dracoLoader
|
|
32
|
+
let basisLoader
|
|
33
|
+
|
|
34
|
+
let meshOptimizerInitialized = false
|
|
35
|
+
|
|
36
|
+
class THREELoader extends Loader {
|
|
37
|
+
constructor() {
|
|
38
|
+
super()
|
|
39
|
+
this.dracoDecoderPath = 'node_modules/three/examples/js/libs/draco/'
|
|
40
|
+
this.basisTranscoderPath = 'node_modules/three/examples/js/libs/basis/'
|
|
41
|
+
|
|
42
|
+
this.extensionTypeMap.set('gltf', 'model/gltf+json')
|
|
43
|
+
this.extensionTypeMap.set('glb', 'model/gltf-binary')
|
|
44
|
+
this.extensionTypeMap.set('basis', 'image/basis')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async _loadFile({ src, type, scale = 1, offset = new Vector3(), meshOptimizer = false }) {
|
|
48
|
+
if (type.startsWith('model')) {
|
|
49
|
+
const [, path, file] = /(.*[\/\\])(.*$)/.exec(src)
|
|
50
|
+
|
|
51
|
+
if (!gltfLoader) {
|
|
52
|
+
gltfLoader = new GLTFLoader(undefined)
|
|
53
|
+
dracoLoader = new DRACOLoader(undefined)
|
|
54
|
+
dracoLoader.setWorkerLimit(2)
|
|
55
|
+
gltfLoader.setDRACOLoader(dracoLoader)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (meshOptimizer && !meshOptimizerInitialized) {
|
|
59
|
+
await import('./meshoptimizerdecoder/meshopt_decoder.js')
|
|
60
|
+
const { EXT_meshopt_compression } = await import('./meshoptimizerdecoder/THREE.EXT_meshopt_compression.js')
|
|
61
|
+
gltfLoader.register(function (parser) {
|
|
62
|
+
const res = new EXT_meshopt_compression(parser, MeshoptDecoder)
|
|
63
|
+
res.name = 'MESHOPT_compression'
|
|
64
|
+
return res
|
|
65
|
+
})
|
|
66
|
+
meshOptimizerInitialized = true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
dracoLoader.setDecoderPath(`${this.baseURI}${this.dracoDecoderPath}`)
|
|
70
|
+
gltfLoader.setPath(path)
|
|
71
|
+
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
gltfLoader.load(file, (data) => {
|
|
74
|
+
computeSceneGeometry(data.scene, scale, offset)
|
|
75
|
+
resolve(data)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
} else if (type === 'image/basis') {
|
|
79
|
+
if (!basisLoader) {
|
|
80
|
+
basisLoader = new BasisTextureLoader(undefined)
|
|
81
|
+
basisLoader.setWorkerLimit(2)
|
|
82
|
+
let renderer
|
|
83
|
+
if (window.WebGL2RenderingContext !== undefined && !/\bforcewebgl1\b/.test(window.location.search)) {
|
|
84
|
+
const canvas = document.createElement('canvas')
|
|
85
|
+
renderer = new WebGLRenderer({
|
|
86
|
+
canvas: canvas,
|
|
87
|
+
context: canvas.getContext('webgl2'),
|
|
88
|
+
})
|
|
89
|
+
} else {
|
|
90
|
+
renderer = new WebGLRenderer()
|
|
91
|
+
}
|
|
92
|
+
basisLoader.detectSupport(renderer)
|
|
93
|
+
}
|
|
94
|
+
basisLoader.setTranscoderPath(`${this.baseURI}${this.basisTranscoderPath}`)
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
basisLoader.load(src, (texture) => {
|
|
97
|
+
resolve(texture)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
} else if (type.startsWith('image') || type.startsWith('video')) {
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
new TextureLoader().load(src, (texture) => {
|
|
103
|
+
resolve(texture)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
} else {
|
|
107
|
+
return super._loadFile({ src, type })
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default new THREELoader()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* three.js extension for EXT_meshopt_compression; requires three.js r118 */
|
|
2
|
+
/* loader.register(function (parser) { return new EXT_meshopt_compression(parser, MeshoptDecoder); }); */
|
|
3
|
+
const EXT_meshopt_compression = (function () {
|
|
4
|
+
function EXT_meshopt_compression(parser, decoder) {
|
|
5
|
+
this.name = 'EXT_meshopt_compression'
|
|
6
|
+
this._parser = parser
|
|
7
|
+
this._decoder = decoder
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
EXT_meshopt_compression.prototype.loadBufferView = function (index) {
|
|
11
|
+
const bufferView = this._parser.json.bufferViews[index]
|
|
12
|
+
|
|
13
|
+
if (bufferView.extensions && bufferView.extensions[this.name]) {
|
|
14
|
+
const extensionDef = bufferView.extensions[this.name]
|
|
15
|
+
|
|
16
|
+
const buffer = this._parser.getDependency('buffer', extensionDef.buffer)
|
|
17
|
+
const decoder = this._decoder
|
|
18
|
+
|
|
19
|
+
return Promise.all([buffer, decoder.ready]).then(function (res) {
|
|
20
|
+
const byteOffset = extensionDef.byteOffset || 0
|
|
21
|
+
const byteLength = extensionDef.byteLength || 0
|
|
22
|
+
|
|
23
|
+
const count = extensionDef.count
|
|
24
|
+
const stride = extensionDef.byteStride
|
|
25
|
+
|
|
26
|
+
const result = new ArrayBuffer(count * stride)
|
|
27
|
+
const source = new Uint8Array(res[0], byteOffset, byteLength)
|
|
28
|
+
|
|
29
|
+
decoder.decodeGltfBuffer(new Uint8Array(result), count, stride, source, extensionDef.mode, extensionDef.filter)
|
|
30
|
+
return result
|
|
31
|
+
})
|
|
32
|
+
} else {
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return EXT_meshopt_compression
|
|
38
|
+
}())
|
|
39
|
+
|
|
40
|
+
/* three.js uses JS modules exclusively since r124 */
|
|
41
|
+
export { EXT_meshopt_compression }
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// This file is part of meshoptimizer library and is distributed under the terms of MIT License.
|
|
2
|
+
// Copyright (C) 2016-2020, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
|
3
|
+
const MeshoptDecoder = (function () {
|
|
4
|
+
'use strict'
|
|
5
|
+
|
|
6
|
+
// Built with emcc (Emscripten gcc/clang-like replacement) 1.39.18 (a3beeb0d6c9825bd1757d03677e817d819949a77)
|
|
7
|
+
// Built from meshoptimizer 0.14
|
|
8
|
+
const wasm_base = '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pAK1BEHLCgBZCdWAEqREAKCIJALCa3QBpAK2BIC8cWAEqREAKCLJMRLCBAECFZlAECFr9zAfJHfREMGXAMCb9HIXALRVSFMAL1BBHKCgFZRNGaALCFJAKCa3QBpANCgBZAL1BFHKCgBZCOWqRNALCGJAKCa3QBpAL1BGHKCgBZCfWANqRNALCEJAKCa3QBpAL1BEHKCgBZCdWANqRNALCIJAKCa3QBpAL2BIC8cWANqRNALCLJMRVCBANCFZlANCFr9zAfJHfRNMGXAGCG6IXABATCFWJHLAQ87FBALAE87FGALAN87FISFMABATCGWJHLAQjGBALANjGNALAEjGIMAOCXlAcCEWJHLAQjGIALAEjGBAOAICGWJAQjGBAOCXlAcCFJCbZCEWJHLANjGBALAEjGIAOAICFJHICbZCGWJAEjGBAOCXlAcCGJCbZCEWJHEAQjGBAEANjGIAOAIAS9FASCb6qJHECbZCGWJANjGBAcCEJRcAEAM9FAMCb6qJMRIAmCFJRmAcCbZRcAICbZRIATCEJHTAF9JQBMMCBC99AVAt6yRcMAOCoFJ8kBAcM9SFGaCUS8oGBHFABCEJC98ZHGJRBGXAGCF9OCBABAFuyQBAB8/BCTW9LIXABTE9FQFMCUSABjGBAFbMCUNC8wjGBCaM/GGFGaABCUFJHFCaJCgF86BBABCgF86BBAFC9+JCgF86BBABCgF86BFAFC99JCgF86BBABCgF86BGAFC98JCgF86BBABCgF86BEABCBABlCEZHFJHBCajGBABCUFAFlC98ZHGJHFC98JCajGBGXAGCV9JQBABCajGNABCajGIAFC94JCajGBAFCWJCajGBAGC8Z9JQBABCajGiABCajGPABCajGTABCajGSAFC9wJCajGBAFC9sJCajGBAFC9oJCajGBAFC9kJCajGBAGABCIZCiqHGlHFCA9JQBABAGJRBEXABha83EiABha83ETABha83ENABha83EBABCAJRBAFC9gJHFC8f9LQBMMM/LSFba8jBCU/EBlHT8kBGaC9+AGCFJAI9LQBpCaAE2BBC+gF9HQBpATAEAIJHbAGlAGTFRMCUoBAG9uC/wgBZHICUGAICUG9JyRtAECFJRVGXEXASAF9PQFAtAFASlASAtJAF9JyRQGXGXAG9FIXAVRISFMAQCbJHEC9wZRmAECIrCEJCGrRYCBRfAVRcEXAbAclAY9JIXCBRVSEMAcAYJRICBRVCBREAmIXEXAbAIlCi9JQIAMCU/CBJAEJRNGXGXGXGXGXAcAECKrJ2BBAECErCKZrCEZCFlfEFGEBMANhB83EBANhB83ENSEMANAI2BIAI2BBHKCKrHLALCE6HLy86BBANAICIJALJHL2BBAKCIrCEZHOAOCE6HOy86BFANALAOJHL2BBAKCGrCEZHOAOCE6HOy86BGANALAOJHL2BBAKCEZHKAKCE6HKy86BEANALAKJHL2BBAI2BFHKCKrHOAOCE6HOy86BIANALAOJHL2BBAKCIrCEZHOAOCE6HOy86BLANALAOJHL2BBAKCGrCEZHOAOCE6HOy86BKANALAOJHL2BBAKCEZHKAKCE6HKy86BOANALAKJHL2BBAI2BGHKCKrHOAOCE6HOy86BNANALAOJHL2BBAKCIrCEZHOAOCE6HOy86BVANALAOJHL2BBAKCGrCEZHOAOCE6HOy86BcANALAOJHL2BBAKCEZHKAKCE6HKy86BMANALAKJHK2BBAI2BEHICKrHLALCE6HLy86BSANALAKJHK2BBAICIrCEZHLALCE6HLy86BQANALAKJHK2BBAICGrCEZHLALCE6HLy86BfANALAKJHN2BBAICEZHIAICE6HIy86BbAIANJRISGMANAI2BNAI2BBHKCIrHLALCb6HLy86BBANAICNJALJHL2BBAKCbZHKAKCb6HKy86BFANALAKJHK2BBAI2BFHLCIrHOAOCb6HOy86BGANAKAOJHK2BBALCbZHLALCb6HLy86BEANALAKJHK2BBAI2BGHLCIrHOAOCb6HOy86BIANAKAOJHK2BBALCbZHLALCb6HLy86BLANALAKJHK2BBAI2BEHLCIrHOAOCb6HOy86BKANAKAOJHK2BBALCbZHLALCb6HLy86BOANALAKJHK2BBAI2BIHLCIrHOAOCb6HOy86BNANAKAOJHK2BBALCbZHLALCb6HLy86BVANALAKJHK2BBAI2BLHLCIrHOAOCb6HOy86BcANAKAOJHK2BBALCbZHLALCb6HLy86BMANALAKJHK2BBAI2BKHLCIrHOAOCb6HOy86BSANAKAOJHK2BBALCbZHLALCb6HLy86BQANALAKJHK2BBAI2BOHICIrHLALCb6HLy86BfANALAKJHN2BBAICbZHIAICb6HIy86BbAIANJRISFMANAI8pBB83BBANAI8pBN83BNAICTJRIMAECTJHEAm9JQBMMAI9FQGAQIXAMAfJ2BBRcAfREEXAMCUGJAEJAcAMCU/CBJAVJ2BBHcCFrCBAcCFZl9zJHc86BBAGAEJREAVCFJHVAQ9HQBMMAIRcAfCFJHfAG9HQBMMABAGAS9sJAMCUGJAGAQ9sTFpAMAMCUGJAQCaJAG9sJAGTFpAIRVMAQCBAVyASJRSAVQBMC9+SFMCBC99AbAVlAGCAAGCA9Ly6yMRVATCU/EBJ8kBAVMMVFBCUSMG+g9m'
|
|
9
|
+
const wasm_simd = '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'
|
|
10
|
+
|
|
11
|
+
// Uses bulk-memory and simd extensions
|
|
12
|
+
const detector = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 3, 2, 0, 0, 5, 3, 1, 0, 1, 12, 1, 0, 10, 22, 2, 12, 0, 65, 0, 65, 0, 65, 0, 252, 10, 0, 0, 11, 7, 0, 65, 0, 253, 15, 26, 11])
|
|
13
|
+
|
|
14
|
+
// Used to unpack wasm
|
|
15
|
+
const wasmpack = new Uint8Array([32, 0, 65, 253, 3, 1, 2, 34, 4, 106, 6, 5, 11, 8, 7, 20, 13, 33, 12, 16, 128, 9, 116, 64, 19, 113, 127, 15, 10, 21, 22, 14, 255, 66, 24, 54, 136, 107, 18, 23, 192, 26, 114, 118, 132, 17, 77, 101, 130, 144, 27, 87, 131, 44, 45, 74, 156, 154, 70, 167])
|
|
16
|
+
|
|
17
|
+
if (typeof WebAssembly !== 'object') {
|
|
18
|
+
// This module requires WebAssembly to function
|
|
19
|
+
return {
|
|
20
|
+
supported: false,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let wasm = wasm_base
|
|
25
|
+
|
|
26
|
+
if (WebAssembly.validate(detector)) {
|
|
27
|
+
wasm = wasm_simd
|
|
28
|
+
console.log('Warning: meshopt_decoder is using experimental SIMD support')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let instance; let heap
|
|
32
|
+
|
|
33
|
+
const env = {
|
|
34
|
+
emscripten_notify_memory_growth: function (index) {
|
|
35
|
+
heap = new Uint8Array(instance.exports.memory.buffer)
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const promise =
|
|
40
|
+
WebAssembly.instantiate(unpack(wasm), { env })
|
|
41
|
+
.then(function (result) {
|
|
42
|
+
instance = result.instance
|
|
43
|
+
instance.exports._initialize()
|
|
44
|
+
env.emscripten_notify_memory_growth(0)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
function unpack(data) {
|
|
48
|
+
const result = new Uint8Array(data.length)
|
|
49
|
+
for (var i = 0; i < data.length; ++i) {
|
|
50
|
+
const ch = data.charCodeAt(i)
|
|
51
|
+
result[i] = ch > 96 ? ch - 71 : ch > 64 ? ch - 65 : ch > 47 ? ch + 4 : ch > 46 ? 63 : 62
|
|
52
|
+
}
|
|
53
|
+
let write = 0
|
|
54
|
+
for (var i = 0; i < data.length; ++i) {
|
|
55
|
+
result[write++] = (result[i] < 60) ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i]
|
|
56
|
+
}
|
|
57
|
+
return result.buffer.slice(0, write)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function decode(fun, target, count, size, source, filter) {
|
|
61
|
+
const sbrk = instance.exports.sbrk
|
|
62
|
+
const count4 = (count + 3) & ~3 // pad for SIMD filter
|
|
63
|
+
const tp = sbrk(count4 * size)
|
|
64
|
+
const sp = sbrk(source.length)
|
|
65
|
+
heap.set(source, sp)
|
|
66
|
+
const res = fun(tp, count, size, sp, source.length)
|
|
67
|
+
if (res == 0 && filter) {
|
|
68
|
+
filter(tp, count4, size)
|
|
69
|
+
}
|
|
70
|
+
target.set(heap.subarray(tp, tp + count * size))
|
|
71
|
+
sbrk(tp - sbrk(0))
|
|
72
|
+
if (res != 0) {
|
|
73
|
+
throw new Error('Malformed buffer data: ' + res)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const filters = {
|
|
78
|
+
// legacy index-based enums for glTF
|
|
79
|
+
0: '',
|
|
80
|
+
1: 'meshopt_decodeFilterOct',
|
|
81
|
+
2: 'meshopt_decodeFilterQuat',
|
|
82
|
+
3: 'meshopt_decodeFilterExp',
|
|
83
|
+
// string-based enums for glTF
|
|
84
|
+
NONE: '',
|
|
85
|
+
OCTAHEDRAL: 'meshopt_decodeFilterOct',
|
|
86
|
+
QUATERNION: 'meshopt_decodeFilterQuat',
|
|
87
|
+
EXPONENTIAL: 'meshopt_decodeFilterExp',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const decoders = {
|
|
91
|
+
// legacy index-based enums for glTF
|
|
92
|
+
0: 'meshopt_decodeVertexBuffer',
|
|
93
|
+
1: 'meshopt_decodeIndexBuffer',
|
|
94
|
+
2: 'meshopt_decodeIndexSequence',
|
|
95
|
+
// string-based enums for glTF
|
|
96
|
+
ATTRIBUTES: 'meshopt_decodeVertexBuffer',
|
|
97
|
+
TRIANGLES: 'meshopt_decodeIndexBuffer',
|
|
98
|
+
INDICES: 'meshopt_decodeIndexSequence',
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
ready: promise,
|
|
103
|
+
supported: true,
|
|
104
|
+
decodeVertexBuffer: function (target, count, size, source, filter) {
|
|
105
|
+
decode(instance.exports.meshopt_decodeVertexBuffer, target, count, size, source, instance.exports[filters[filter]])
|
|
106
|
+
},
|
|
107
|
+
decodeIndexBuffer: function (target, count, size, source) {
|
|
108
|
+
decode(instance.exports.meshopt_decodeIndexBuffer, target, count, size, source)
|
|
109
|
+
},
|
|
110
|
+
decodeIndexSequence: function (target, count, size, source) {
|
|
111
|
+
decode(instance.exports.meshopt_decodeIndexSequence, target, count, size, source)
|
|
112
|
+
},
|
|
113
|
+
decodeGltfBuffer: function (target, count, size, source, mode, filter) {
|
|
114
|
+
decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]])
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
})()
|
|
118
|
+
|
|
119
|
+
if (typeof exports === 'object' && typeof module === 'object') {
|
|
120
|
+
module.exports = MeshoptDecoder
|
|
121
|
+
} else if (typeof define === 'function' && define['amd']) {
|
|
122
|
+
define([], function () {
|
|
123
|
+
return MeshoptDecoder
|
|
124
|
+
})
|
|
125
|
+
} else if (typeof exports === 'object') {
|
|
126
|
+
exports['MeshoptDecoder'] = MeshoptDecoder
|
|
127
|
+
} else {
|
|
128
|
+
(typeof self !== 'undefined' ? self : this).MeshoptDecoder = MeshoptDecoder
|
|
129
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import THREEShaderMaterial from './THREEShaderMaterial.js'
|
|
2
|
+
import { ShaderChunk } from '../../../three/src/Three.js'
|
|
3
|
+
|
|
4
|
+
export default class THREEBaseMaterial extends THREEShaderMaterial {
|
|
5
|
+
constructor({
|
|
6
|
+
vertexChunks = [],
|
|
7
|
+
fragmentChunks = [],
|
|
8
|
+
uniforms = {},
|
|
9
|
+
...options
|
|
10
|
+
} = {}) {
|
|
11
|
+
super({
|
|
12
|
+
uniforms,
|
|
13
|
+
vertex: `
|
|
14
|
+
void main() {
|
|
15
|
+
}
|
|
16
|
+
`,
|
|
17
|
+
vertexChunks: [
|
|
18
|
+
['start', `
|
|
19
|
+
${options.morphTargets ? '#include <morphtarget_pars_vertex>' : ''}
|
|
20
|
+
${options.skinning ? '#include <skinning_pars_vertex>' : ''}
|
|
21
|
+
|
|
22
|
+
out vec3 vPosition;
|
|
23
|
+
out vec3 vNormal;
|
|
24
|
+
out vec2 vUV;
|
|
25
|
+
out vec3 vWorldPosition;
|
|
26
|
+
out vec3 vViewDirection;
|
|
27
|
+
out float vFresnel;
|
|
28
|
+
`],
|
|
29
|
+
['main', `
|
|
30
|
+
vec3 transformedPosition = position;
|
|
31
|
+
vec3 transformedNormal = normal;
|
|
32
|
+
|
|
33
|
+
${options.skinning ? ShaderChunk.skinbase_vertex : ''}
|
|
34
|
+
|
|
35
|
+
${options.morphTargets ? ShaderChunk.morphnormal_vertex.replace(/objectNormal/g, 'transformedNormal') : ''}
|
|
36
|
+
${options.skinning ? ShaderChunk.skinnormal_vertex.replace(/objectNormal/g, 'transformedNormal') : ''}
|
|
37
|
+
|
|
38
|
+
${options.morphTargets ? ShaderChunk.morphtarget_vertex.replace(/transformed/g, 'transformedPosition') : ''}
|
|
39
|
+
${options.skinning ? ShaderChunk.skinning_vertex.replace(/transformed/g, 'transformedPosition') : ''}
|
|
40
|
+
`],
|
|
41
|
+
['end', `
|
|
42
|
+
vec3 worldPosition = (modelMatrix * vec4(transformedPosition, 1.)).xyz;
|
|
43
|
+
gl_Position = projectionMatrix * viewMatrix * vec4(worldPosition, 1.);
|
|
44
|
+
|
|
45
|
+
vWorldPosition = worldPosition;
|
|
46
|
+
vViewDirection = normalize(worldPosition - cameraPosition);
|
|
47
|
+
vPosition = transformedPosition;
|
|
48
|
+
vNormal = normalize(mat3(modelMatrix) * transformedNormal);
|
|
49
|
+
vUV = uv;
|
|
50
|
+
vFresnel = max(0., 1. - dot(-vViewDirection, vNormal));
|
|
51
|
+
`],
|
|
52
|
+
...vertexChunks,
|
|
53
|
+
],
|
|
54
|
+
fragmentChunks: [
|
|
55
|
+
['start', `
|
|
56
|
+
in vec3 vPosition;
|
|
57
|
+
in vec3 vNormal;
|
|
58
|
+
in vec2 vUV;
|
|
59
|
+
in vec3 vWorldPosition;
|
|
60
|
+
in vec3 vViewDirection;
|
|
61
|
+
in float vFresnel;
|
|
62
|
+
`],
|
|
63
|
+
...fragmentChunks,
|
|
64
|
+
],
|
|
65
|
+
...options,
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import THREEShaderMaterial from './THREEShaderMaterial.js'
|
|
2
|
+
import LightShader from '../../core/shader/LightShader.js'
|
|
3
|
+
import RayShader from '../../core/shader/RayShader.js'
|
|
4
|
+
import PBRShader from '../../core/shader/PBRShader.js'
|
|
5
|
+
import { Color, Vector3, ShaderChunk } from '../../../three/src/Three.js'
|
|
6
|
+
|
|
7
|
+
export default class THREEPBRMaterial extends THREEShaderMaterial {
|
|
8
|
+
constructor({
|
|
9
|
+
webgl2 = true,
|
|
10
|
+
vertexChunks = [],
|
|
11
|
+
fragmentChunks = [],
|
|
12
|
+
uniforms = {},
|
|
13
|
+
pbrDiffuseLightFromRay = (uniforms.envMap ? `
|
|
14
|
+
vec4 texel = ${webgl2 ? 'textureLod' : 'textureCubeLodEXT'}(envMap, ray.direction, roughness * ${Math.log2(uniforms.envMap.image.width).toFixed(1)});
|
|
15
|
+
return texel.rgb;
|
|
16
|
+
` : undefined),
|
|
17
|
+
pbrReflectionFromRay = (uniforms.envMap ? `
|
|
18
|
+
vec4 texel = ${webgl2 ? 'textureLod' : 'textureCubeLodEXT'}(envMap, ray.direction, roughness * ${Math.log2(uniforms.envMap.image.width).toFixed(1)});
|
|
19
|
+
return texel.rgb;
|
|
20
|
+
` : undefined),
|
|
21
|
+
...options
|
|
22
|
+
} = {}) {
|
|
23
|
+
super({
|
|
24
|
+
lights: !!uniforms.light,
|
|
25
|
+
uniforms: {
|
|
26
|
+
baseColor: new Color('#ffffff'),
|
|
27
|
+
metalness: 0,
|
|
28
|
+
roughness: 0,
|
|
29
|
+
opacity: 1,
|
|
30
|
+
light: {
|
|
31
|
+
intensity: 0,
|
|
32
|
+
color: new Color('#ffffff'),
|
|
33
|
+
position: new Vector3(),
|
|
34
|
+
direction: new Vector3(),
|
|
35
|
+
},
|
|
36
|
+
...uniforms,
|
|
37
|
+
},
|
|
38
|
+
vertex: `
|
|
39
|
+
void main() {
|
|
40
|
+
}
|
|
41
|
+
`,
|
|
42
|
+
vertexChunks: [
|
|
43
|
+
['start', `
|
|
44
|
+
${options.skinning ? '#include <skinning_pars_vertex>' : ''}
|
|
45
|
+
|
|
46
|
+
varying vec3 vPosition;
|
|
47
|
+
varying vec3 vNormal;
|
|
48
|
+
varying vec2 vUv;
|
|
49
|
+
varying vec3 vWorldPosition;
|
|
50
|
+
varying vec3 vViewDirection;
|
|
51
|
+
`],
|
|
52
|
+
['main', `
|
|
53
|
+
vec3 pbrPosition = position;
|
|
54
|
+
vec3 pbrNormal = normal;
|
|
55
|
+
|
|
56
|
+
${options.skinning ? ShaderChunk.skinbase_vertex : ''}
|
|
57
|
+
${options.skinning ? ShaderChunk.skinnormal_vertex.replace(/objectNormal/g, 'pbrNormal') : ''}
|
|
58
|
+
${options.skinning ? ShaderChunk.skinning_vertex.replace(/transformed/g, 'pbrPosition') : ''}
|
|
59
|
+
`],
|
|
60
|
+
['end', `
|
|
61
|
+
vec3 pbrWorldPosition = (modelMatrix * vec4(pbrPosition, 1.)).xyz;
|
|
62
|
+
gl_Position = projectionMatrix * viewMatrix * vec4(pbrWorldPosition, 1.);
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
vWorldPosition = pbrWorldPosition;
|
|
66
|
+
vViewDirection = normalize(pbrWorldPosition - cameraPosition);
|
|
67
|
+
vPosition = pbrPosition;
|
|
68
|
+
vNormal = normalize(mat3(modelMatrix) * pbrNormal);
|
|
69
|
+
vUv = uv;
|
|
70
|
+
`],
|
|
71
|
+
...vertexChunks,
|
|
72
|
+
],
|
|
73
|
+
fragmentChunks: [
|
|
74
|
+
['start', `
|
|
75
|
+
${LightShader.Light}
|
|
76
|
+
${RayShader.Ray}
|
|
77
|
+
${PBRShader.PhysicallyBasedMaterial}
|
|
78
|
+
|
|
79
|
+
uniform vec3 baseColor;
|
|
80
|
+
uniform float metalness;
|
|
81
|
+
uniform float roughness;
|
|
82
|
+
uniform float opacity;
|
|
83
|
+
uniform Light light;
|
|
84
|
+
${uniforms.envMap ? 'uniform samplerCube envMap;' : ''}
|
|
85
|
+
${uniforms.map ? 'uniform sampler2D map;' : ''}
|
|
86
|
+
|
|
87
|
+
varying vec3 vNormal;
|
|
88
|
+
varying vec3 vPosition;
|
|
89
|
+
varying vec2 vUv;
|
|
90
|
+
varying vec3 vWorldPosition;
|
|
91
|
+
varying vec3 vViewDirection;
|
|
92
|
+
|
|
93
|
+
${PBRShader.computePBRColor({ pbrReflectionFromRay, pbrDiffuseLightFromRay })}
|
|
94
|
+
`],
|
|
95
|
+
['main', `
|
|
96
|
+
${uniforms.map ? 'vec4 mapTexel = texture2D(map, vUv);' : ''}
|
|
97
|
+
vec4 pbrColor = computePBRColor(vViewDirection, light, vPosition, vNormal, PhysicallyBasedMaterial(vec4(${uniforms.map ? 'baseColor * mapTexel.rgb' : 'baseColor'}, ${uniforms.map ? 'opacity * mapTexel.a' : 'opacity'}), metalness, roughness));
|
|
98
|
+
`],
|
|
99
|
+
['end', `
|
|
100
|
+
gl_FragColor = pbrColor;
|
|
101
|
+
`],
|
|
102
|
+
...fragmentChunks,
|
|
103
|
+
],
|
|
104
|
+
...options,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}
|