bg2e-js 2.3.11 → 2.3.13
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/dist/bg2e-js.js +356 -326
- package/dist/bg2e-js.js.map +1 -1
- package/package.json +56 -56
- package/src/app/AppController.ts +39 -39
- package/src/app/Bg2KeyboardEvent.ts +54 -54
- package/src/app/Bg2MouseEvent.ts +82 -82
- package/src/app/Bg2TouchEvent.ts +18 -18
- package/src/app/Canvas.ts +108 -108
- package/src/app/EventBase.ts +10 -10
- package/src/app/MainLoop.ts +273 -273
- package/src/app/index.ts +24 -24
- package/src/base/Color.ts +134 -134
- package/src/base/Environment.ts +183 -183
- package/src/base/Light.ts +192 -192
- package/src/base/Material.ts +620 -620
- package/src/base/PolyList.ts +365 -365
- package/src/base/Texture.ts +620 -620
- package/src/base/index.ts +81 -81
- package/src/db/Bg2LoaderPlugin.ts +143 -143
- package/src/db/DBPluginApi.ts +48 -48
- package/src/db/Loader.ts +116 -116
- package/src/db/LoaderPlugin.ts +34 -34
- package/src/db/MtlParser.ts +7 -7
- package/src/db/ObjLoaderPlugin.ts +54 -54
- package/src/db/ObjParser.ts +252 -252
- package/src/db/ObjWriterPlugin.ts +18 -18
- package/src/db/VitscnjLoaderPlugin.ts +112 -112
- package/src/db/Writer.ts +52 -52
- package/src/db/WriterPlugin.ts +22 -22
- package/src/db/index.ts +44 -44
- package/src/debug/DebugRenderer.ts +173 -173
- package/src/debug/WebGLTextureViewer.ts +75 -75
- package/src/debug/index.ts +6 -6
- package/src/index.html +11 -11
- package/src/index.ts +33 -33
- package/src/manipulation/SelectionBuffer.ts +81 -81
- package/src/manipulation/SelectionHighlight.ts +105 -84
- package/src/manipulation/SelectionIdAssignVisitor.ts +96 -96
- package/src/manipulation/SelectionManager.ts +196 -188
- package/src/manipulation/SelectionMode.ts +6 -6
- package/src/math/Mat3.ts +259 -259
- package/src/math/Mat4.ts +710 -710
- package/src/math/MatrixStrategy.ts +25 -25
- package/src/math/Quat.ts +65 -65
- package/src/math/Vec.ts +753 -753
- package/src/math/constants.ts +46 -46
- package/src/math/functions.ts +103 -103
- package/src/math/index.ts +74 -74
- package/src/phsics/joint.ts +137 -137
- package/src/primitives/arrow.ts +57 -57
- package/src/primitives/cone.ts +138 -138
- package/src/primitives/cube.ts +60 -60
- package/src/primitives/cylinder.ts +216 -216
- package/src/primitives/index.ts +13 -13
- package/src/primitives/plane.ts +31 -31
- package/src/primitives/sphere.ts +809 -809
- package/src/react/useBg2e.ts +69 -69
- package/src/render/BRDFIntegrationMap.ts +4 -4
- package/src/render/Environment.ts +135 -135
- package/src/render/FrameBuffer.ts +35 -35
- package/src/render/MaterialRenderer.ts +34 -34
- package/src/render/Pipeline.ts +108 -108
- package/src/render/PolyListRenderer.ts +47 -47
- package/src/render/RenderBuffer.ts +197 -197
- package/src/render/RenderQueue.ts +198 -198
- package/src/render/RenderState.ts +116 -116
- package/src/render/Renderer.ts +248 -248
- package/src/render/SceneAppController.ts +250 -250
- package/src/render/SceneRenderer.ts +387 -387
- package/src/render/Shader.ts +32 -32
- package/src/render/ShadowRenderer.ts +176 -176
- package/src/render/SkyCube.ts +105 -105
- package/src/render/SkySphere.ts +117 -117
- package/src/render/TextureMergerRenderer.ts +70 -70
- package/src/render/TextureRenderer.ts +34 -34
- package/src/render/index.ts +67 -67
- package/src/render/webgl/FrameBuffer.ts +9 -9
- package/src/render/webgl/MaterialRenderer.ts +112 -112
- package/src/render/webgl/Pipeline.ts +88 -88
- package/src/render/webgl/PolyListRenderer.ts +260 -260
- package/src/render/webgl/RenderBuffer.ts +226 -226
- package/src/render/webgl/Renderer.ts +262 -262
- package/src/render/webgl/SceneRenderer.ts +67 -67
- package/src/render/webgl/ShaderProgram.ts +424 -424
- package/src/render/webgl/ShadowRenderer.ts +6 -6
- package/src/render/webgl/SkyCube.ts +15 -15
- package/src/render/webgl/SkySphere.ts +15 -15
- package/src/render/webgl/State.ts +152 -152
- package/src/render/webgl/TextureRenderer.ts +167 -167
- package/src/render/webgl/VertexBuffer.ts +137 -137
- package/src/render/webgl/index.ts +35 -35
- package/src/scene/Camera.ts +458 -458
- package/src/scene/Chain.ts +44 -44
- package/src/scene/ChainJoint.ts +58 -58
- package/src/scene/Component.ts +177 -177
- package/src/scene/ComponentMap.ts +106 -106
- package/src/scene/Drawable.ts +154 -154
- package/src/scene/EnvironmentComponent.ts +141 -141
- package/src/scene/FindNodeVisitor.ts +59 -59
- package/src/scene/LightComponent.ts +154 -154
- package/src/scene/MatrixState.ts +46 -46
- package/src/scene/Node.ts +328 -328
- package/src/scene/NodeVisitor.ts +15 -15
- package/src/scene/OrbitCameraController.ts +450 -450
- package/src/scene/SmoothOrbitCameraController.ts +99 -99
- package/src/scene/Transform.ts +73 -73
- package/src/scene/index.ts +60 -60
- package/src/shaders/BasicDiffuseColorShader.ts +111 -111
- package/src/shaders/BasicPBRLightShader.ts +276 -276
- package/src/shaders/DebugRenderShader.ts +97 -97
- package/src/shaders/DepthRenderShader.ts +127 -127
- package/src/shaders/IrradianceMapCubeShader.ts +115 -115
- package/src/shaders/PBRLightIBLShader.ts +486 -486
- package/src/shaders/PickSelectionShader.ts +101 -101
- package/src/shaders/PresentDebugFramebufferShader.ts +118 -118
- package/src/shaders/PresentTextureShader.ts +99 -99
- package/src/shaders/SelectionHighlightShader.ts +143 -127
- package/src/shaders/ShaderFunction.ts +318 -318
- package/src/shaders/SkyCubeShader.ts +93 -93
- package/src/shaders/SkySphereShader.ts +102 -102
- package/src/shaders/SpecularMapCubeShader.ts +164 -164
- package/src/shaders/TextureMergerShader.ts +171 -171
- package/src/shaders/index.ts +36 -36
- package/src/shaders/webgl/color_correction.glsl +47 -47
- package/src/shaders/webgl/constants.glsl +6 -6
- package/src/shaders/webgl/index.ts +70 -70
- package/src/shaders/webgl/normal_map.glsl +9 -9
- package/src/shaders/webgl/pbr.glsl +173 -173
- package/src/shaders/webgl/uniforms.glsl +91 -91
- package/src/shaders/webgl_shader_lib.ts +213 -213
- package/src/tools/BinaryResourceProvider.ts +14 -14
- package/src/tools/ImageResourceProvider.ts +66 -66
- package/src/tools/MaterialModifier.ts +446 -446
- package/src/tools/Resource.ts +203 -203
- package/src/tools/ResourceProvider.ts +69 -69
- package/src/tools/TextResourceProvider.ts +24 -24
- package/src/tools/TextureCache.ts +51 -51
- package/src/tools/TextureResourceDatabase.ts +100 -100
- package/src/tools/UserAgent.ts +362 -362
- package/src/tools/VideoResourceProvider.ts +50 -50
- package/src/tools/WriteStrategy.ts +22 -22
- package/src/tools/base64.ts +11 -11
- package/src/tools/crypto.ts +19 -19
- package/src/tools/endiantess.ts +13 -13
- package/src/tools/image.ts +18 -18
- package/src/tools/index.ts +41 -41
- package/src/tools/processType.ts +39 -39
- package/src/vite-env.d.ts +12 -12
package/src/base/Material.ts
CHANGED
|
@@ -1,620 +1,620 @@
|
|
|
1
|
-
|
|
2
|
-
import Vec from '../math/Vec';
|
|
3
|
-
import Color from './Color';
|
|
4
|
-
import Texture, { TextureDataType, TextureFilter, TextureWrap } from './Texture';
|
|
5
|
-
import Canvas from '../app/Canvas';
|
|
6
|
-
import TextureCache from '../tools/TextureCache';
|
|
7
|
-
import { NumericArray } from '../math/constants';
|
|
8
|
-
|
|
9
|
-
export enum MaterialType {
|
|
10
|
-
PBR = "pbr"
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface TypeLoader {
|
|
14
|
-
serialize: (attName: string, obj: any) => any;
|
|
15
|
-
deserialize: (attName: string, obj: any, relativePath?: string, canvas?: Canvas | null) => any;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const textureTypeLoader: TypeLoader = {
|
|
19
|
-
serialize: (attName: string, obj: any) => {
|
|
20
|
-
if (!obj) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
if (obj instanceof Texture) {
|
|
24
|
-
return obj.fileName;
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Texture`);
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
deserialize: (attName: string, obj: any, relativePath: string = "", canvas: Canvas | null = null) => {
|
|
32
|
-
if (!obj) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
else if (attName === "ambientOcclussion" && typeof(obj) === "number") {
|
|
36
|
-
// Compatibility with v1.4 where ambient occlussion could be a float value
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
else if (typeof(obj) === "string") {
|
|
40
|
-
const texturePath = relativePath + obj;
|
|
41
|
-
const textureCache = TextureCache.Get(canvas);
|
|
42
|
-
if (textureCache.findTexture(texturePath)) {
|
|
43
|
-
console.debug(`Texture '${ texturePath }' already loaded. Reusing texture.`);
|
|
44
|
-
return textureCache.getTexture(texturePath);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
console.log(`Texture not found in cache. Loading texture '${ texturePath }'`);
|
|
48
|
-
const tex = new Texture(canvas);
|
|
49
|
-
tex.fileName = relativePath + obj;
|
|
50
|
-
tex.dataType = TextureDataType.IMAGE;
|
|
51
|
-
tex.minFilter = TextureFilter.LINEAR_MIPMAP_LINEAR;
|
|
52
|
-
tex.magFilter = TextureFilter.LINEAR;
|
|
53
|
-
tex.wrapModeX = TextureWrap.REPEAT;
|
|
54
|
-
tex.wrapModeY = TextureWrap.REPEAT;
|
|
55
|
-
textureCache.registerTexture(tex);
|
|
56
|
-
return tex;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is string (file path)`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export const colorTypeLoader: TypeLoader = {
|
|
66
|
-
serialize: (attName: string, obj: any) => {
|
|
67
|
-
if (!obj) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (obj instanceof Color) {
|
|
72
|
-
return obj;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Color`);
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
deserialize: (attName: string, obj: any) => {
|
|
80
|
-
if (!obj) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
else if ((Array.isArray(obj) || obj instanceof NumericArray) &&
|
|
84
|
-
(obj.length === 3 || obj.length === 4)
|
|
85
|
-
) {
|
|
86
|
-
if (obj.length === 3) {
|
|
87
|
-
return new Color([obj[0], obj[1], obj[2], 1]);
|
|
88
|
-
}
|
|
89
|
-
else if (obj.length === 4) {
|
|
90
|
-
return new Color([obj[0], obj[1], obj[2], obj[3]]);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is array with 3 or 4 elements`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const vectorTypeLoader: TypeLoader = {
|
|
100
|
-
serialize: (attName: string, obj: any) => {
|
|
101
|
-
if (!obj) {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (obj instanceof Vec) {
|
|
106
|
-
return obj;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Vec`);
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
deserialize: (attName: string, obj: any) => {
|
|
114
|
-
if (!obj) {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
else if (obj.length >= 2 && obj.length <= 4) {
|
|
118
|
-
return new Vec(obj);
|
|
119
|
-
}
|
|
120
|
-
// Retrocompatibility with v1.4
|
|
121
|
-
else if (obj._v && obj._v.length >= 2 && obj._v.length <= 4) {
|
|
122
|
-
return new Vec(obj._v);
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is array with 2, 3 or 4 elements`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export const primitiveTypeLoader: TypeLoader = {
|
|
131
|
-
serialize: (attName: string, obj: any) => {
|
|
132
|
-
if (!obj) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return obj;
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
deserialize: (attName: string, obj: any) => {
|
|
140
|
-
return obj;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
interface MaterialAttribute {
|
|
145
|
-
loader: TypeLoader;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export const MaterialAttributeNames: { [key: string]: MaterialAttribute } = {
|
|
149
|
-
type: { loader: primitiveTypeLoader },
|
|
150
|
-
alphaCutoff: { loader: primitiveTypeLoader },
|
|
151
|
-
isTransparent: { loader: primitiveTypeLoader },
|
|
152
|
-
albedo: { loader: colorTypeLoader },
|
|
153
|
-
albedoTexture: { loader: textureTypeLoader },
|
|
154
|
-
albedoScale: { loader: vectorTypeLoader },
|
|
155
|
-
albedoUV: { loader: primitiveTypeLoader },
|
|
156
|
-
normalTexture: { loader: textureTypeLoader },
|
|
157
|
-
normalScale: { loader: vectorTypeLoader },
|
|
158
|
-
normalUV: { loader: primitiveTypeLoader },
|
|
159
|
-
metalness: { loader: primitiveTypeLoader },
|
|
160
|
-
metalnessTexture: { loader: textureTypeLoader },
|
|
161
|
-
metalnessChannel: { loader: primitiveTypeLoader },
|
|
162
|
-
metalnessScale: { loader: vectorTypeLoader },
|
|
163
|
-
metalnessUV: { loader: primitiveTypeLoader },
|
|
164
|
-
roughness: { loader: primitiveTypeLoader },
|
|
165
|
-
roughnessTexture: { loader: textureTypeLoader },
|
|
166
|
-
roughnessChannel: { loader: primitiveTypeLoader },
|
|
167
|
-
roughnessScale: { loader: vectorTypeLoader },
|
|
168
|
-
roughnessUV: { loader: primitiveTypeLoader },
|
|
169
|
-
fresnelTint: { loader: colorTypeLoader },
|
|
170
|
-
sheenIntensity: { loader: primitiveTypeLoader },
|
|
171
|
-
sheenColor: { loader: colorTypeLoader },
|
|
172
|
-
lightEmission: { loader: colorTypeLoader },
|
|
173
|
-
lightEmissionTexture: { loader: textureTypeLoader },
|
|
174
|
-
lightEmissionChannel: { loader: primitiveTypeLoader },
|
|
175
|
-
lightEmissionScale: { loader: vectorTypeLoader },
|
|
176
|
-
lightEmissionUV: { loader: primitiveTypeLoader },
|
|
177
|
-
ambientOcclussion: { loader: textureTypeLoader },
|
|
178
|
-
ambientOcclussionChannel: { loader: primitiveTypeLoader },
|
|
179
|
-
ambientOcclussionUV: { loader: primitiveTypeLoader },
|
|
180
|
-
heightTexture: { loader: textureTypeLoader },
|
|
181
|
-
heightChannel: { loader: primitiveTypeLoader },
|
|
182
|
-
heightScale: { loader: vectorTypeLoader },
|
|
183
|
-
heightUV: { loader: primitiveTypeLoader },
|
|
184
|
-
heightIntensity: { loader: primitiveTypeLoader },
|
|
185
|
-
castShadows: { loader: primitiveTypeLoader },
|
|
186
|
-
unlit: { loader: primitiveTypeLoader }
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export const assertTexture = (v: any, name: string): void => {
|
|
190
|
-
if (!(v instanceof Texture)) {
|
|
191
|
-
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Texture`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export const assertColor = (v: any, name: string): void => {
|
|
196
|
-
if (!(v instanceof Color)) {
|
|
197
|
-
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Color`);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
export const assertScale = (v: any, name: string): void => {
|
|
202
|
-
if (!(v instanceof Vec) || v.length != 2) {
|
|
203
|
-
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Vec with two elements.`);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Clone the `obj` parameter if it is
|
|
208
|
-
// - Vec
|
|
209
|
-
// - Color
|
|
210
|
-
// - Texture
|
|
211
|
-
// Returns the same parameter if not
|
|
212
|
-
export const cloneObject = (obj: any): any => {
|
|
213
|
-
if (obj instanceof Color) {
|
|
214
|
-
return new Color(obj);
|
|
215
|
-
}
|
|
216
|
-
else if (obj instanceof Vec) {
|
|
217
|
-
return new Vec(obj);
|
|
218
|
-
}
|
|
219
|
-
else if (obj instanceof Texture) {
|
|
220
|
-
return obj.clone();
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
return obj;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export default class Material {
|
|
228
|
-
static async Deserialize(sceneData: any, relativePath: string = "", canvas: Canvas | null = null): Promise<Material> {
|
|
229
|
-
const result = new Material(canvas);
|
|
230
|
-
await result.deserialize(sceneData, relativePath, canvas);
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
private _canvas: Canvas | null;
|
|
235
|
-
private _type: string;
|
|
236
|
-
private _renderer: any;
|
|
237
|
-
private _alphaCutoff: number;
|
|
238
|
-
private _isTransparent: boolean;
|
|
239
|
-
private _albedo: Color;
|
|
240
|
-
private _albedoTexture: Texture | null;
|
|
241
|
-
private _albedoScale: Vec;
|
|
242
|
-
private _albedoUV: number;
|
|
243
|
-
private _normalTexture: Texture | null;
|
|
244
|
-
private _normalScale: Vec;
|
|
245
|
-
private _normalUV: number;
|
|
246
|
-
private _normalChannel: number;
|
|
247
|
-
private _metalness: number;
|
|
248
|
-
private _metalnessTexture: Texture | null;
|
|
249
|
-
private _metalnessChannel: number;
|
|
250
|
-
private _metalnessScale: Vec;
|
|
251
|
-
private _metalnessUV: number;
|
|
252
|
-
private _roughness: number;
|
|
253
|
-
private _roughnessTexture: Texture | null;
|
|
254
|
-
private _roughnessChannel: number;
|
|
255
|
-
private _roughnessScale: Vec;
|
|
256
|
-
private _roughnessUV: number;
|
|
257
|
-
private _fresnelTint: Color;
|
|
258
|
-
private _sheenIntensity: number;
|
|
259
|
-
private _sheenColor: Color;
|
|
260
|
-
private _lightEmission: Color | number;
|
|
261
|
-
private _lightEmissionTexture: Texture | null;
|
|
262
|
-
private _lightEmissionChannel: number;
|
|
263
|
-
private _lightEmissionScale: Vec;
|
|
264
|
-
private _lightEmissionUV: number;
|
|
265
|
-
private _ambientOcclussion: Texture | null;
|
|
266
|
-
private _ambientOcclussionChannel: number;
|
|
267
|
-
private _ambientOcclussionUV: number;
|
|
268
|
-
private _heightTexture: Texture | null;
|
|
269
|
-
private _heightChannel: number;
|
|
270
|
-
private _heightScale: Vec;
|
|
271
|
-
private _heightUV: number;
|
|
272
|
-
private _heightIntensity: number;
|
|
273
|
-
private _castShadows: boolean;
|
|
274
|
-
private _unlit: boolean;
|
|
275
|
-
private _dirty: boolean;
|
|
276
|
-
|
|
277
|
-
constructor(canvas: Canvas | null = null) {
|
|
278
|
-
this._canvas = canvas || Canvas.FirstCanvas();
|
|
279
|
-
this._type = MaterialType.PBR;
|
|
280
|
-
this._renderer = null;
|
|
281
|
-
|
|
282
|
-
this._alphaCutoff = 0.5;
|
|
283
|
-
this._isTransparent = false;
|
|
284
|
-
this._albedo = Color.White();
|
|
285
|
-
this._albedoTexture = null;
|
|
286
|
-
this._albedoScale = new Vec(1, 1);
|
|
287
|
-
this._albedoUV = 0;
|
|
288
|
-
this._normalTexture = null;
|
|
289
|
-
this._normalScale = new Vec(1, 1);
|
|
290
|
-
this._normalUV = 0;
|
|
291
|
-
this._normalChannel = 0;
|
|
292
|
-
this._metalness = 0;
|
|
293
|
-
this._metalnessTexture = null;
|
|
294
|
-
this._metalnessChannel = 0;
|
|
295
|
-
this._metalnessScale = new Vec(1, 1);
|
|
296
|
-
this._metalnessUV = 0;
|
|
297
|
-
this._roughness = 1;
|
|
298
|
-
this._roughnessTexture = null;
|
|
299
|
-
this._roughnessChannel = 0;
|
|
300
|
-
this._roughnessScale = new Vec(1, 1);
|
|
301
|
-
this._roughnessUV = 0;
|
|
302
|
-
this._fresnelTint = Color.White();
|
|
303
|
-
this._sheenIntensity = 0.0;
|
|
304
|
-
this._sheenColor = Color.White();
|
|
305
|
-
this._lightEmission = 0;
|
|
306
|
-
this._lightEmissionTexture = null;
|
|
307
|
-
this._lightEmissionChannel = 0;
|
|
308
|
-
this._lightEmissionScale = new Vec(1, 1);
|
|
309
|
-
this._lightEmissionUV = 0;
|
|
310
|
-
this._ambientOcclussion = null;
|
|
311
|
-
this._ambientOcclussionChannel = 0;
|
|
312
|
-
this._ambientOcclussionUV = 1;
|
|
313
|
-
this._heightTexture = null;
|
|
314
|
-
this._heightChannel = 0;
|
|
315
|
-
this._heightScale = new Vec(1, 1);
|
|
316
|
-
this._heightUV = 0;
|
|
317
|
-
this._heightIntensity = 1.0;
|
|
318
|
-
this._castShadows = true;
|
|
319
|
-
this._unlit = false;
|
|
320
|
-
|
|
321
|
-
this._dirty = true;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
get canvas(): Canvas | null {
|
|
325
|
-
return this._canvas;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
get renderer(): any {
|
|
329
|
-
return this._renderer;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
get dirty(): boolean {
|
|
333
|
-
return this._dirty;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
set dirty(d: boolean) {
|
|
337
|
-
this._dirty = d;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
clone(): Material {
|
|
341
|
-
const result = new Material();
|
|
342
|
-
result.assign(this);
|
|
343
|
-
return result;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
assign(other: Material): void {
|
|
347
|
-
this._type = other._type;
|
|
348
|
-
this._alphaCutoff = other._alphaCutoff;;
|
|
349
|
-
this._isTransparent = other._isTransparent;
|
|
350
|
-
this._albedo = cloneObject(other._albedo);
|
|
351
|
-
this._albedoTexture = cloneObject(other._albedoTexture);
|
|
352
|
-
this._albedoScale = cloneObject(other._albedoScale);
|
|
353
|
-
this._albedoUV = other._albedoUV;
|
|
354
|
-
this._normalTexture = cloneObject(other._normalTexture);
|
|
355
|
-
this._normalScale = cloneObject(other._normalScale);
|
|
356
|
-
this._normalUV = other._normalUV;
|
|
357
|
-
this._metalness = other._metalness;
|
|
358
|
-
this._metalnessTexture = cloneObject(other._metalnessTexture);
|
|
359
|
-
this._metalnessChannel = other._metalnessChannel;
|
|
360
|
-
this._metalnessScale = cloneObject(other._metalnessScale);
|
|
361
|
-
this._metalnessUV = other._metalnessUV;
|
|
362
|
-
this._roughness = other._roughness;
|
|
363
|
-
this._roughnessTexture = cloneObject(other._roughnessTexture);
|
|
364
|
-
this._roughnessChannel = other._roughnessChannel;
|
|
365
|
-
this._roughnessScale = cloneObject(other._roughnessScale);
|
|
366
|
-
this._roughnessUV = other._roughnessUV;
|
|
367
|
-
this._fresnelTint = cloneObject(other._fresnelTint);
|
|
368
|
-
this._sheenIntensity = other._sheenIntensity;
|
|
369
|
-
this._sheenColor = cloneObject(other._sheenColor);
|
|
370
|
-
this._lightEmission = other._lightEmission;
|
|
371
|
-
this._lightEmissionTexture = cloneObject(other._lightEmissionTexture);
|
|
372
|
-
this._lightEmissionChannel = other._lightEmissionChannel;
|
|
373
|
-
this._lightEmissionScale = cloneObject(other._lightEmissionScale);
|
|
374
|
-
this._lightEmissionUV = other._lightEmissionUV;
|
|
375
|
-
this._ambientOcclussion = other._ambientOcclussion;
|
|
376
|
-
this._ambientOcclussionChannel = other._ambientOcclussionChannel;
|
|
377
|
-
this._ambientOcclussionUV = other._ambientOcclussionUV;
|
|
378
|
-
this._heightTexture = cloneObject(other._heightTexture);
|
|
379
|
-
this._heightChannel = other._heightChannel;
|
|
380
|
-
this._heightScale = cloneObject(other._heightScale);
|
|
381
|
-
this._heightUV = other._heightUV;
|
|
382
|
-
this._heightIntensity = other._heightIntensity;
|
|
383
|
-
this._castShadows = other._castShadows;
|
|
384
|
-
this._unlit = other._unlit;
|
|
385
|
-
|
|
386
|
-
this._dirty = true;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
get type(): string { return this._type; }
|
|
390
|
-
set type(v: string) {
|
|
391
|
-
// Compatibility with v1.4
|
|
392
|
-
if (v === "PBRMaterial") {
|
|
393
|
-
v = "pbr";
|
|
394
|
-
}
|
|
395
|
-
this._type = v;
|
|
396
|
-
this._dirty = true;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
get albedo(): Color { return this._albedo; }
|
|
400
|
-
set albedo(v: Color) {
|
|
401
|
-
this._albedo = v;
|
|
402
|
-
this._dirty = true;
|
|
403
|
-
}
|
|
404
|
-
get albedoTexture(): Texture | null { return this._albedoTexture; }
|
|
405
|
-
set albedoTexture(v: Texture | null) {
|
|
406
|
-
v && assertTexture(v, "albedoTexture");
|
|
407
|
-
if (this._albedoTexture instanceof Texture) {
|
|
408
|
-
this._albedoTexture.decReferences();
|
|
409
|
-
}
|
|
410
|
-
this._albedoTexture = v;
|
|
411
|
-
if (this._albedoTexture instanceof Texture) {
|
|
412
|
-
this._albedoTexture.incReferences();
|
|
413
|
-
}
|
|
414
|
-
this._dirty = true;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
get albedoScale(): Vec { return this._albedoScale; }
|
|
418
|
-
set albedoScale(v: Vec) { assertScale(v, "albedoScale"); this._albedoScale = new Vec(v); this._dirty = true; }
|
|
419
|
-
get albedoUV(): number { return this._albedoUV; }
|
|
420
|
-
set albedoUV(v: number) { this._albedoUV = v; this._dirty = true; }
|
|
421
|
-
get alphaCutoff(): number { return this._alphaCutoff; }
|
|
422
|
-
set alphaCutoff(v: number) { this._alphaCutoff = v; this._dirty = true; }
|
|
423
|
-
get isTransparent(): boolean { return this._isTransparent; }
|
|
424
|
-
set isTransparent(v: boolean) { this._isTransparent = v; this._dirty = true; }
|
|
425
|
-
|
|
426
|
-
get normalTexture(): Texture | null { return this._normalTexture; }
|
|
427
|
-
set normalTexture(v: Texture | null) {
|
|
428
|
-
v && assertTexture(v, "normalTexture");
|
|
429
|
-
if (this._normalTexture instanceof Texture) {
|
|
430
|
-
this._normalTexture.decReferences();
|
|
431
|
-
}
|
|
432
|
-
this._normalTexture = v;
|
|
433
|
-
if (this._normalTexture instanceof Texture) {
|
|
434
|
-
this._normalTexture.incReferences();
|
|
435
|
-
}
|
|
436
|
-
this._dirty = true;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
get normalChannel(): number { return this._normalChannel; }
|
|
440
|
-
set normalChannel(v: number) { this._normalChannel = v; this._dirty = true; }
|
|
441
|
-
get normalScale(): Vec { return this._normalScale; }
|
|
442
|
-
set normalScale(v: Vec) { assertScale(v, "normalScale"); this._normalScale = new Vec(v); this._dirty = true; }
|
|
443
|
-
get normalUV(): number { return this._normalUV; }
|
|
444
|
-
set normalUV(v: number) { this._normalUV = v; this._dirty = true; }
|
|
445
|
-
|
|
446
|
-
get metalness(): number { return this._metalness; }
|
|
447
|
-
set metalness(v: number) {
|
|
448
|
-
this._metalness = v;
|
|
449
|
-
this._dirty = true;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
get metalnessTexture(): Texture | null { return this._metalnessTexture; }
|
|
453
|
-
set metalnessTexture(v: Texture | null) {
|
|
454
|
-
v && assertTexture(v, "metalness");
|
|
455
|
-
if (this._metalnessTexture instanceof Texture) {
|
|
456
|
-
this._metalnessTexture.decReferences();
|
|
457
|
-
}
|
|
458
|
-
this._metalnessTexture = v;
|
|
459
|
-
if (this._metalnessTexture instanceof Texture) {
|
|
460
|
-
this._metalnessTexture.incReferences();
|
|
461
|
-
}
|
|
462
|
-
this._dirty = true;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
get metalnessChannel(): number { return this._metalnessChannel; }
|
|
466
|
-
set metalnessChannel(v: number) { this._metalnessChannel = v; this._dirty = true; }
|
|
467
|
-
get metalnessScale(): Vec { return this._metalnessScale; }
|
|
468
|
-
set metalnessScale(v: Vec) { assertScale(v, "metalnessScale"); this._metalnessScale = new Vec(v); this._dirty = true; }
|
|
469
|
-
get metalnessUV(): number { return this._metalnessUV; }
|
|
470
|
-
set metalnessUV(v: number) { this._metalnessUV = v; this._dirty = true; }
|
|
471
|
-
|
|
472
|
-
get roughness(): number { return this._roughness; }
|
|
473
|
-
set roughness(v: number) {
|
|
474
|
-
this._roughness = v;
|
|
475
|
-
this._dirty = true;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
get roughnessTexture(): Texture | null { return this._roughnessTexture; }
|
|
479
|
-
set roughnessTexture (v: Texture | null) {
|
|
480
|
-
v && assertTexture(v, "roughness");
|
|
481
|
-
if (this._roughnessTexture instanceof Texture) {
|
|
482
|
-
this._roughnessTexture.decReferences();
|
|
483
|
-
}
|
|
484
|
-
this._roughnessTexture = v;
|
|
485
|
-
if (this._roughnessTexture instanceof Texture) {
|
|
486
|
-
this._roughnessTexture.incReferences();
|
|
487
|
-
}
|
|
488
|
-
this._dirty = true;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
get roughnessChannel(): number { return this._roughnessChannel; }
|
|
492
|
-
set roughnessChannel(v: number) { this._roughnessChannel = v; this._dirty = true; }
|
|
493
|
-
get roughnessScale(): Vec { return this._roughnessScale; }
|
|
494
|
-
set roughnessScale(v: Vec) { assertScale(v, "roughnessScale"); this._roughnessScale = new Vec(v); this._dirty = true; }
|
|
495
|
-
get roughnessUV(): number { return this._roughnessUV; }
|
|
496
|
-
set roughnessUV(v: number) { this._roughnessUV = v; this._dirty = true; }
|
|
497
|
-
|
|
498
|
-
get fresnelTint(): Color { return this._fresnelTint; }
|
|
499
|
-
set fresnelTint(v: Color) { assertColor(v, "fresnelTint"); this._fresnelTint = v; this._dirty = true; }
|
|
500
|
-
get sheenIntensity(): number { return this._sheenIntensity; }
|
|
501
|
-
set sheenIntensity(v: number) { this._sheenIntensity = v; this._dirty = true; }
|
|
502
|
-
get sheenColor(): Color { return this._sheenColor; }
|
|
503
|
-
set sheenColor(v: Color) { assertColor(v, "sheenColor"); this._sheenColor = v; this._dirty = true; }
|
|
504
|
-
|
|
505
|
-
get lightEmission(): Color | number { return this._lightEmission; }
|
|
506
|
-
set lightEmission(v: Color | number) {
|
|
507
|
-
if (typeof v === "number") {
|
|
508
|
-
v = new Color([v, v, v, 1]);
|
|
509
|
-
}
|
|
510
|
-
assertColor(v, "lightEmission"); this._lightEmission = v; this._dirty = true;
|
|
511
|
-
}
|
|
512
|
-
get lightEmissionTexture(): Texture | null { return this._lightEmissionTexture; }
|
|
513
|
-
set lightEmissionTexture(v: Texture | null) {
|
|
514
|
-
v && assertTexture(v, 'lightEmissionTexture');
|
|
515
|
-
if (this._lightEmissionTexture instanceof Texture) {
|
|
516
|
-
this._lightEmissionTexture.decReferences();
|
|
517
|
-
}
|
|
518
|
-
this._lightEmissionTexture = v;
|
|
519
|
-
if (this._lightEmissionTexture instanceof Texture) {
|
|
520
|
-
this._lightEmissionTexture.incReferences();
|
|
521
|
-
}
|
|
522
|
-
this._dirty = true;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
get lightEmissionChannel(): number { return this._lightEmissionChannel; }
|
|
526
|
-
set lightEmissionChannel(v: number) { this._lightEmissionChannel = v; this._dirty = true; }
|
|
527
|
-
get lightEmissionScale(): Vec { return this._lightEmissionScale; }
|
|
528
|
-
set lightEmissionScale(v: Vec) { assertScale(v, "lightEmissionScale"); this._lightEmissionScale = new Vec(v); this._dirty = true; }
|
|
529
|
-
get lightEmissionUV(): number { return this._lightEmissionUV; }
|
|
530
|
-
set lightEmissionUV(v: number) { this._lightEmissionUV = v; this._dirty = true; }
|
|
531
|
-
|
|
532
|
-
get ambientOcclussion(): Texture | null { return this._ambientOcclussion; }
|
|
533
|
-
set ambientOcclussion(v: Texture | null) {
|
|
534
|
-
v && assertTexture(v, "ambientOcclussion");
|
|
535
|
-
if (this._ambientOcclussion instanceof Texture) {
|
|
536
|
-
this._ambientOcclussion.decReferences();
|
|
537
|
-
}
|
|
538
|
-
this._ambientOcclussion = v;
|
|
539
|
-
if (this._ambientOcclussion instanceof Texture) {
|
|
540
|
-
this._ambientOcclussion.incReferences();
|
|
541
|
-
}
|
|
542
|
-
this._dirty = true;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
get ambientOcclussionChannel(): number { return this._ambientOcclussionChannel; }
|
|
546
|
-
set ambientOcclussionChannel(v: number) { this._ambientOcclussionChannel = v; this._dirty = true; }
|
|
547
|
-
get ambientOcclussionUV(): number { return this._ambientOcclussionUV; }
|
|
548
|
-
set ambientOcclussionUV(v: number) { this._ambientOcclussionUV = v; this._dirty = true; }
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
get heightTexture(): Texture | null { return this._heightTexture; }
|
|
553
|
-
set heightTexture(v: Texture | null) { assertTexture(v, "heightTexture"); this._heightTexture = v; this._dirty = true; }
|
|
554
|
-
get heightChannel(): number { return this._heightChannel; }
|
|
555
|
-
set heightChannel(v: number) { this._heightChannel = v; this._dirty = true; }
|
|
556
|
-
get heightScale(): Vec { return this._heightScale; }
|
|
557
|
-
set heightScale(v: Vec) { assertScale(v, "heightScale"); this._heightScale = new Vec(v); this._dirty = true; }
|
|
558
|
-
get heightUV(): number { return this._heightUV; }
|
|
559
|
-
set heightUV(v: number) { this._heightUV = v; this._dirty = true; }
|
|
560
|
-
get heightIntensity(): number { return this._heightIntensity; }
|
|
561
|
-
set heightIntensity(v: number) { this._heightIntensity = v; this._dirty = true; }
|
|
562
|
-
get castShadows(): boolean { return this._castShadows; }
|
|
563
|
-
set castShadows(v: boolean) { this._castShadows = v; this._dirty = true; }
|
|
564
|
-
get unlit(): boolean { return this._unlit; }
|
|
565
|
-
set unlit(v: boolean) { this._unlit = v; this._dirty = true; }
|
|
566
|
-
|
|
567
|
-
async serialize(sceneData: any): Promise<void> {
|
|
568
|
-
for (const att in MaterialAttributeNames) {
|
|
569
|
-
const value = MaterialAttributeNames[att].loader.serialize(att, (this as any)[att]);
|
|
570
|
-
if (value) {
|
|
571
|
-
sceneData[att] = value;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
async deserialize(sceneData: any, relativePath: string, canvas?: Canvas | null): Promise<void> {
|
|
577
|
-
const P: Promise<any>[] = [];
|
|
578
|
-
|
|
579
|
-
this.type = sceneData.type || MaterialType.PBR;
|
|
580
|
-
this.alphaCutoff = sceneData.alphaCutoff || 0.5;
|
|
581
|
-
this.isTransparent = sceneData.isTransparent || false;
|
|
582
|
-
|
|
583
|
-
for (const attName in MaterialAttributeNames) {
|
|
584
|
-
const loader = MaterialAttributeNames[attName]?.loader;
|
|
585
|
-
if (loader) {
|
|
586
|
-
const value = loader.deserialize(attName, sceneData[attName], relativePath, this.canvas);
|
|
587
|
-
if (value instanceof Texture) {
|
|
588
|
-
P.push(value.loadImageData());
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
if (value !== null && value !== undefined) {
|
|
592
|
-
(this as any)[attName] = value;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
await Promise.all(P);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
destroy(): void {
|
|
600
|
-
const decReferences = (attrib: string) => {
|
|
601
|
-
if ((this as any)[attrib] instanceof Texture) {
|
|
602
|
-
(this as any)[attrib].decReferences();
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
decReferences("albedoTexture");
|
|
607
|
-
decReferences("normalTexture");
|
|
608
|
-
decReferences("metalnessTexture");
|
|
609
|
-
decReferences("roughnessTexture");
|
|
610
|
-
decReferences("lightEmissionTexture");
|
|
611
|
-
decReferences("ambientOcclussion");
|
|
612
|
-
decReferences("height");
|
|
613
|
-
|
|
614
|
-
this._canvas = null;
|
|
615
|
-
|
|
616
|
-
if (this.renderer) {
|
|
617
|
-
this.renderer.destroy();
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
}
|
|
1
|
+
|
|
2
|
+
import Vec from '../math/Vec';
|
|
3
|
+
import Color from './Color';
|
|
4
|
+
import Texture, { TextureDataType, TextureFilter, TextureWrap } from './Texture';
|
|
5
|
+
import Canvas from '../app/Canvas';
|
|
6
|
+
import TextureCache from '../tools/TextureCache';
|
|
7
|
+
import { NumericArray } from '../math/constants';
|
|
8
|
+
|
|
9
|
+
export enum MaterialType {
|
|
10
|
+
PBR = "pbr"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface TypeLoader {
|
|
14
|
+
serialize: (attName: string, obj: any) => any;
|
|
15
|
+
deserialize: (attName: string, obj: any, relativePath?: string, canvas?: Canvas | null) => any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const textureTypeLoader: TypeLoader = {
|
|
19
|
+
serialize: (attName: string, obj: any) => {
|
|
20
|
+
if (!obj) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (obj instanceof Texture) {
|
|
24
|
+
return obj.fileName;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Texture`);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
deserialize: (attName: string, obj: any, relativePath: string = "", canvas: Canvas | null = null) => {
|
|
32
|
+
if (!obj) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
else if (attName === "ambientOcclussion" && typeof(obj) === "number") {
|
|
36
|
+
// Compatibility with v1.4 where ambient occlussion could be a float value
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
else if (typeof(obj) === "string") {
|
|
40
|
+
const texturePath = relativePath + obj;
|
|
41
|
+
const textureCache = TextureCache.Get(canvas);
|
|
42
|
+
if (textureCache.findTexture(texturePath)) {
|
|
43
|
+
console.debug(`Texture '${ texturePath }' already loaded. Reusing texture.`);
|
|
44
|
+
return textureCache.getTexture(texturePath);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log(`Texture not found in cache. Loading texture '${ texturePath }'`);
|
|
48
|
+
const tex = new Texture(canvas);
|
|
49
|
+
tex.fileName = relativePath + obj;
|
|
50
|
+
tex.dataType = TextureDataType.IMAGE;
|
|
51
|
+
tex.minFilter = TextureFilter.LINEAR_MIPMAP_LINEAR;
|
|
52
|
+
tex.magFilter = TextureFilter.LINEAR;
|
|
53
|
+
tex.wrapModeX = TextureWrap.REPEAT;
|
|
54
|
+
tex.wrapModeY = TextureWrap.REPEAT;
|
|
55
|
+
textureCache.registerTexture(tex);
|
|
56
|
+
return tex;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is string (file path)`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const colorTypeLoader: TypeLoader = {
|
|
66
|
+
serialize: (attName: string, obj: any) => {
|
|
67
|
+
if (!obj) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (obj instanceof Color) {
|
|
72
|
+
return obj;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Color`);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
deserialize: (attName: string, obj: any) => {
|
|
80
|
+
if (!obj) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
else if ((Array.isArray(obj) || obj instanceof NumericArray) &&
|
|
84
|
+
(obj.length === 3 || obj.length === 4)
|
|
85
|
+
) {
|
|
86
|
+
if (obj.length === 3) {
|
|
87
|
+
return new Color([obj[0], obj[1], obj[2], 1]);
|
|
88
|
+
}
|
|
89
|
+
else if (obj.length === 4) {
|
|
90
|
+
return new Color([obj[0], obj[1], obj[2], obj[3]]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is array with 3 or 4 elements`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const vectorTypeLoader: TypeLoader = {
|
|
100
|
+
serialize: (attName: string, obj: any) => {
|
|
101
|
+
if (!obj) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (obj instanceof Vec) {
|
|
106
|
+
return obj;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw new Error(`Invalid parameter found in material serialization. The required parameter type is Vec`);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
deserialize: (attName: string, obj: any) => {
|
|
114
|
+
if (!obj) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
else if (obj.length >= 2 && obj.length <= 4) {
|
|
118
|
+
return new Vec(obj);
|
|
119
|
+
}
|
|
120
|
+
// Retrocompatibility with v1.4
|
|
121
|
+
else if (obj._v && obj._v.length >= 2 && obj._v.length <= 4) {
|
|
122
|
+
return new Vec(obj._v);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
throw new Error(`Invalid parameter found in material deserialization. The required parameter type is array with 2, 3 or 4 elements`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const primitiveTypeLoader: TypeLoader = {
|
|
131
|
+
serialize: (attName: string, obj: any) => {
|
|
132
|
+
if (!obj) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return obj;
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
deserialize: (attName: string, obj: any) => {
|
|
140
|
+
return obj;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface MaterialAttribute {
|
|
145
|
+
loader: TypeLoader;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const MaterialAttributeNames: { [key: string]: MaterialAttribute } = {
|
|
149
|
+
type: { loader: primitiveTypeLoader },
|
|
150
|
+
alphaCutoff: { loader: primitiveTypeLoader },
|
|
151
|
+
isTransparent: { loader: primitiveTypeLoader },
|
|
152
|
+
albedo: { loader: colorTypeLoader },
|
|
153
|
+
albedoTexture: { loader: textureTypeLoader },
|
|
154
|
+
albedoScale: { loader: vectorTypeLoader },
|
|
155
|
+
albedoUV: { loader: primitiveTypeLoader },
|
|
156
|
+
normalTexture: { loader: textureTypeLoader },
|
|
157
|
+
normalScale: { loader: vectorTypeLoader },
|
|
158
|
+
normalUV: { loader: primitiveTypeLoader },
|
|
159
|
+
metalness: { loader: primitiveTypeLoader },
|
|
160
|
+
metalnessTexture: { loader: textureTypeLoader },
|
|
161
|
+
metalnessChannel: { loader: primitiveTypeLoader },
|
|
162
|
+
metalnessScale: { loader: vectorTypeLoader },
|
|
163
|
+
metalnessUV: { loader: primitiveTypeLoader },
|
|
164
|
+
roughness: { loader: primitiveTypeLoader },
|
|
165
|
+
roughnessTexture: { loader: textureTypeLoader },
|
|
166
|
+
roughnessChannel: { loader: primitiveTypeLoader },
|
|
167
|
+
roughnessScale: { loader: vectorTypeLoader },
|
|
168
|
+
roughnessUV: { loader: primitiveTypeLoader },
|
|
169
|
+
fresnelTint: { loader: colorTypeLoader },
|
|
170
|
+
sheenIntensity: { loader: primitiveTypeLoader },
|
|
171
|
+
sheenColor: { loader: colorTypeLoader },
|
|
172
|
+
lightEmission: { loader: colorTypeLoader },
|
|
173
|
+
lightEmissionTexture: { loader: textureTypeLoader },
|
|
174
|
+
lightEmissionChannel: { loader: primitiveTypeLoader },
|
|
175
|
+
lightEmissionScale: { loader: vectorTypeLoader },
|
|
176
|
+
lightEmissionUV: { loader: primitiveTypeLoader },
|
|
177
|
+
ambientOcclussion: { loader: textureTypeLoader },
|
|
178
|
+
ambientOcclussionChannel: { loader: primitiveTypeLoader },
|
|
179
|
+
ambientOcclussionUV: { loader: primitiveTypeLoader },
|
|
180
|
+
heightTexture: { loader: textureTypeLoader },
|
|
181
|
+
heightChannel: { loader: primitiveTypeLoader },
|
|
182
|
+
heightScale: { loader: vectorTypeLoader },
|
|
183
|
+
heightUV: { loader: primitiveTypeLoader },
|
|
184
|
+
heightIntensity: { loader: primitiveTypeLoader },
|
|
185
|
+
castShadows: { loader: primitiveTypeLoader },
|
|
186
|
+
unlit: { loader: primitiveTypeLoader }
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const assertTexture = (v: any, name: string): void => {
|
|
190
|
+
if (!(v instanceof Texture)) {
|
|
191
|
+
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Texture`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export const assertColor = (v: any, name: string): void => {
|
|
196
|
+
if (!(v instanceof Color)) {
|
|
197
|
+
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Color`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export const assertScale = (v: any, name: string): void => {
|
|
202
|
+
if (!(v instanceof Vec) || v.length != 2) {
|
|
203
|
+
throw new Error(`Invalid parameter setting '${ name }' material attribute. The required parameter type is Vec with two elements.`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Clone the `obj` parameter if it is
|
|
208
|
+
// - Vec
|
|
209
|
+
// - Color
|
|
210
|
+
// - Texture
|
|
211
|
+
// Returns the same parameter if not
|
|
212
|
+
export const cloneObject = (obj: any): any => {
|
|
213
|
+
if (obj instanceof Color) {
|
|
214
|
+
return new Color(obj);
|
|
215
|
+
}
|
|
216
|
+
else if (obj instanceof Vec) {
|
|
217
|
+
return new Vec(obj);
|
|
218
|
+
}
|
|
219
|
+
else if (obj instanceof Texture) {
|
|
220
|
+
return obj.clone();
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return obj;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export default class Material {
|
|
228
|
+
static async Deserialize(sceneData: any, relativePath: string = "", canvas: Canvas | null = null): Promise<Material> {
|
|
229
|
+
const result = new Material(canvas);
|
|
230
|
+
await result.deserialize(sceneData, relativePath, canvas);
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private _canvas: Canvas | null;
|
|
235
|
+
private _type: string;
|
|
236
|
+
private _renderer: any;
|
|
237
|
+
private _alphaCutoff: number;
|
|
238
|
+
private _isTransparent: boolean;
|
|
239
|
+
private _albedo: Color;
|
|
240
|
+
private _albedoTexture: Texture | null;
|
|
241
|
+
private _albedoScale: Vec;
|
|
242
|
+
private _albedoUV: number;
|
|
243
|
+
private _normalTexture: Texture | null;
|
|
244
|
+
private _normalScale: Vec;
|
|
245
|
+
private _normalUV: number;
|
|
246
|
+
private _normalChannel: number;
|
|
247
|
+
private _metalness: number;
|
|
248
|
+
private _metalnessTexture: Texture | null;
|
|
249
|
+
private _metalnessChannel: number;
|
|
250
|
+
private _metalnessScale: Vec;
|
|
251
|
+
private _metalnessUV: number;
|
|
252
|
+
private _roughness: number;
|
|
253
|
+
private _roughnessTexture: Texture | null;
|
|
254
|
+
private _roughnessChannel: number;
|
|
255
|
+
private _roughnessScale: Vec;
|
|
256
|
+
private _roughnessUV: number;
|
|
257
|
+
private _fresnelTint: Color;
|
|
258
|
+
private _sheenIntensity: number;
|
|
259
|
+
private _sheenColor: Color;
|
|
260
|
+
private _lightEmission: Color | number;
|
|
261
|
+
private _lightEmissionTexture: Texture | null;
|
|
262
|
+
private _lightEmissionChannel: number;
|
|
263
|
+
private _lightEmissionScale: Vec;
|
|
264
|
+
private _lightEmissionUV: number;
|
|
265
|
+
private _ambientOcclussion: Texture | null;
|
|
266
|
+
private _ambientOcclussionChannel: number;
|
|
267
|
+
private _ambientOcclussionUV: number;
|
|
268
|
+
private _heightTexture: Texture | null;
|
|
269
|
+
private _heightChannel: number;
|
|
270
|
+
private _heightScale: Vec;
|
|
271
|
+
private _heightUV: number;
|
|
272
|
+
private _heightIntensity: number;
|
|
273
|
+
private _castShadows: boolean;
|
|
274
|
+
private _unlit: boolean;
|
|
275
|
+
private _dirty: boolean;
|
|
276
|
+
|
|
277
|
+
constructor(canvas: Canvas | null = null) {
|
|
278
|
+
this._canvas = canvas || Canvas.FirstCanvas();
|
|
279
|
+
this._type = MaterialType.PBR;
|
|
280
|
+
this._renderer = null;
|
|
281
|
+
|
|
282
|
+
this._alphaCutoff = 0.5;
|
|
283
|
+
this._isTransparent = false;
|
|
284
|
+
this._albedo = Color.White();
|
|
285
|
+
this._albedoTexture = null;
|
|
286
|
+
this._albedoScale = new Vec(1, 1);
|
|
287
|
+
this._albedoUV = 0;
|
|
288
|
+
this._normalTexture = null;
|
|
289
|
+
this._normalScale = new Vec(1, 1);
|
|
290
|
+
this._normalUV = 0;
|
|
291
|
+
this._normalChannel = 0;
|
|
292
|
+
this._metalness = 0;
|
|
293
|
+
this._metalnessTexture = null;
|
|
294
|
+
this._metalnessChannel = 0;
|
|
295
|
+
this._metalnessScale = new Vec(1, 1);
|
|
296
|
+
this._metalnessUV = 0;
|
|
297
|
+
this._roughness = 1;
|
|
298
|
+
this._roughnessTexture = null;
|
|
299
|
+
this._roughnessChannel = 0;
|
|
300
|
+
this._roughnessScale = new Vec(1, 1);
|
|
301
|
+
this._roughnessUV = 0;
|
|
302
|
+
this._fresnelTint = Color.White();
|
|
303
|
+
this._sheenIntensity = 0.0;
|
|
304
|
+
this._sheenColor = Color.White();
|
|
305
|
+
this._lightEmission = 0;
|
|
306
|
+
this._lightEmissionTexture = null;
|
|
307
|
+
this._lightEmissionChannel = 0;
|
|
308
|
+
this._lightEmissionScale = new Vec(1, 1);
|
|
309
|
+
this._lightEmissionUV = 0;
|
|
310
|
+
this._ambientOcclussion = null;
|
|
311
|
+
this._ambientOcclussionChannel = 0;
|
|
312
|
+
this._ambientOcclussionUV = 1;
|
|
313
|
+
this._heightTexture = null;
|
|
314
|
+
this._heightChannel = 0;
|
|
315
|
+
this._heightScale = new Vec(1, 1);
|
|
316
|
+
this._heightUV = 0;
|
|
317
|
+
this._heightIntensity = 1.0;
|
|
318
|
+
this._castShadows = true;
|
|
319
|
+
this._unlit = false;
|
|
320
|
+
|
|
321
|
+
this._dirty = true;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
get canvas(): Canvas | null {
|
|
325
|
+
return this._canvas;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
get renderer(): any {
|
|
329
|
+
return this._renderer;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
get dirty(): boolean {
|
|
333
|
+
return this._dirty;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
set dirty(d: boolean) {
|
|
337
|
+
this._dirty = d;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
clone(): Material {
|
|
341
|
+
const result = new Material();
|
|
342
|
+
result.assign(this);
|
|
343
|
+
return result;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
assign(other: Material): void {
|
|
347
|
+
this._type = other._type;
|
|
348
|
+
this._alphaCutoff = other._alphaCutoff;;
|
|
349
|
+
this._isTransparent = other._isTransparent;
|
|
350
|
+
this._albedo = cloneObject(other._albedo);
|
|
351
|
+
this._albedoTexture = cloneObject(other._albedoTexture);
|
|
352
|
+
this._albedoScale = cloneObject(other._albedoScale);
|
|
353
|
+
this._albedoUV = other._albedoUV;
|
|
354
|
+
this._normalTexture = cloneObject(other._normalTexture);
|
|
355
|
+
this._normalScale = cloneObject(other._normalScale);
|
|
356
|
+
this._normalUV = other._normalUV;
|
|
357
|
+
this._metalness = other._metalness;
|
|
358
|
+
this._metalnessTexture = cloneObject(other._metalnessTexture);
|
|
359
|
+
this._metalnessChannel = other._metalnessChannel;
|
|
360
|
+
this._metalnessScale = cloneObject(other._metalnessScale);
|
|
361
|
+
this._metalnessUV = other._metalnessUV;
|
|
362
|
+
this._roughness = other._roughness;
|
|
363
|
+
this._roughnessTexture = cloneObject(other._roughnessTexture);
|
|
364
|
+
this._roughnessChannel = other._roughnessChannel;
|
|
365
|
+
this._roughnessScale = cloneObject(other._roughnessScale);
|
|
366
|
+
this._roughnessUV = other._roughnessUV;
|
|
367
|
+
this._fresnelTint = cloneObject(other._fresnelTint);
|
|
368
|
+
this._sheenIntensity = other._sheenIntensity;
|
|
369
|
+
this._sheenColor = cloneObject(other._sheenColor);
|
|
370
|
+
this._lightEmission = other._lightEmission;
|
|
371
|
+
this._lightEmissionTexture = cloneObject(other._lightEmissionTexture);
|
|
372
|
+
this._lightEmissionChannel = other._lightEmissionChannel;
|
|
373
|
+
this._lightEmissionScale = cloneObject(other._lightEmissionScale);
|
|
374
|
+
this._lightEmissionUV = other._lightEmissionUV;
|
|
375
|
+
this._ambientOcclussion = other._ambientOcclussion;
|
|
376
|
+
this._ambientOcclussionChannel = other._ambientOcclussionChannel;
|
|
377
|
+
this._ambientOcclussionUV = other._ambientOcclussionUV;
|
|
378
|
+
this._heightTexture = cloneObject(other._heightTexture);
|
|
379
|
+
this._heightChannel = other._heightChannel;
|
|
380
|
+
this._heightScale = cloneObject(other._heightScale);
|
|
381
|
+
this._heightUV = other._heightUV;
|
|
382
|
+
this._heightIntensity = other._heightIntensity;
|
|
383
|
+
this._castShadows = other._castShadows;
|
|
384
|
+
this._unlit = other._unlit;
|
|
385
|
+
|
|
386
|
+
this._dirty = true;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
get type(): string { return this._type; }
|
|
390
|
+
set type(v: string) {
|
|
391
|
+
// Compatibility with v1.4
|
|
392
|
+
if (v === "PBRMaterial") {
|
|
393
|
+
v = "pbr";
|
|
394
|
+
}
|
|
395
|
+
this._type = v;
|
|
396
|
+
this._dirty = true;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
get albedo(): Color { return this._albedo; }
|
|
400
|
+
set albedo(v: Color) {
|
|
401
|
+
this._albedo = v;
|
|
402
|
+
this._dirty = true;
|
|
403
|
+
}
|
|
404
|
+
get albedoTexture(): Texture | null { return this._albedoTexture; }
|
|
405
|
+
set albedoTexture(v: Texture | null) {
|
|
406
|
+
v && assertTexture(v, "albedoTexture");
|
|
407
|
+
if (this._albedoTexture instanceof Texture) {
|
|
408
|
+
this._albedoTexture.decReferences();
|
|
409
|
+
}
|
|
410
|
+
this._albedoTexture = v;
|
|
411
|
+
if (this._albedoTexture instanceof Texture) {
|
|
412
|
+
this._albedoTexture.incReferences();
|
|
413
|
+
}
|
|
414
|
+
this._dirty = true;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
get albedoScale(): Vec { return this._albedoScale; }
|
|
418
|
+
set albedoScale(v: Vec) { assertScale(v, "albedoScale"); this._albedoScale = new Vec(v); this._dirty = true; }
|
|
419
|
+
get albedoUV(): number { return this._albedoUV; }
|
|
420
|
+
set albedoUV(v: number) { this._albedoUV = v; this._dirty = true; }
|
|
421
|
+
get alphaCutoff(): number { return this._alphaCutoff; }
|
|
422
|
+
set alphaCutoff(v: number) { this._alphaCutoff = v; this._dirty = true; }
|
|
423
|
+
get isTransparent(): boolean { return this._isTransparent; }
|
|
424
|
+
set isTransparent(v: boolean) { this._isTransparent = v; this._dirty = true; }
|
|
425
|
+
|
|
426
|
+
get normalTexture(): Texture | null { return this._normalTexture; }
|
|
427
|
+
set normalTexture(v: Texture | null) {
|
|
428
|
+
v && assertTexture(v, "normalTexture");
|
|
429
|
+
if (this._normalTexture instanceof Texture) {
|
|
430
|
+
this._normalTexture.decReferences();
|
|
431
|
+
}
|
|
432
|
+
this._normalTexture = v;
|
|
433
|
+
if (this._normalTexture instanceof Texture) {
|
|
434
|
+
this._normalTexture.incReferences();
|
|
435
|
+
}
|
|
436
|
+
this._dirty = true;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
get normalChannel(): number { return this._normalChannel; }
|
|
440
|
+
set normalChannel(v: number) { this._normalChannel = v; this._dirty = true; }
|
|
441
|
+
get normalScale(): Vec { return this._normalScale; }
|
|
442
|
+
set normalScale(v: Vec) { assertScale(v, "normalScale"); this._normalScale = new Vec(v); this._dirty = true; }
|
|
443
|
+
get normalUV(): number { return this._normalUV; }
|
|
444
|
+
set normalUV(v: number) { this._normalUV = v; this._dirty = true; }
|
|
445
|
+
|
|
446
|
+
get metalness(): number { return this._metalness; }
|
|
447
|
+
set metalness(v: number) {
|
|
448
|
+
this._metalness = v;
|
|
449
|
+
this._dirty = true;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
get metalnessTexture(): Texture | null { return this._metalnessTexture; }
|
|
453
|
+
set metalnessTexture(v: Texture | null) {
|
|
454
|
+
v && assertTexture(v, "metalness");
|
|
455
|
+
if (this._metalnessTexture instanceof Texture) {
|
|
456
|
+
this._metalnessTexture.decReferences();
|
|
457
|
+
}
|
|
458
|
+
this._metalnessTexture = v;
|
|
459
|
+
if (this._metalnessTexture instanceof Texture) {
|
|
460
|
+
this._metalnessTexture.incReferences();
|
|
461
|
+
}
|
|
462
|
+
this._dirty = true;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
get metalnessChannel(): number { return this._metalnessChannel; }
|
|
466
|
+
set metalnessChannel(v: number) { this._metalnessChannel = v; this._dirty = true; }
|
|
467
|
+
get metalnessScale(): Vec { return this._metalnessScale; }
|
|
468
|
+
set metalnessScale(v: Vec) { assertScale(v, "metalnessScale"); this._metalnessScale = new Vec(v); this._dirty = true; }
|
|
469
|
+
get metalnessUV(): number { return this._metalnessUV; }
|
|
470
|
+
set metalnessUV(v: number) { this._metalnessUV = v; this._dirty = true; }
|
|
471
|
+
|
|
472
|
+
get roughness(): number { return this._roughness; }
|
|
473
|
+
set roughness(v: number) {
|
|
474
|
+
this._roughness = v;
|
|
475
|
+
this._dirty = true;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
get roughnessTexture(): Texture | null { return this._roughnessTexture; }
|
|
479
|
+
set roughnessTexture (v: Texture | null) {
|
|
480
|
+
v && assertTexture(v, "roughness");
|
|
481
|
+
if (this._roughnessTexture instanceof Texture) {
|
|
482
|
+
this._roughnessTexture.decReferences();
|
|
483
|
+
}
|
|
484
|
+
this._roughnessTexture = v;
|
|
485
|
+
if (this._roughnessTexture instanceof Texture) {
|
|
486
|
+
this._roughnessTexture.incReferences();
|
|
487
|
+
}
|
|
488
|
+
this._dirty = true;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
get roughnessChannel(): number { return this._roughnessChannel; }
|
|
492
|
+
set roughnessChannel(v: number) { this._roughnessChannel = v; this._dirty = true; }
|
|
493
|
+
get roughnessScale(): Vec { return this._roughnessScale; }
|
|
494
|
+
set roughnessScale(v: Vec) { assertScale(v, "roughnessScale"); this._roughnessScale = new Vec(v); this._dirty = true; }
|
|
495
|
+
get roughnessUV(): number { return this._roughnessUV; }
|
|
496
|
+
set roughnessUV(v: number) { this._roughnessUV = v; this._dirty = true; }
|
|
497
|
+
|
|
498
|
+
get fresnelTint(): Color { return this._fresnelTint; }
|
|
499
|
+
set fresnelTint(v: Color) { assertColor(v, "fresnelTint"); this._fresnelTint = v; this._dirty = true; }
|
|
500
|
+
get sheenIntensity(): number { return this._sheenIntensity; }
|
|
501
|
+
set sheenIntensity(v: number) { this._sheenIntensity = v; this._dirty = true; }
|
|
502
|
+
get sheenColor(): Color { return this._sheenColor; }
|
|
503
|
+
set sheenColor(v: Color) { assertColor(v, "sheenColor"); this._sheenColor = v; this._dirty = true; }
|
|
504
|
+
|
|
505
|
+
get lightEmission(): Color | number { return this._lightEmission; }
|
|
506
|
+
set lightEmission(v: Color | number) {
|
|
507
|
+
if (typeof v === "number") {
|
|
508
|
+
v = new Color([v, v, v, 1]);
|
|
509
|
+
}
|
|
510
|
+
assertColor(v, "lightEmission"); this._lightEmission = v; this._dirty = true;
|
|
511
|
+
}
|
|
512
|
+
get lightEmissionTexture(): Texture | null { return this._lightEmissionTexture; }
|
|
513
|
+
set lightEmissionTexture(v: Texture | null) {
|
|
514
|
+
v && assertTexture(v, 'lightEmissionTexture');
|
|
515
|
+
if (this._lightEmissionTexture instanceof Texture) {
|
|
516
|
+
this._lightEmissionTexture.decReferences();
|
|
517
|
+
}
|
|
518
|
+
this._lightEmissionTexture = v;
|
|
519
|
+
if (this._lightEmissionTexture instanceof Texture) {
|
|
520
|
+
this._lightEmissionTexture.incReferences();
|
|
521
|
+
}
|
|
522
|
+
this._dirty = true;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
get lightEmissionChannel(): number { return this._lightEmissionChannel; }
|
|
526
|
+
set lightEmissionChannel(v: number) { this._lightEmissionChannel = v; this._dirty = true; }
|
|
527
|
+
get lightEmissionScale(): Vec { return this._lightEmissionScale; }
|
|
528
|
+
set lightEmissionScale(v: Vec) { assertScale(v, "lightEmissionScale"); this._lightEmissionScale = new Vec(v); this._dirty = true; }
|
|
529
|
+
get lightEmissionUV(): number { return this._lightEmissionUV; }
|
|
530
|
+
set lightEmissionUV(v: number) { this._lightEmissionUV = v; this._dirty = true; }
|
|
531
|
+
|
|
532
|
+
get ambientOcclussion(): Texture | null { return this._ambientOcclussion; }
|
|
533
|
+
set ambientOcclussion(v: Texture | null) {
|
|
534
|
+
v && assertTexture(v, "ambientOcclussion");
|
|
535
|
+
if (this._ambientOcclussion instanceof Texture) {
|
|
536
|
+
this._ambientOcclussion.decReferences();
|
|
537
|
+
}
|
|
538
|
+
this._ambientOcclussion = v;
|
|
539
|
+
if (this._ambientOcclussion instanceof Texture) {
|
|
540
|
+
this._ambientOcclussion.incReferences();
|
|
541
|
+
}
|
|
542
|
+
this._dirty = true;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
get ambientOcclussionChannel(): number { return this._ambientOcclussionChannel; }
|
|
546
|
+
set ambientOcclussionChannel(v: number) { this._ambientOcclussionChannel = v; this._dirty = true; }
|
|
547
|
+
get ambientOcclussionUV(): number { return this._ambientOcclussionUV; }
|
|
548
|
+
set ambientOcclussionUV(v: number) { this._ambientOcclussionUV = v; this._dirty = true; }
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
get heightTexture(): Texture | null { return this._heightTexture; }
|
|
553
|
+
set heightTexture(v: Texture | null) { assertTexture(v, "heightTexture"); this._heightTexture = v; this._dirty = true; }
|
|
554
|
+
get heightChannel(): number { return this._heightChannel; }
|
|
555
|
+
set heightChannel(v: number) { this._heightChannel = v; this._dirty = true; }
|
|
556
|
+
get heightScale(): Vec { return this._heightScale; }
|
|
557
|
+
set heightScale(v: Vec) { assertScale(v, "heightScale"); this._heightScale = new Vec(v); this._dirty = true; }
|
|
558
|
+
get heightUV(): number { return this._heightUV; }
|
|
559
|
+
set heightUV(v: number) { this._heightUV = v; this._dirty = true; }
|
|
560
|
+
get heightIntensity(): number { return this._heightIntensity; }
|
|
561
|
+
set heightIntensity(v: number) { this._heightIntensity = v; this._dirty = true; }
|
|
562
|
+
get castShadows(): boolean { return this._castShadows; }
|
|
563
|
+
set castShadows(v: boolean) { this._castShadows = v; this._dirty = true; }
|
|
564
|
+
get unlit(): boolean { return this._unlit; }
|
|
565
|
+
set unlit(v: boolean) { this._unlit = v; this._dirty = true; }
|
|
566
|
+
|
|
567
|
+
async serialize(sceneData: any): Promise<void> {
|
|
568
|
+
for (const att in MaterialAttributeNames) {
|
|
569
|
+
const value = MaterialAttributeNames[att].loader.serialize(att, (this as any)[att]);
|
|
570
|
+
if (value) {
|
|
571
|
+
sceneData[att] = value;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
async deserialize(sceneData: any, relativePath: string, canvas?: Canvas | null): Promise<void> {
|
|
577
|
+
const P: Promise<any>[] = [];
|
|
578
|
+
|
|
579
|
+
this.type = sceneData.type || MaterialType.PBR;
|
|
580
|
+
this.alphaCutoff = sceneData.alphaCutoff || 0.5;
|
|
581
|
+
this.isTransparent = sceneData.isTransparent || false;
|
|
582
|
+
|
|
583
|
+
for (const attName in MaterialAttributeNames) {
|
|
584
|
+
const loader = MaterialAttributeNames[attName]?.loader;
|
|
585
|
+
if (loader) {
|
|
586
|
+
const value = loader.deserialize(attName, sceneData[attName], relativePath, this.canvas);
|
|
587
|
+
if (value instanceof Texture) {
|
|
588
|
+
P.push(value.loadImageData());
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
if (value !== null && value !== undefined) {
|
|
592
|
+
(this as any)[attName] = value;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
await Promise.all(P);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
destroy(): void {
|
|
600
|
+
const decReferences = (attrib: string) => {
|
|
601
|
+
if ((this as any)[attrib] instanceof Texture) {
|
|
602
|
+
(this as any)[attrib].decReferences();
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
decReferences("albedoTexture");
|
|
607
|
+
decReferences("normalTexture");
|
|
608
|
+
decReferences("metalnessTexture");
|
|
609
|
+
decReferences("roughnessTexture");
|
|
610
|
+
decReferences("lightEmissionTexture");
|
|
611
|
+
decReferences("ambientOcclussion");
|
|
612
|
+
decReferences("height");
|
|
613
|
+
|
|
614
|
+
this._canvas = null;
|
|
615
|
+
|
|
616
|
+
if (this.renderer) {
|
|
617
|
+
this.renderer.destroy();
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|