@@ -6,15 +6,143 @@ export class ForwardPlusRenderer extends renderer.Renderer {
66 // TODO-2: add layouts, pipelines, textures, etc. needed for Forward+ here
77 // you may need extra uniforms such as the camera view matrix and the canvas resolution
88
9+ sceneBindGroupLayout : GPUBindGroupLayout ;
10+ sceneBindGroup : GPUBindGroup ;
11+
12+ depthTexture : GPUTexture ;
13+ depthTextureView : GPUTextureView ;
14+
15+ pipeline : GPURenderPipeline ;
916 constructor ( stage : Stage ) {
1017 super ( stage ) ;
1118
1219 // TODO-2: initialize layouts, pipelines, textures, etc. needed for Forward+ here
20+ this . sceneBindGroupLayout = renderer . device . createBindGroupLayout ( {
21+ label : "forward+ scene bgl" ,
22+ entries : [
23+ {
24+ // camera uniforms
25+ binding : 0 ,
26+ visibility : GPUShaderStage . VERTEX | GPUShaderStage . FRAGMENT ,
27+ buffer : { type : "uniform" } ,
28+ } ,
29+ {
30+ // light set
31+ binding : 1 ,
32+ visibility : GPUShaderStage . FRAGMENT ,
33+ buffer : { type : "read-only-storage" } ,
34+ } ,
35+ {
36+ // cluster grid
37+ binding : 2 ,
38+ visibility : GPUShaderStage . FRAGMENT ,
39+ buffer : { type : "read-only-storage" } ,
40+ } ,
41+ {
42+ // cluster light indices
43+ binding : 3 ,
44+ visibility : GPUShaderStage . FRAGMENT ,
45+ buffer : { type : "read-only-storage" } ,
46+ } ,
47+ ] ,
48+ } ) ;
49+ this . sceneBindGroup = renderer . device . createBindGroup ( {
50+ label : "forward+ scene bg" ,
51+ layout : this . sceneBindGroupLayout ,
52+ entries : [
53+ { binding : 0 , resource : { buffer : this . camera . uniformsBuffer } } ,
54+ { binding : 1 , resource : { buffer : this . lights . lightSetStorageBuffer } } ,
55+ { binding : 2 , resource : { buffer : this . lights . clusterLightGridBuffer } } ,
56+ {
57+ binding : 3 ,
58+ resource : { buffer : this . lights . clusterLightIndexBuffer } ,
59+ }
60+ ] ,
61+ } ) ;
62+ this . depthTexture = renderer . device . createTexture ( {
63+ size : [ renderer . canvas . width , renderer . canvas . height ] ,
64+ format : "depth24plus" ,
65+ usage : GPUTextureUsage . RENDER_ATTACHMENT
66+ } ) ;
67+ this . depthTextureView = this . depthTexture . createView ( ) ;
68+ this . pipeline = renderer . device . createRenderPipeline ( {
69+ layout : renderer . device . createPipelineLayout ( {
70+ label : "Forward+ pipeline layout" ,
71+ bindGroupLayouts : [
72+ this . sceneBindGroupLayout ,
73+ renderer . modelBindGroupLayout ,
74+ renderer . materialBindGroupLayout
75+ ]
76+ } ) ,
77+ depthStencil : {
78+ depthWriteEnabled : true ,
79+ depthCompare : "less" ,
80+ format : "depth24plus"
81+ } ,
82+ vertex : {
83+ module : renderer . device . createShaderModule ( {
84+ label : "Forward+ shader (same as naive vert)" ,
85+ code : shaders . naiveVertSrc
86+ } ) ,
87+ buffers : [ renderer . vertexBufferLayout ]
88+ } ,
89+ fragment : {
90+ module : renderer . device . createShaderModule ( {
91+ label : "naive frag shader" ,
92+ code : shaders . forwardPlusFragSrc ,
93+ } ) ,
94+ targets : [
95+ {
96+ format : renderer . canvasFormat ,
97+ }
98+ ]
99+ }
100+ } ) ;
101+
13102 }
14103
15104 override draw ( ) {
16105 // TODO-2: run the Forward+ rendering pass:
17106 // - run the clustering compute shader
18107 // - run the main rendering pass, using the computed clusters for efficient lighting
108+ const encoder = renderer . device . createCommandEncoder ( ) ;
109+ const canvasTextureView = renderer . context . getCurrentTexture ( ) . createView ( ) ;
110+ this . lights . doLightClustering ( encoder ) ;
111+
112+
113+ const renderPass = encoder . beginRenderPass ( {
114+ label : "forward+ render pass" ,
115+ colorAttachments : [
116+ {
117+ view : canvasTextureView ,
118+ clearValue : [ 0 , 0 , 0 , 0 ] ,
119+ loadOp : "clear" ,
120+ storeOp : "store"
121+ }
122+ ] ,
123+ depthStencilAttachment : {
124+ view : this . depthTextureView ,
125+ depthClearValue : 1.0 ,
126+ depthLoadOp : "clear" ,
127+ depthStoreOp : "store"
128+ }
129+ } ) ;
130+ renderPass . setPipeline ( this . pipeline ) ;
131+
132+ renderPass . setBindGroup ( shaders . constants . bindGroup_scene , this . sceneBindGroup )
133+
134+ this . scene . iterate ( node => {
135+ renderPass . setBindGroup ( shaders . constants . bindGroup_model , node . modelBindGroup ) ;
136+ } , material => {
137+ renderPass . setBindGroup ( shaders . constants . bindGroup_material , material . materialBindGroup ) ;
138+ } , primitive => {
139+ renderPass . setVertexBuffer ( 0 , primitive . vertexBuffer ) ;
140+ renderPass . setIndexBuffer ( primitive . indexBuffer , 'uint32' ) ;
141+ renderPass . drawIndexed ( primitive . numIndices ) ;
142+ } ) ;
143+
144+ renderPass . end ( ) ;
145+
146+ renderer . device . queue . submit ( [ encoder . finish ( ) ] ) ;
19147 }
20148}
0 commit comments