@@ -324,8 +324,9 @@ class WebgpuShaderProcessorWGSL {
324
324
// generate fragment output struct
325
325
const fOutput = WebgpuShaderProcessorWGSL . generateFragmentOutputStruct ( fragmentExtracted . src , device . maxColorAttachments ) ;
326
326
327
- // VS - inject input copy to globals
327
+ // inject the call to the function which copies the shader input globals
328
328
vertexExtracted . src = WebgpuShaderProcessorWGSL . copyInputs ( vertexExtracted . src , shader ) ;
329
+ fragmentExtracted . src = WebgpuShaderProcessorWGSL . copyInputs ( fragmentExtracted . src , shader ) ;
329
330
330
331
// VS - insert the blocks to the source
331
332
const vBlock = `${ attributesBlock } \n${ vertexVaryingsBlock } \n${ uniformsData . code } \n${ resourcesData . code } \n` ;
@@ -633,6 +634,8 @@ class WebgpuShaderProcessorWGSL {
633
634
634
635
static processVaryings ( varyingLines , varyingMap , isVertex ) {
635
636
let block = '' ;
637
+ let blockPrivates = '' ;
638
+ let blockCopy = '' ;
636
639
varyingLines . forEach ( ( line , index ) => {
637
640
const match = line . match ( VARYING ) ;
638
641
Debug . assert ( match , `Varying line is not valid: ${ line } ` ) ;
@@ -650,20 +653,51 @@ class WebgpuShaderProcessorWGSL {
650
653
651
654
// generates: `@location(0) @interpolate(perspective, centroid) smoothColor : vec3f`
652
655
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
+ }
653
666
}
654
667
} ) ;
655
668
656
669
// add built-in varyings
657
670
if ( isVertex ) {
658
- block += ' @builtin(position) position : vec4f,\n' ; // output position
671
+ block += ' @builtin(position) position : vec4f,\n' ; // output position
659
672
} else {
660
- block += ' @builtin(position) position : vec4f,\n' ; // interpolated fragment position
673
+ block += ' @builtin(position) position : vec4f,\n' ; // interpolated fragment position
661
674
block += ' @builtin(front_facing) frontFacing : bool,\n' ; // front-facing
662
675
block += ' @builtin(sample_index) sampleIndex : u32\n' ; // sample index for MSAA
663
676
}
664
677
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
+
665
694
const structName = isVertex ? 'VertexOutput' : 'FragmentInput' ;
666
- return `struct ${ structName } {\n${ block } };\n` ;
695
+ return `
696
+ struct ${ structName } {
697
+ ${ block }
698
+ };
699
+ ${ fragmentGlobals }
700
+ ` ;
667
701
}
668
702
669
703
static generateFragmentOutputStruct ( src , numRenderTargets ) {
@@ -757,25 +791,27 @@ class WebgpuShaderProcessorWGSL {
757
791
}
758
792
} ) ;
759
793
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
-
764
794
return `
765
795
struct VertexInput {
766
796
${ blockAttributes }
797
+ @builtin(vertex_index) vertexIndex : u32, // built-in vertex index
798
+ @builtin(instance_index) instanceIndex : u32 // built-in instance index
767
799
};
768
800
769
801
${ blockPrivates }
802
+ var<private> pcVertexIndex: u32;
803
+ var<private> pcInstanceIndex: u32;
770
804
771
- fn _copyInputs_ (input: VertexInput) {
805
+ fn _pcCopyInputs (input: VertexInput) {
772
806
${ blockCopy }
807
+ pcVertexIndex = input.vertexIndex;
808
+ pcInstanceIndex = input.instanceIndex;
773
809
}
774
810
` ;
775
811
}
776
812
777
813
/**
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
779
815
* brace of a WGSL function marked with `@vertex` or `@fragment`.
780
816
*
781
817
* @param {string } src - The source string containing the WGSL code.
@@ -799,7 +835,7 @@ class WebgpuShaderProcessorWGSL {
799
835
const beginning = src . slice ( 0 , braceIndex + 1 ) ;
800
836
const end = src . slice ( braceIndex + 1 ) ;
801
837
802
- const lineToInject = `\n _copyInputs_ (${ inputName } );` ;
838
+ const lineToInject = `\n _pcCopyInputs (${ inputName } );` ;
803
839
return beginning + lineToInject + end ;
804
840
}
805
841
0 commit comments