1- import { Renderer3D } from '../core/p5.Renderer3D' ;
1+ import { Renderer3D , getStrokeDefs } from '../core/p5.Renderer3D' ;
22import { Shader } from '../webgl/p5.Shader' ;
33import * as constants from '../core/constants' ;
4+
5+
46import { colorVertexShader , colorFragmentShader } from './shaders/color' ;
7+ import { lineVertexShader , lineFragmentShader } from './shaders/line' ;
58import { materialVertexShader , materialFragmentShader } from './shaders/material' ;
69
10+ const { lineDefs} = getStrokeDefs ( ( n , v , t ) => `const${ n } :${ t } =${ v } ;\n` ) ;
11+
712class RendererWebGPU extends Renderer3D {
813constructor ( pInst , w , h , isMainCanvas , elt ) {
914super ( pInst , w , h , isMainCanvas , elt )
@@ -457,7 +462,6 @@ class RendererWebGPU extends Renderer3D {
457462for ( const attrName in shader . attributes ) {
458463const attr = shader . attributes [ attrName ] ;
459464if ( ! attr || attr . location === - 1 ) continue ;
460-
461465// Get the vertex buffer info associated with this attribute
462466const renderBuffer =
463467this . buffers [ shader . shaderType ] . find ( buf => buf . attr === attrName ) ||
@@ -481,7 +485,6 @@ class RendererWebGPU extends Renderer3D {
481485] ,
482486} ) ;
483487}
484-
485488return layouts ;
486489}
487490
@@ -516,7 +519,9 @@ class RendererWebGPU extends Renderer3D {
516519
517520_useShader ( shader , options ) { }
518521
519- _updateViewport ( ) { }
522+ _updateViewport ( ) {
523+ this . _viewport = [ 0 , 0 , this . width , this . height ] ;
524+ }
520525
521526zClipRange ( ) {
522527return [ 0 , 1 ] ;
@@ -557,8 +562,9 @@ class RendererWebGPU extends Renderer3D {
557562if ( ! buffers ) return ;
558563
559564const commandEncoder = this . device . createCommandEncoder ( ) ;
565+ const currentTexture = this . drawingContext . getCurrentTexture ( ) ;
560566const colorAttachment = {
561- view :this . drawingContext . getCurrentTexture ( ) . createView ( ) ,
567+ view :currentTexture . createView ( ) ,
562568loadOp :"load" ,
563569storeOp :"store" ,
564570} ;
@@ -581,34 +587,33 @@ class RendererWebGPU extends Renderer3D {
581587} ;
582588
583589const passEncoder = commandEncoder . beginRenderPass ( renderPassDescriptor ) ;
584- passEncoder . setPipeline ( this . _curShader . getPipeline ( this . _shaderOptions ( { mode } ) ) ) ;
585-
590+ const currentShader = this . _curShader ;
591+ passEncoder . setPipeline ( currentShader . getPipeline ( this . _shaderOptions ( { mode } ) ) ) ;
586592// Bind vertex buffers
587- for ( const buffer of this . _getVertexBuffers ( this . _curShader ) ) {
593+ for ( const buffer of this . _getVertexBuffers ( currentShader ) ) {
588594passEncoder . setVertexBuffer (
589- this . _curShader . attributes [ buffer . attr ] . location ,
595+ currentShader . attributes [ buffer . attr ] . location ,
590596buffers [ buffer . dst ] ,
5915970
592598) ;
593599}
594-
595600// Bind uniforms
596601this . _packUniforms ( this . _curShader ) ;
597602this . device . queue . writeBuffer (
598- this . _curShader . _uniformBuffer ,
603+ currentShader . _uniformBuffer ,
5996040 ,
600- this . _curShader . _uniformData . buffer ,
601- this . _curShader . _uniformData . byteOffset ,
602- this . _curShader . _uniformData . byteLength
605+ currentShader . _uniformData . buffer ,
606+ currentShader . _uniformData . byteOffset ,
607+ currentShader . _uniformData . byteLength
603608) ;
604609
605610// Bind sampler/texture uniforms
606- for ( const [ group , entries ] of this . _curShader . _groupEntries ) {
611+ for ( const [ group , entries ] of currentShader . _groupEntries ) {
607612const bgEntries = entries . map ( entry => {
608613if ( group === 0 && entry . binding === 0 ) {
609614return {
610615binding :0 ,
611- resource :{ buffer :this . _curShader . _uniformBuffer } ,
616+ resource :{ buffer :currentShader . _uniformBuffer } ,
612617} ;
613618}
614619
@@ -620,22 +625,27 @@ class RendererWebGPU extends Renderer3D {
620625} ;
621626} ) ;
622627
623- const layout = this . _curShader . _bindGroupLayouts [ group ] ;
628+ const layout = currentShader . _bindGroupLayouts [ group ] ;
624629const bindGroup = this . device . createBindGroup ( {
625630 layout,
626631entries :bgEntries ,
627632} ) ;
628-
629633passEncoder . setBindGroup ( group , bindGroup ) ;
630634}
631635
632- // Bind index buffer and issue draw
633- if ( buffers . indexBuffer ) {
634- const indexFormat = buffers . indexFormat || "uint16" ;
635- passEncoder . setIndexBuffer ( buffers . indexBuffer , indexFormat ) ;
636- passEncoder . drawIndexed ( geometry . faces . length * 3 , count , 0 , 0 , 0 ) ;
637- } else {
638- passEncoder . draw ( geometry . vertices . length , count , 0 , 0 ) ;
636+ if ( currentShader . shaderType === "fill" ) {
637+ // Bind index buffer and issue draw
638+ if ( buffers . indexBuffer ) {
639+ const indexFormat = buffers . indexFormat || "uint16" ;
640+ passEncoder . setIndexBuffer ( buffers . indexBuffer , indexFormat ) ;
641+ passEncoder . drawIndexed ( geometry . faces . length * 3 , count , 0 , 0 , 0 ) ;
642+ } else {
643+ passEncoder . draw ( geometry . vertices . length , count , 0 , 0 ) ;
644+ }
645+ }
646+
647+ if ( buffers . lineVerticesBuffer && currentShader . shaderType === "stroke" ) {
648+ passEncoder . draw ( geometry . lineVertices . length / 3 , count , 0 , 0 ) ;
639649}
640650
641651passEncoder . end ( ) ;
@@ -788,7 +798,6 @@ class RendererWebGPU extends Renderer3D {
788798}
789799const structType = uniformVarMatch [ 2 ] ;
790800const uniforms = this . _parseStruct ( shader . vertSrc ( ) , structType ) ;
791-
792801// Extract samplers from group bindings
793802const samplers = [ ] ;
794803const samplerRegex = / @ g r o u p \( ( \d + ) \) \s * @ b i n d i n g \( ( \d + ) \) \s * v a r \s + ( \w + ) \s * : \s * ( \w + ) ; / g;
@@ -941,6 +950,33 @@ class RendererWebGPU extends Renderer3D {
941950return this . _defaultColorShader ;
942951}
943952
953+ _getLineShader ( ) {
954+ if ( ! this . _defaultLineShader ) {
955+ this . _defaultLineShader = new Shader (
956+ this ,
957+ lineDefs + lineVertexShader ,
958+ lineDefs + lineFragmentShader ,
959+ {
960+ vertex :{
961+ "void beforeVertex" :"() {}" ,
962+ "StrokeVertex getObjectInputs" :"(inputs: StrokeVertex) { return inputs; }" ,
963+ "StrokeVertex getWorldInputs" :"(inputs: StrokeVertex) { return inputs; }" ,
964+ "StrokeVertex getCameraInputs" :"(inputs: StrokeVertex) { return inputs; }" ,
965+ "void afterVertex" :"() {}" ,
966+ } ,
967+ fragment :{
968+ "void beforeFragment" :"() {}" ,
969+ "Inputs getPixelInputs" :"(inputs: Inputs) { return inputs; }" ,
970+ "vec4<f32> getFinalColor" :"(color: vec4<f32>) { return color; }" ,
971+ "bool shouldDiscard" :"(outside: bool) { return outside; };" ,
972+ "void afterFragment" :"() {}" ,
973+ } ,
974+ }
975+ ) ;
976+ }
977+ return this . _defaultLineShader ;
978+ }
979+
944980//////////////////////////////////////////////
945981// Setting
946982//////////////////////////////////////////////
@@ -956,7 +992,7 @@ class RendererWebGPU extends Renderer3D {
956992//////////////////////////////////////////////
957993// Shader hooks
958994//////////////////////////////////////////////
959- fillHooks ( shader , src , shaderType ) {
995+ populateHooks ( shader , src , shaderType ) {
960996if ( ! src . includes ( 'fn main' ) ) return src ;
961997
962998// Apply some p5-specific preprocessing. WGSL doesn't have preprocessor