ShaderMaterial.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { Material } from './Material.js';
  2. import { cloneUniforms } from '../renderers/shaders/UniformsUtils.js';
  3. import default_vertex from '../renderers/shaders/ShaderChunk/default_vertex.glsl.js';
  4. import default_fragment from '../renderers/shaders/ShaderChunk/default_fragment.glsl.js';
  5. /**
  6. * parameters = {
  7. * defines: { "label" : "value" },
  8. * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
  9. *
  10. * fragmentShader: <string>,
  11. * vertexShader: <string>,
  12. *
  13. * wireframe: <boolean>,
  14. * wireframeLinewidth: <float>,
  15. *
  16. * lights: <bool>
  17. * }
  18. */
  19. class ShaderMaterial extends Material {
  20. constructor( parameters ) {
  21. super();
  22. this.type = 'ShaderMaterial';
  23. this.defines = {};
  24. this.uniforms = {};
  25. this.vertexShader = default_vertex;
  26. this.fragmentShader = default_fragment;
  27. this.linewidth = 1;
  28. this.wireframe = false;
  29. this.wireframeLinewidth = 1;
  30. this.fog = false; // set to use scene fog
  31. this.lights = false; // set to use scene lights
  32. this.clipping = false; // set to use user-defined clipping planes
  33. this.extensions = {
  34. derivatives: false, // set to use derivatives
  35. fragDepth: false, // set to use fragment depth values
  36. drawBuffers: false, // set to use draw buffers
  37. shaderTextureLOD: false // set to use shader texture LOD
  38. };
  39. // When rendered geometry doesn't include these attributes but the material does,
  40. // use these default values in WebGL. This avoids errors when buffer data is missing.
  41. this.defaultAttributeValues = {
  42. 'color': [ 1, 1, 1 ],
  43. 'uv': [ 0, 0 ],
  44. 'uv2': [ 0, 0 ]
  45. };
  46. this.index0AttributeName = undefined;
  47. this.uniformsNeedUpdate = false;
  48. this.glslVersion = null;
  49. if ( parameters !== undefined ) {
  50. if ( parameters.attributes !== undefined ) {
  51. console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
  52. }
  53. this.setValues( parameters );
  54. }
  55. }
  56. copy( source ) {
  57. super.copy( source );
  58. this.fragmentShader = source.fragmentShader;
  59. this.vertexShader = source.vertexShader;
  60. this.uniforms = cloneUniforms( source.uniforms );
  61. this.defines = Object.assign( {}, source.defines );
  62. this.wireframe = source.wireframe;
  63. this.wireframeLinewidth = source.wireframeLinewidth;
  64. this.lights = source.lights;
  65. this.clipping = source.clipping;
  66. this.extensions = Object.assign( {}, source.extensions );
  67. this.glslVersion = source.glslVersion;
  68. return this;
  69. }
  70. toJSON( meta ) {
  71. const data = super.toJSON( meta );
  72. data.glslVersion = this.glslVersion;
  73. data.uniforms = {};
  74. for ( const name in this.uniforms ) {
  75. const uniform = this.uniforms[ name ];
  76. const value = uniform.value;
  77. if ( value && value.isTexture ) {
  78. data.uniforms[ name ] = {
  79. type: 't',
  80. value: value.toJSON( meta ).uuid
  81. };
  82. } else if ( value && value.isColor ) {
  83. data.uniforms[ name ] = {
  84. type: 'c',
  85. value: value.getHex()
  86. };
  87. } else if ( value && value.isVector2 ) {
  88. data.uniforms[ name ] = {
  89. type: 'v2',
  90. value: value.toArray()
  91. };
  92. } else if ( value && value.isVector3 ) {
  93. data.uniforms[ name ] = {
  94. type: 'v3',
  95. value: value.toArray()
  96. };
  97. } else if ( value && value.isVector4 ) {
  98. data.uniforms[ name ] = {
  99. type: 'v4',
  100. value: value.toArray()
  101. };
  102. } else if ( value && value.isMatrix3 ) {
  103. data.uniforms[ name ] = {
  104. type: 'm3',
  105. value: value.toArray()
  106. };
  107. } else if ( value && value.isMatrix4 ) {
  108. data.uniforms[ name ] = {
  109. type: 'm4',
  110. value: value.toArray()
  111. };
  112. } else {
  113. data.uniforms[ name ] = {
  114. value: value
  115. };
  116. // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
  117. }
  118. }
  119. if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;
  120. data.vertexShader = this.vertexShader;
  121. data.fragmentShader = this.fragmentShader;
  122. const extensions = {};
  123. for ( const key in this.extensions ) {
  124. if ( this.extensions[ key ] === true ) extensions[ key ] = true;
  125. }
  126. if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions;
  127. return data;
  128. }
  129. }
  130. ShaderMaterial.prototype.isShaderMaterial = true;
  131. export { ShaderMaterial };