NodeMaterial.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { Material, ShaderMaterial } from 'three';
  2. import { getNodesKeys } from '../core/NodeUtils.js';
  3. class NodeMaterial extends ShaderMaterial {
  4. constructor() {
  5. super();
  6. this.type = this.constructor.name;
  7. this.lights = true;
  8. }
  9. setDefaultValues( values ) {
  10. // This approach is to reuse the native refreshUniforms*
  11. // and turn available the use of features like transmission and environment in core
  12. let value;
  13. for ( const property in values ) {
  14. value = values[ property ];
  15. if ( this[ property ] === undefined ) {
  16. if ( value && typeof value.clone === 'function' ) {
  17. this[ property ] = value.clone();
  18. } else {
  19. this[ property ] = value;
  20. }
  21. }
  22. }
  23. Object.assign( this.defines, values.defines );
  24. }
  25. toJSON( meta ) {
  26. const isRoot = ( meta === undefined || typeof meta === 'string' );
  27. if ( isRoot ) {
  28. meta = {
  29. textures: {},
  30. images: {},
  31. nodes: {}
  32. };
  33. }
  34. const data = Material.prototype.toJSON.call( this, meta );
  35. const nodeKeys = getNodesKeys( this );
  36. data.inputNodes = {};
  37. for ( const name of nodeKeys ) {
  38. data.inputNodes[ name ] = this[ name ].toJSON( meta ).uuid;
  39. }
  40. // TODO: Copied from Object3D.toJSON
  41. function extractFromCache( cache ) {
  42. const values = [];
  43. for ( const key in cache ) {
  44. const data = cache[ key ];
  45. delete data.metadata;
  46. values.push( data );
  47. }
  48. return values;
  49. }
  50. if ( isRoot ) {
  51. const textures = extractFromCache( meta.textures );
  52. const images = extractFromCache( meta.images );
  53. const nodes = extractFromCache( meta.nodes );
  54. if ( textures.length > 0 ) data.textures = textures;
  55. if ( images.length > 0 ) data.images = images;
  56. if ( nodes.length > 0 ) data.nodes = nodes;
  57. }
  58. return data;
  59. }
  60. }
  61. NodeMaterial.prototype.isNodeMaterial = true;
  62. export default NodeMaterial;