WebGPUUniformsGroup.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import WebGPUBinding from './WebGPUBinding.js';
  2. class WebGPUUniformsGroup extends WebGPUBinding {
  3. constructor() {
  4. super();
  5. this.name = '';
  6. this.uniforms = new Map();
  7. this.update = function () {};
  8. this.type = 'uniform-buffer';
  9. this.visibility = GPUShaderStage.VERTEX;
  10. this.usage = GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST;
  11. this.array = null; // set by the renderer
  12. this.bufferGPU = null; // set by the renderer
  13. Object.defineProperty( this, 'isUniformsGroup', { value: true } );
  14. }
  15. setName( name ) {
  16. this.name = name;
  17. }
  18. setUniform( name, uniform ) {
  19. this.uniforms.set( name, uniform );
  20. return this;
  21. }
  22. removeUniform( name ) {
  23. this.uniforms.delete( name );
  24. return this;
  25. }
  26. setUpdateCallback( callback ) {
  27. this.update = callback;
  28. return this;
  29. }
  30. copy( source ) {
  31. this.name = source.name;
  32. const uniformsSource = source.uniforms;
  33. this.uniforms.clear();
  34. for ( const entry of uniformsSource ) {
  35. this.uniforms.set( ...entry );
  36. }
  37. return this;
  38. }
  39. clone() {
  40. return new this.constructor().copy( this );
  41. }
  42. getByteLength() {
  43. let size = 0;
  44. for ( const uniform of this.uniforms.values() ) {
  45. size += this.getUniformByteLength( uniform );
  46. }
  47. return size;
  48. }
  49. getUniformByteLength( uniform ) {
  50. let size;
  51. if ( typeof uniform === 'number' ) {
  52. size = 4;
  53. } else if ( uniform.isVector2 ) {
  54. size = 8;
  55. } else if ( uniform.isVector3 || uniform.isColor ) {
  56. size = 12;
  57. } else if ( uniform.isVector4 ) {
  58. size = 16;
  59. } else if ( uniform.isMatrix3 ) {
  60. size = 48; // (3 * 4) * 4 bytes
  61. } else if ( uniform.isMatrix4 ) {
  62. size = 64;
  63. } else if ( uniform.isTexture ) {
  64. console.error( 'THREE.UniformsGroup: Texture samplers can not be part of an uniforms group.' );
  65. } else {
  66. console.error( 'THREE.UniformsGroup: Unsupported uniform value type.', uniform );
  67. }
  68. return size;
  69. }
  70. updateNumber( v, offset ) {
  71. let updated = false;
  72. const a = this.array;
  73. if ( a[ offset ] !== v ) {
  74. a[ offset ] = v;
  75. updated = true;
  76. }
  77. return updated;
  78. }
  79. updateVector2( v, offset ) {
  80. let updated = false;
  81. const a = this.array;
  82. if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y ) {
  83. a[ offset + 0 ] = v.x;
  84. a[ offset + 1 ] = v.y;
  85. updated = true;
  86. }
  87. return updated;
  88. }
  89. updateVector3( v, offset ) {
  90. let updated = false;
  91. const a = this.array;
  92. if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z ) {
  93. a[ offset + 0 ] = v.x;
  94. a[ offset + 1 ] = v.y;
  95. a[ offset + 2 ] = v.z;
  96. updated = true;
  97. }
  98. return updated;
  99. }
  100. updateVector4( v, offset ) {
  101. let updated = false;
  102. const a = this.array;
  103. if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z || a[ offset + 4 ] !== v.w ) {
  104. a[ offset + 0 ] = v.x;
  105. a[ offset + 1 ] = v.y;
  106. a[ offset + 2 ] = v.z;
  107. a[ offset + 3 ] = v.z;
  108. updated = true;
  109. }
  110. return updated;
  111. }
  112. updateColor( c, offset ) {
  113. let updated = false;
  114. const a = this.array;
  115. if ( a[ offset + 0 ] !== c.r || a[ offset + 1 ] !== c.g || a[ offset + 2 ] !== c.b ) {
  116. a[ offset + 0 ] = c.r;
  117. a[ offset + 1 ] = c.g;
  118. a[ offset + 2 ] = c.b;
  119. updated = true;
  120. }
  121. return updated;
  122. }
  123. updateMatrix3( m, offset ) {
  124. let updated = false;
  125. const a = this.array;
  126. const e = m.elements;
  127. if ( a[ offset + 0 ] !== e[ 0 ] || a[ offset + 1 ] !== e[ 1 ] || a[ offset + 2 ] !== e[ 2 ] ||
  128. a[ offset + 4 ] !== e[ 3 ] || a[ offset + 5 ] !== e[ 4 ] || a[ offset + 6 ] !== e[ 5 ] ||
  129. a[ offset + 8 ] !== e[ 6 ] || a[ offset + 9 ] !== e[ 7 ] || a[ offset + 10 ] !== e[ 8 ] ) {
  130. a[ offset + 0 ] = e[ 0 ];
  131. a[ offset + 1 ] = e[ 1 ];
  132. a[ offset + 2 ] = e[ 2 ];
  133. a[ offset + 4 ] = e[ 3 ];
  134. a[ offset + 5 ] = e[ 4 ];
  135. a[ offset + 6 ] = e[ 5 ];
  136. a[ offset + 8 ] = e[ 6 ];
  137. a[ offset + 9 ] = e[ 7 ];
  138. a[ offset + 10 ] = e[ 8 ];
  139. updated = true;
  140. }
  141. return updated;
  142. }
  143. updateMatrix4( m, offset ) {
  144. let updated = false;
  145. const a = this.array;
  146. const e = m.elements;
  147. if ( arraysEqual( a, e, offset ) === false ) {
  148. a.set( e, offset );
  149. updated = true;
  150. }
  151. return updated;
  152. }
  153. }
  154. function arraysEqual( a, b, offset ) {
  155. for ( let i = 0, l = b.length; i < l; i ++ ) {
  156. if ( a[ offset + i ] !== b[ i ] ) return false;
  157. }
  158. return true;
  159. }
  160. export default WebGPUUniformsGroup;