@@ -324,8 +324,9 @@ class WebgpuShaderProcessorWGSL {
324324 // generate fragment output struct
325325 const fOutput = WebgpuShaderProcessorWGSL . generateFragmentOutputStruct ( fragmentExtracted . src , device . maxColorAttachments ) ;
326326
327- // VS - inject input copy to globals
327+ // inject the call to the function which copies the shader input globals
328328 vertexExtracted . src = WebgpuShaderProcessorWGSL . copyInputs ( vertexExtracted . src , shader ) ;
329+ fragmentExtracted . src = WebgpuShaderProcessorWGSL . copyInputs ( fragmentExtracted . src , shader ) ;
329330
330331 // VS - insert the blocks to the source
331332 const vBlock = `${ attributesBlock } \n${ vertexVaryingsBlock } \n${ uniformsData . code } \n${ resourcesData . code } \n` ;
@@ -633,6 +634,8 @@ class WebgpuShaderProcessorWGSL {
633634
634635 static processVaryings ( varyingLines , varyingMap , isVertex ) {
635636 let block = '' ;
637+ let blockPrivates = '' ;
638+ let blockCopy = '' ;
636639 varyingLines . forEach ( ( line , index ) => {
637640 const match = line . match ( VARYING ) ;
638641 Debug . assert ( match , `Varying line is not valid: ${ line } ` ) ;
@@ -650,20 +653,51 @@ class WebgpuShaderProcessorWGSL {
650653
651654 // generates: `@location(0) @interpolate(perspective, centroid) smoothColor : vec3f`
652655 block += ` @location(${ index } ) ${ line } ,\n` ;
656+
657+ // fragment shader inputs (varyings)
658+ if ( ! isVertex ) {
659+
660+ // private global variable for fragment varying
661+ blockPrivates += ` var<private> ${ line } ;\n` ;
662+
663+ // copy input variable to the private variable
664+ blockCopy += ` ${ name } = input.${ name } ;\n` ;
665+ }
653666 }
654667 } ) ;
655668
656669 // add built-in varyings
657670 if ( isVertex ) {
658- block += ' @builtin(position) position : vec4f,\n' ; // output position
671+ block += ' @builtin(position) position : vec4f,\n' ; // output position
659672 } else {
660- block += ' @builtin(position) position : vec4f,\n' ; // interpolated fragment position
673+ block += ' @builtin(position) position : vec4f,\n' ; // interpolated fragment position
661674 block += ' @builtin(front_facing) frontFacing : bool,\n' ; // front-facing
662675 block += ' @builtin(sample_index) sampleIndex : u32\n' ; // sample index for MSAA
663676 }
664677
678+ // global variables for build-in input into fragment shader
679+ const fragmentGlobals = isVertex ? '' : `
680+ var<private> pcPosition: vec4f;
681+ var<private> pcFrontFacing: bool;
682+ var<private> pcSampleIndex: u32;
683+ ${ blockPrivates }
684+
685+ // function to copy inputs (varyings) to private global variables
686+ fn _pcCopyInputs(input: FragmentInput) {
687+ ${ blockCopy }
688+ pcPosition = input.position;
689+ pcFrontFacing = input.frontFacing;
690+ pcSampleIndex = input.sampleIndex;
691+ }
692+ ` ;
693+
665694 const structName = isVertex ? 'VertexOutput' : 'FragmentInput' ;
666- return `struct ${ structName } {\n${ block } };\n` ;
695+ return `
696+ struct ${ structName } {
697+ ${ block }
698+ };
699+ ${ fragmentGlobals }
700+ ` ;
667701 }
668702
669703 static generateFragmentOutputStruct ( src , numRenderTargets ) {
@@ -757,25 +791,27 @@ class WebgpuShaderProcessorWGSL {
757791 }
758792 } ) ;
759793
760- // add built-in attributes
761- blockAttributes += ' @builtin(vertex_index) vertexIndex : u32,\n' ; // vertex index
762- blockAttributes += ' @builtin(instance_index) instanceIndex : u32\n' ; // instance index
763-
764794 return `
765795 struct VertexInput {
766796 ${ blockAttributes }
797+ @builtin(vertex_index) vertexIndex : u32, // built-in vertex index
798+ @builtin(instance_index) instanceIndex : u32 // built-in instance index
767799 };
768800
769801 ${ blockPrivates }
802+ var<private> pcVertexIndex: u32;
803+ var<private> pcInstanceIndex: u32;
770804
771- fn _copyInputs_ (input: VertexInput) {
805+ fn _pcCopyInputs (input: VertexInput) {
772806 ${ blockCopy }
807+ pcVertexIndex = input.vertexIndex;
808+ pcInstanceIndex = input.instanceIndex;
773809 }
774810 ` ;
775811 }
776812
777813 /**
778- * Injects a call to _copyInputs_ with the function's input parameter right after the opening
814+ * Injects a call to _pcCopyInputs with the function's input parameter right after the opening
779815 * brace of a WGSL function marked with `@vertex` or `@fragment`.
780816 *
781817 * @param {string } src - The source string containing the WGSL code.
@@ -799,7 +835,7 @@ class WebgpuShaderProcessorWGSL {
799835 const beginning = src . slice ( 0 , braceIndex + 1 ) ;
800836 const end = src . slice ( braceIndex + 1 ) ;
801837
802- const lineToInject = `\n _copyInputs_ (${ inputName } );` ;
838+ const lineToInject = `\n _pcCopyInputs (${ inputName } );` ;
803839 return beginning + lineToInject + end ;
804840 }
805841
0 commit comments