11import WebGPUUniformsGroup from './WebGPUUniformsGroup.js' ;
22import WebGPUSampler from './WebGPUSampler.js' ;
33import WebGPUSampledTexture from './WebGPUSampledTexture.js' ;
4- import { Matrix4 } from '../../../../build/three.module.js' ;
4+ import { Matrix3 , Matrix4 , Vector2 , Vector3 , Vector4 } from '../../../../build/three.module.js' ;
55
66class WebGPUBindings {
77
@@ -22,7 +22,17 @@ class WebGPUBindings {
2222
2323 }
2424
25- get ( object ) {
25+ // Here taking shaderUniforms is what I don't really like.
26+ // To set up bindings, uniforms information in shader is necessary.
27+ // But just getting existing bindings doesn't need uniforms information.
28+ // I moved bindings.update() in WebGPURenderer after render pipeline get/creation
29+ // (See _renderObject() in WebGPURenderer), and bindings.get() in WebGPURenderPipelines
30+ // is only the place where bindings setup can cause now.
31+ // So passing bindings.get() call in WebGPURenderPipelines passes shaderUniforms
32+ // and other bindings.get() doesn't pass.
33+ // I don't think this is a good design and want to simplify...
34+
35+ get ( object , shaderUniforms ) {
2636
2737 let data = this . uniformsData . get ( object ) ;
2838
@@ -45,6 +55,10 @@ class WebGPUBindings {
4555
4656 bindings = this . _getLinesBasicBindings ( ) ;
4757
58+ } else if ( material . isShaderMaterial ) {
59+
60+ bindings = this . _getShaderBindings ( material , shaderUniforms ) ;
61+
4862 } else {
4963
5064 console . error ( 'THREE.WebGPURenderer: Unknwon shader type.' ) ;
@@ -115,7 +129,23 @@ class WebGPUBindings {
115129 } else if ( binding . isSampler ) {
116130
117131 const material = object . material ;
118- const texture = material [ binding . name ] ;
132+
133+ // Here may be tricky.
134+ // Needs to search texture.
135+ // Assuming binding name has path from material to texture
136+ // separated by '.', like "map" or "uniforms.mySampler.value".
137+ // I want to simplify.
138+
139+ const names = binding . name . split ( '.' ) ;
140+ let target = material ;
141+
142+ for ( const name of names ) {
143+
144+ target = target [ name ] ;
145+
146+ }
147+
148+ const texture = target ;
119149
120150 textures . updateSampler ( texture ) ;
121151
@@ -131,7 +161,17 @@ class WebGPUBindings {
131161 } else if ( binding . isSampledTexture ) {
132162
133163 const material = object . material ;
134- const texture = material [ binding . name ] ;
164+
165+ const names = binding . name . split ( '.' ) ;
166+ let target = material ;
167+
168+ for ( const name of names ) {
169+
170+ target = target [ name ] ;
171+
172+ }
173+
174+ const texture = target ;
135175
136176 const forceUpdate = textures . updateTexture ( texture ) ;
137177 const textureGPU = textures . getTextureGPU ( texture ) ;
@@ -379,6 +419,128 @@ class WebGPUBindings {
379419
380420 }
381421
422+ _getShaderBindings ( material , shaderUniforms ) {
423+
424+ // Creates bindings from shader uniforms information
425+
426+ const bindings = [ ] ;
427+
428+ for ( const shaderUniform of shaderUniforms ) {
429+
430+ const name = shaderUniform . name ;
431+ const type = shaderUniform . type ;
432+ const groupType = shaderUniform . groupType ;
433+ const visibility = shaderUniform . visibility === 'vertex|fragment' ? GPUShaderStage . VERTEX | GPUShaderStage . FRAGMENT :
434+ shaderUniform . visibility === 'vertex' ? GPUShaderStage . VERTEX : GPUShaderStage . FRAGMENT ;
435+ let group ;
436+
437+ if ( name === 'modelUniforms' ) {
438+
439+ // Reserved name 'modelUniforms'
440+
441+ group = new WebGPUUniformsGroup ( ) ;
442+ group . setName ( name ) ;
443+ group . visibility = visibility ;
444+ group . setUniform ( 'modelMatrix' , new Matrix4 ( ) ) ;
445+ group . setUniform ( 'modelViewMatrix' , new Matrix4 ( ) ) ;
446+
447+ group . setUpdateCallback ( function ( object /*, camera */ ) {
448+
449+ let updated = false ;
450+
451+ if ( this . updateMatrix4 ( object . matrixWorld , 0 ) ) updated = true ;
452+ if ( this . updateMatrix4 ( object . modelViewMatrix , 16 ) ) updated = true ;
453+
454+ return updated ;
455+
456+ } ) ;
457+
458+ } else if ( name === 'cameraUniforms' ) {
459+
460+ // Reserved name 'cameraUniforms'
461+
462+ group = this . sharedUniformsGroups . get ( 'cameraUniforms' ) ;
463+
464+ } else if ( groupType === 'uniform-buffer' ) {
465+
466+ group = new WebGPUUniformsGroup ( ) ;
467+ group . setName ( name ) ;
468+ group . visibility = visibility ;
469+
470+ const entries = shaderUniform . entries ;
471+
472+ for ( const entry of entries ) {
473+
474+ group . setUniform ( entry . name , getInitialValue ( entry . type ) ) ;
475+
476+ }
477+
478+ group . setUpdateCallback ( function ( array , object /*, camera */ ) {
479+
480+ const values = material . uniforms [ name ] . value ;
481+ let offset = 0 ;
482+ let updated = false ;
483+
484+ for ( let i = 0 ; i < entries . length ; i ++ ) {
485+
486+ const entry = entries [ i ] ;
487+ const value = values [ i ] ;
488+ if ( this . updateByType ( value , offset ) ) updated = true ;
489+ offset += this . getUniformByteLength ( value ) / 4 ; // Assuming array is Float32 so far
490+
491+ }
492+
493+ return updated ;
494+
495+ } ) ;
496+
497+ } else if ( groupType === 'sampler' ) {
498+
499+ group = new WebGPUSampler ( ) ;
500+ group . setName ( 'uniforms.' + name + '.value' ) ;
501+ group . visibility = visibility ;
502+
503+ } else if ( groupType === 'sampled-texture' ) {
504+
505+ group = new WebGPUSampledTexture ( ) ;
506+ group . setName ( 'uniforms.' + name + '.value' ) ;
507+ group . visibility = visibility ;
508+
509+ } else {
510+
511+ console . error ( 'THREE.WebGPURenderer: Unknown uniform type ' + type ) ;
512+
513+ }
514+
515+ bindings . push ( group ) ;
516+
517+ }
518+
519+ return bindings ;
520+
521+ }
522+
523+ }
524+
525+ function getInitialValue ( type ) {
526+
527+ switch ( type ) {
528+ case 'float' :
529+ return 0.0 ;
530+ case 'vec2' :
531+ return new Vector2 ( ) ;
532+ case 'vec3' :
533+ return new Vector3 ( ) ;
534+ case 'vec4' :
535+ return new Vector4 ( ) ;
536+ case 'mat3' :
537+ return new Matrix3 ( ) ;
538+ case 'mat4' :
539+ return new Matrix4 ( ) ;
540+ }
541+
542+ console . error ( 'THREE.WebGPURenderer: Unknown uniform type ' + type ) ;
543+
382544}
383545
384546export default WebGPUBindings ;
0 commit comments