@@ -13,17 +13,23 @@ import Data.Float32 (fromNumber')
13
13
import Data.Foldable (traverse_ )
14
14
import Data.Int (toNumber )
15
15
import Data.Int.Bits (complement , (.&.))
16
+ import Data.JSDate (getTime , now )
16
17
import Data.Maybe (Maybe (..), maybe )
18
+ import Data.Number (pi , sin )
17
19
import Data.UInt (fromInt )
18
20
import Effect (Effect )
19
21
import Effect.Aff (error , launchAff_ , throwError )
20
22
import Effect.Class (liftEffect )
21
23
import Unsafe.Coerce (unsafeCoerce )
22
24
import Web.DOM.Element (setAttribute )
23
25
import Web.DOM.NonElementParentNode (getElementById )
26
+ import Web.GPU.BufferSource (fromFloat32Array )
24
27
import Web.GPU.GPU (requestAdapter )
25
28
import Web.GPU.GPUAdapter (requestDevice )
29
+ import Web.GPU.GPUBindGroupEntry (GPUBufferBinding , gpuBindGroupEntry )
30
+ import Web.GPU.GPUBindGroupLayoutEntry (gpuBindGroupLayoutEntry )
26
31
import Web.GPU.GPUBuffer (GPUBuffer , getMappedRange , unmap )
32
+ import Web.GPU.GPUBufferBindingLayout (GPUBufferBindingLayout )
27
33
import Web.GPU.GPUBufferUsage (GPUBufferUsageFlags )
28
34
import Web.GPU.GPUBufferUsage as GPUBufferUsage
29
35
import Web.GPU.GPUCanvasAlphaMode (opaque )
@@ -35,7 +41,7 @@ import Web.GPU.GPUCommandEncoder (beginRenderPass, finish)
35
41
import Web.GPU.GPUCompareFunction as GPUCompareFunction
36
42
import Web.GPU.GPUCullMode (none )
37
43
import 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 )
39
45
import Web.GPU.GPUDevice as GPUDevice
40
46
import Web.GPU.GPUExtent3D (gpuExtent3DWHD )
41
47
import Web.GPU.GPUFragmentState (GPUFragmentState )
@@ -44,12 +50,13 @@ import Web.GPU.GPUIndexFormat (uint16)
44
50
import Web.GPU.GPULoadOp as GPULoadOp
45
51
import Web.GPU.GPUPrimitiveState (GPUPrimitiveState )
46
52
import Web.GPU.GPUPrimitiveTopology (triangleList )
47
- import Web.GPU.GPUQueue (submit )
53
+ import Web.GPU.GPUQueue (submit , writeBuffer )
48
54
import Web.GPU.GPURenderPassColorAttachment (GPURenderPassColorAttachment )
49
55
import Web.GPU.GPURenderPassDepthStencilAttachment (GPURenderPassDepthStencilAttachment )
50
56
import 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 )
52
58
import Web.GPU.GPURenderPipelineDescriptor (GPURenderPipelineDescriptor )
59
+ import Web.GPU.GPUShaderStage as GPUShaderStage
53
60
import Web.GPU.GPUStoreOp as GPUStoreOp
54
61
import Web.GPU.GPUTexture (createView )
55
62
import Web.GPU.GPUTextureDescriptor (GPUTextureDescriptor )
@@ -111,6 +118,42 @@ main = do
111
118
, 1.0
112
119
-- 🔵
113
120
]
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
114
157
-- 📇 Index Buffer Data
115
158
indices :: Uint16Array <- fromArray $ map fromInt [ 0 , 1 , 2 ]
116
159
-- 🏭 Entry to WebGPU
@@ -156,22 +199,36 @@ main = do
156
199
positionBuffer <- liftEffect $ createBufferF positions GPUBufferUsage .vertex
157
200
colorBuffer <- liftEffect $ createBufferF colors GPUBufferUsage .vertex
158
201
indexBuffer <- liftEffect $ createBufferF indices GPUBufferUsage .index
202
+ -- ✋ Declare buffer handles
203
+
204
+ uniformBuffer <- liftEffect $ createBufferF uniformData
205
+ (GPUBufferUsage .uniform .|. GPUBufferUsage .copyDst)
206
+
159
207
-- 🖍️ Shaders
160
208
let
161
209
vsmDesc =
162
210
x
163
211
{ code:
164
212
"""
213
+ struct UBO {
214
+ modelViewProj: mat4x4<f32>,
215
+ primaryColor: vec4<f32>,
216
+ accentColor: vec4<f32>
217
+ };
218
+
165
219
struct VSOut {
166
220
@builtin(position) Position: vec4<f32>,
167
221
@location(0) color: vec3<f32>,
168
222
};
169
223
224
+ @group(0) @binding(0)
225
+ var<uniform> uniforms: UBO;
226
+
170
227
@vertex
171
228
fn main(@location(0) inPos: vec3<f32>,
172
229
@location(1) inColor: vec3<f32>) -> VSOut {
173
230
var vsOut: VSOut;
174
- vsOut.Position = vec4<f32>(inPos, 1.0);
231
+ vsOut.Position = uniforms.modelViewProj * vec4<f32>(inPos, 1.0);
175
232
vsOut.color = inColor;
176
233
return vsOut;
177
234
}
@@ -231,8 +288,24 @@ fn main(@location(0) inColor: vec3<f32>) -> @location(0) vec4<f32> {
231
288
, depthCompare: GPUCompareFunction .less
232
289
}
233
290
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
+ }
234
307
-- 🦄 Uniform Data
235
- let pipelineLayoutDesc = x { bindGroupLayouts: [] }
308
+ let pipelineLayoutDesc = x { bindGroupLayouts: [ uniformBindGroupLayout ] }
236
309
layout <- liftEffect $ createPipelineLayout device pipelineLayoutDesc
237
310
238
311
-- 🎭 Shader Stages
@@ -354,6 +427,11 @@ fn main(@location(0) inColor: vec3<f32>) -> @location(0) vec4<f32> {
354
427
setVertexBuffer passEncoder 0 positionBuffer
355
428
setVertexBuffer passEncoder 1 colorBuffer
356
429
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
357
435
drawIndexedWithInstanceCount passEncoder 3 1
358
436
end passEncoder
359
437
toSubmit <- finish commandEncoder
0 commit comments