@@ -13,17 +13,23 @@ import Data.Float32 (fromNumber')
1313import Data.Foldable (traverse_ )
1414import Data.Int (toNumber )
1515import Data.Int.Bits (complement , (.&.))
16+ import Data.JSDate (getTime , now )
1617import Data.Maybe (Maybe (..), maybe )
18+ import Data.Number (pi , sin )
1719import Data.UInt (fromInt )
1820import Effect (Effect )
1921import Effect.Aff (error , launchAff_ , throwError )
2022import Effect.Class (liftEffect )
2123import Unsafe.Coerce (unsafeCoerce )
2224import Web.DOM.Element (setAttribute )
2325import Web.DOM.NonElementParentNode (getElementById )
26+ import Web.GPU.BufferSource (fromFloat32Array )
2427import Web.GPU.GPU (requestAdapter )
2528import Web.GPU.GPUAdapter (requestDevice )
29+ import Web.GPU.GPUBindGroupEntry (GPUBufferBinding , gpuBindGroupEntry )
30+ import Web.GPU.GPUBindGroupLayoutEntry (gpuBindGroupLayoutEntry )
2631import Web.GPU.GPUBuffer (GPUBuffer , getMappedRange , unmap )
32+ import Web.GPU.GPUBufferBindingLayout (GPUBufferBindingLayout )
2733import Web.GPU.GPUBufferUsage (GPUBufferUsageFlags )
2834import Web.GPU.GPUBufferUsage as GPUBufferUsage
2935import Web.GPU.GPUCanvasAlphaMode (opaque )
@@ -35,7 +41,7 @@ import Web.GPU.GPUCommandEncoder (beginRenderPass, finish)
3541import Web.GPU.GPUCompareFunction as GPUCompareFunction
3642import Web.GPU.GPUCullMode (none )
3743import Web.GPU.GPUDepthStencilState (GPUDepthStencilState )
38- import Web.GPU.GPUDevice (createBuffer , createCommandEncoder , createPipelineLayout , createRenderPipeline , createShaderModule , createTexture )
44+ import Web.GPU.GPUDevice (createBuffer , createBindGroupLayout , createBindGroup , createCommandEncoder , createPipelineLayout , createRenderPipeline , createShaderModule , createTexture )
3945import Web.GPU.GPUDevice as GPUDevice
4046import Web.GPU.GPUExtent3D (gpuExtent3DWHD )
4147import Web.GPU.GPUFragmentState (GPUFragmentState )
@@ -44,12 +50,13 @@ import Web.GPU.GPUIndexFormat (uint16)
4450import Web.GPU.GPULoadOp as GPULoadOp
4551import Web.GPU.GPUPrimitiveState (GPUPrimitiveState )
4652import Web.GPU.GPUPrimitiveTopology (triangleList )
47- import Web.GPU.GPUQueue (submit )
53+ import Web.GPU.GPUQueue (submit , writeBuffer )
4854import Web.GPU.GPURenderPassColorAttachment (GPURenderPassColorAttachment )
4955import Web.GPU.GPURenderPassDepthStencilAttachment (GPURenderPassDepthStencilAttachment )
5056import Web.GPU.GPURenderPassDescriptor (GPURenderPassDescriptor )
51- import Web.GPU.GPURenderPassEncoder (drawIndexedWithInstanceCount , end , setIndexBuffer , setPipeline , setScissorRect , setVertexBuffer , setViewport )
57+ import Web.GPU.GPURenderPassEncoder (drawIndexedWithInstanceCount , end , setBindGroup , setIndexBuffer , setPipeline , setScissorRect , setVertexBuffer , setViewport )
5258import Web.GPU.GPURenderPipelineDescriptor (GPURenderPipelineDescriptor )
59+ import Web.GPU.GPUShaderStage as GPUShaderStage
5360import Web.GPU.GPUStoreOp as GPUStoreOp
5461import Web.GPU.GPUTexture (createView )
5562import Web.GPU.GPUTextureDescriptor (GPUTextureDescriptor )
@@ -111,6 +118,42 @@ main = do
111118 , 1.0
112119 -- 🔵
113120 ]
121+ let
122+ makeUniformData yScale = do
123+ uniformData :: Float32Array <- fromArray $ map fromNumber'
124+ [
125+ -- ♟️ ModelViewProjection Matrix (Identity)
126+ 1.0
127+ , 0.0
128+ , 0.0
129+ , 0.0
130+ , 0.0
131+ , 1.0 * yScale
132+ , 0.0
133+ , 0.0
134+ , 0.0
135+ , 0.0
136+ , 1.0
137+ , 0.0
138+ , 0.0
139+ , 0.0
140+ , 0.0
141+ , 1.0
142+ ,
143+ -- 🔴 Primary Color
144+ 0.9
145+ , 0.1
146+ , 0.3
147+ , 1.0
148+ ,
149+ -- 🟣 Accent Color
150+ 0.8
151+ , 0.2
152+ , 0.8
153+ , 1.0
154+ ]
155+ pure uniformData
156+ uniformData <- makeUniformData 1.0
114157 -- 📇 Index Buffer Data
115158 indices :: Uint16Array <- fromArray $ map fromInt [ 0 , 1 , 2 ]
116159 -- 🏭 Entry to WebGPU
@@ -156,22 +199,36 @@ main = do
156199 positionBuffer <- liftEffect $ createBufferF positions GPUBufferUsage .vertex
157200 colorBuffer <- liftEffect $ createBufferF colors GPUBufferUsage .vertex
158201 indexBuffer <- liftEffect $ createBufferF indices GPUBufferUsage .index
202+ -- ✋ Declare buffer handles
203+
204+ uniformBuffer <- liftEffect $ createBufferF uniformData
205+ (GPUBufferUsage .uniform .|. GPUBufferUsage .copyDst)
206+
159207 -- 🖍️ Shaders
160208 let
161209 vsmDesc =
162210 x
163211 { code:
164212 """
213+ struct UBO {
214+ modelViewProj: mat4x4<f32>,
215+ primaryColor: vec4<f32>,
216+ accentColor: vec4<f32>
217+ };
218+
165219struct VSOut {
166220 @builtin(position) Position: vec4<f32>,
167221 @location(0) color: vec3<f32>,
168222};
169223
224+ @group(0) @binding(0)
225+ var<uniform> uniforms: UBO;
226+
170227@vertex
171228fn main(@location(0) inPos: vec3<f32>,
172229 @location(1) inColor: vec3<f32>) -> VSOut {
173230 var vsOut: VSOut;
174- vsOut.Position = vec4<f32>(inPos, 1.0);
231+ vsOut.Position = uniforms.modelViewProj * vec4<f32>(inPos, 1.0);
175232 vsOut.color = inColor;
176233 return vsOut;
177234}
@@ -231,8 +288,24 @@ fn main(@location(0) inColor: vec3<f32>) -> @location(0) vec4<f32> {
231288 , depthCompare: GPUCompareFunction .less
232289 }
233290
291+ uniformBindGroupLayout <- liftEffect $ createBindGroupLayout device $ x
292+ { entries:
293+ [ gpuBindGroupLayoutEntry 0 GPUShaderStage .vertex
294+ (x {} :: GPUBufferBindingLayout )
295+ ]
296+ }
297+
298+ -- 🗄️ Bind Group
299+ -- ✍ This would be used when *encoding commands*
300+ uniformBindGroup <- liftEffect $ createBindGroup device $ x
301+ { layout: uniformBindGroupLayout
302+ , entries:
303+ [ gpuBindGroupEntry 0
304+ (x { buffer: uniformBuffer } :: GPUBufferBinding )
305+ ]
306+ }
234307 -- 🦄 Uniform Data
235- let pipelineLayoutDesc = x { bindGroupLayouts: [] }
308+ let pipelineLayoutDesc = x { bindGroupLayouts: [ uniformBindGroupLayout ] }
236309 layout <- liftEffect $ createPipelineLayout device pipelineLayoutDesc
237310
238311 -- 🎭 Shader Stages
@@ -354,6 +427,11 @@ fn main(@location(0) inColor: vec3<f32>) -> @location(0) vec4<f32> {
354427 setVertexBuffer passEncoder 0 positionBuffer
355428 setVertexBuffer passEncoder 1 colorBuffer
356429 setIndexBuffer passEncoder indexBuffer uint16
430+ tn <- getTime <$> now
431+ let y = sin (tn * 0.001 * pi) * 0.4 + 0.6
432+ newBuffer <- makeUniformData y
433+ writeBuffer queue uniformBuffer 0 (fromFloat32Array newBuffer)
434+ setBindGroup passEncoder 0 uniformBindGroup
357435 drawIndexedWithInstanceCount passEncoder 3 1
358436 end passEncoder
359437 toSubmit <- finish commandEncoder
0 commit comments