UNPKG

9.92 kBJavaScriptView Raw
1import { EventDispatcher } from '../core/EventDispatcher.js';
2import { NoColors, FrontSide, FlatShading, NormalBlending, LessEqualDepth, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor } from '../constants.js';
3import { _Math } from '../math/Math.js';
4
5/**
6 * @author mrdoob / http://mrdoob.com/
7 * @author alteredq / http://alteredqualia.com/
8 */
9
10var materialId = 0;
11
12function Material() {
13
14 Object.defineProperty( this, 'id', { value: materialId ++ } );
15
16 this.uuid = _Math.generateUUID();
17
18 this.name = '';
19 this.type = 'Material';
20
21 this.fog = true;
22 this.lights = true;
23
24 this.blending = NormalBlending;
25 this.side = FrontSide;
26 this.flatShading = false;
27 this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors
28
29 this.opacity = 1;
30 this.transparent = false;
31
32 this.blendSrc = SrcAlphaFactor;
33 this.blendDst = OneMinusSrcAlphaFactor;
34 this.blendEquation = AddEquation;
35 this.blendSrcAlpha = null;
36 this.blendDstAlpha = null;
37 this.blendEquationAlpha = null;
38
39 this.depthFunc = LessEqualDepth;
40 this.depthTest = true;
41 this.depthWrite = true;
42
43 this.clippingPlanes = null;
44 this.clipIntersection = false;
45 this.clipShadows = false;
46
47 this.shadowSide = null;
48
49 this.colorWrite = true;
50
51 this.precision = null; // override the renderer's default precision for this material
52
53 this.polygonOffset = false;
54 this.polygonOffsetFactor = 0;
55 this.polygonOffsetUnits = 0;
56
57 this.dithering = false;
58
59 this.alphaTest = 0;
60 this.premultipliedAlpha = false;
61
62 this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer
63
64 this.visible = true;
65
66 this.userData = {};
67
68 this.needsUpdate = true;
69
70}
71
72Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
73
74 constructor: Material,
75
76 isMaterial: true,
77
78 onBeforeCompile: function () {},
79
80 setValues: function ( values ) {
81
82 if ( values === undefined ) return;
83
84 for ( var key in values ) {
85
86 var newValue = values[ key ];
87
88 if ( newValue === undefined ) {
89
90 console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
91 continue;
92
93 }
94
95 // for backward compatability if shading is set in the constructor
96 if ( key === 'shading' ) {
97
98 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
99 this.flatShading = ( newValue === FlatShading ) ? true : false;
100 continue;
101
102 }
103
104 var currentValue = this[ key ];
105
106 if ( currentValue === undefined ) {
107
108 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
109 continue;
110
111 }
112
113 if ( currentValue && currentValue.isColor ) {
114
115 currentValue.set( newValue );
116
117 } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
118
119 currentValue.copy( newValue );
120
121 } else if ( key === 'overdraw' ) {
122
123 // ensure overdraw is backwards-compatible with legacy boolean type
124 this[ key ] = Number( newValue );
125
126 } else {
127
128 this[ key ] = newValue;
129
130 }
131
132 }
133
134 },
135
136 toJSON: function ( meta ) {
137
138 var isRoot = ( meta === undefined || typeof meta === 'string' );
139
140 if ( isRoot ) {
141
142 meta = {
143 textures: {},
144 images: {}
145 };
146
147 }
148
149 var data = {
150 metadata: {
151 version: 4.5,
152 type: 'Material',
153 generator: 'Material.toJSON'
154 }
155 };
156
157 // standard Material serialization
158 data.uuid = this.uuid;
159 data.type = this.type;
160
161 if ( this.name !== '' ) data.name = this.name;
162
163 if ( this.color && this.color.isColor ) data.color = this.color.getHex();
164
165 if ( this.roughness !== undefined ) data.roughness = this.roughness;
166 if ( this.metalness !== undefined ) data.metalness = this.metalness;
167
168 if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex();
169 if ( this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity;
170
171 if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex();
172 if ( this.shininess !== undefined ) data.shininess = this.shininess;
173 if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat;
174 if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness;
175
176 if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid;
177 if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid;
178 if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid;
179 if ( this.bumpMap && this.bumpMap.isTexture ) {
180
181 data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
182 data.bumpScale = this.bumpScale;
183
184 }
185 if ( this.normalMap && this.normalMap.isTexture ) {
186
187 data.normalMap = this.normalMap.toJSON( meta ).uuid;
188 data.normalScale = this.normalScale.toArray();
189
190 }
191 if ( this.displacementMap && this.displacementMap.isTexture ) {
192
193 data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
194 data.displacementScale = this.displacementScale;
195 data.displacementBias = this.displacementBias;
196
197 }
198 if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid;
199 if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid;
200
201 if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid;
202 if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid;
203
204 if ( this.envMap && this.envMap.isTexture ) {
205
206 data.envMap = this.envMap.toJSON( meta ).uuid;
207 data.reflectivity = this.reflectivity; // Scale behind envMap
208
209 }
210
211 if ( this.gradientMap && this.gradientMap.isTexture ) {
212
213 data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
214
215 }
216
217 if ( this.size !== undefined ) data.size = this.size;
218 if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation;
219
220 if ( this.blending !== NormalBlending ) data.blending = this.blending;
221 if ( this.flatShading === true ) data.flatShading = this.flatShading;
222 if ( this.side !== FrontSide ) data.side = this.side;
223 if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors;
224
225 if ( this.opacity < 1 ) data.opacity = this.opacity;
226 if ( this.transparent === true ) data.transparent = this.transparent;
227
228 data.depthFunc = this.depthFunc;
229 data.depthTest = this.depthTest;
230 data.depthWrite = this.depthWrite;
231
232 // rotation (SpriteMaterial)
233 if ( this.rotation !== 0 ) data.rotation = this.rotation;
234
235 if ( this.linewidth !== 1 ) data.linewidth = this.linewidth;
236 if ( this.dashSize !== undefined ) data.dashSize = this.dashSize;
237 if ( this.gapSize !== undefined ) data.gapSize = this.gapSize;
238 if ( this.scale !== undefined ) data.scale = this.scale;
239
240 if ( this.dithering === true ) data.dithering = true;
241
242 if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
243 if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
244
245 if ( this.wireframe === true ) data.wireframe = this.wireframe;
246 if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth;
247 if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap;
248 if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin;
249
250 if ( this.morphTargets === true ) data.morphTargets = true;
251 if ( this.skinning === true ) data.skinning = true;
252
253 if ( this.visible === false ) data.visible = false;
254 if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData;
255
256 // TODO: Copied from Object3D.toJSON
257
258 function extractFromCache( cache ) {
259
260 var values = [];
261
262 for ( var key in cache ) {
263
264 var data = cache[ key ];
265 delete data.metadata;
266 values.push( data );
267
268 }
269
270 return values;
271
272 }
273
274 if ( isRoot ) {
275
276 var textures = extractFromCache( meta.textures );
277 var images = extractFromCache( meta.images );
278
279 if ( textures.length > 0 ) data.textures = textures;
280 if ( images.length > 0 ) data.images = images;
281
282 }
283
284 return data;
285
286 },
287
288 clone: function () {
289
290 return new this.constructor().copy( this );
291
292 },
293
294 copy: function ( source ) {
295
296 this.name = source.name;
297
298 this.fog = source.fog;
299 this.lights = source.lights;
300
301 this.blending = source.blending;
302 this.side = source.side;
303 this.flatShading = source.flatShading;
304 this.vertexColors = source.vertexColors;
305
306 this.opacity = source.opacity;
307 this.transparent = source.transparent;
308
309 this.blendSrc = source.blendSrc;
310 this.blendDst = source.blendDst;
311 this.blendEquation = source.blendEquation;
312 this.blendSrcAlpha = source.blendSrcAlpha;
313 this.blendDstAlpha = source.blendDstAlpha;
314 this.blendEquationAlpha = source.blendEquationAlpha;
315
316 this.depthFunc = source.depthFunc;
317 this.depthTest = source.depthTest;
318 this.depthWrite = source.depthWrite;
319
320 this.colorWrite = source.colorWrite;
321
322 this.precision = source.precision;
323
324 this.polygonOffset = source.polygonOffset;
325 this.polygonOffsetFactor = source.polygonOffsetFactor;
326 this.polygonOffsetUnits = source.polygonOffsetUnits;
327
328 this.dithering = source.dithering;
329
330 this.alphaTest = source.alphaTest;
331 this.premultipliedAlpha = source.premultipliedAlpha;
332
333 this.overdraw = source.overdraw;
334
335 this.visible = source.visible;
336 this.userData = JSON.parse( JSON.stringify( source.userData ) );
337
338 this.clipShadows = source.clipShadows;
339 this.clipIntersection = source.clipIntersection;
340
341 var srcPlanes = source.clippingPlanes,
342 dstPlanes = null;
343
344 if ( srcPlanes !== null ) {
345
346 var n = srcPlanes.length;
347 dstPlanes = new Array( n );
348
349 for ( var i = 0; i !== n; ++ i )
350 dstPlanes[ i ] = srcPlanes[ i ].clone();
351
352 }
353
354 this.clippingPlanes = dstPlanes;
355
356 this.shadowSide = source.shadowSide;
357
358 return this;
359
360 },
361
362 dispose: function () {
363
364 this.dispatchEvent( { type: 'dispose' } );
365
366 }
367
368} );
369
370
371export { Material };