From 2df0bc2786870a6d36ae42e6f9fd16d1c810e137 Mon Sep 17 00:00:00 2001 From: PiergiorgioZagaria <75474806+PiergiorgioZagaria@users.noreply.github.com> Date: Sun, 15 May 2022 19:34:09 +0200 Subject: [PATCH] examples/gkurve: moved vertex uniform data to vertex buffer and added view (#277) --- examples/gkurve/frag.wgsl | 8 +++--- examples/gkurve/main.zig | 57 +++++++++++++++++++++++---------------- examples/gkurve/vert.wgsl | 9 +++---- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/examples/gkurve/frag.wgsl b/examples/gkurve/frag.wgsl index df41e423..bc9fd14e 100755 --- a/examples/gkurve/frag.wgsl +++ b/examples/gkurve/frag.wgsl @@ -2,12 +2,12 @@ struct FragUniform { type_: u32, padding: vec3, } -@binding(1) @group(0) var ubos: array; +@binding(1) @group(0) var ubos: array; @stage(fragment) fn main( @location(0) uv: vec2, @location(1) bary: vec3, - @interpolate(flat) @location(2) instance_index: u32, + @interpolate(flat) @location(2) triangle_index: u32, ) -> @location(0) vec4 { // Example 1: Visualize barycentric coordinates: // return vec4(bary.x, bary.y, bary.z, 1.0); @@ -17,10 +17,10 @@ struct FragUniform { // Example 2: Render gkurves var inversion = -1.0; - if(ubos[instance_index].type_ == 1u) { + if(ubos[triangle_index].type_ == 1u) { // Solid triangle return vec4(0.0, 1.0, 0.0, 1.0); - } else if(ubos[instance_index].type_ == 2u) { + } else if(ubos[triangle_index].type_ == 2u) { // Concave (inverted quadratic bezier curve) inversion = -1.0; } else { diff --git a/examples/gkurve/main.zig b/examples/gkurve/main.zig index c14f7d00..258fb309 100644 --- a/examples/gkurve/main.zig +++ b/examples/gkurve/main.zig @@ -14,11 +14,22 @@ pub const Vertex = struct { uv: @Vector(2, f32), }; // Simple triangle -const triangle_half_height = 250*@sqrt(0.75); +const WINDOW_WIDTH = 640; +const WINDOW_HEIGHT = 480; +const TRIANGLE_SCALE = 250; +const TRIANGLE_HEIGHT = TRIANGLE_SCALE * @sqrt(0.75); pub const vertices = [_]Vertex{ - .{ .pos = .{ 0, triangle_half_height, 0, 1 }, .uv = .{ 0.5, 1 } }, - .{ .pos = .{ -250, -triangle_half_height, 0, 1 }, .uv = .{ 0, 0 } }, - .{ .pos = .{ 250, -triangle_half_height, 0, 1 }, .uv = .{ 1, 0 } }, + .{ .pos = .{ WINDOW_WIDTH / 2 + TRIANGLE_SCALE / 2, WINDOW_HEIGHT / 2 + TRIANGLE_HEIGHT, 0, 1 }, .uv = .{ 0.5, 1 } }, + .{ .pos = .{ WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 0, 1 }, .uv = .{ 0, 0 } }, + .{ .pos = .{ WINDOW_WIDTH / 2 + TRIANGLE_SCALE, WINDOW_HEIGHT / 2 + 0, 0, 1 }, .uv = .{ 1, 0 } }, + + .{ .pos = .{ WINDOW_WIDTH / 2 + TRIANGLE_SCALE / 2, WINDOW_HEIGHT / 2, 0, 1 }, .uv = .{ 0.5, 1 } }, + .{ .pos = .{ WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 - TRIANGLE_HEIGHT, 0, 1 }, .uv = .{ 0, 0 } }, + .{ .pos = .{ WINDOW_WIDTH / 2 + TRIANGLE_SCALE, WINDOW_HEIGHT / 2 - TRIANGLE_HEIGHT, 0, 1 }, .uv = .{ 1, 0 } }, + + .{ .pos = .{ WINDOW_WIDTH / 2 - TRIANGLE_SCALE / 2, WINDOW_HEIGHT / 2 + TRIANGLE_HEIGHT, 0, 1 }, .uv = .{ 0.5, 1 } }, + .{ .pos = .{ WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, 0, 1 }, .uv = .{ 0, 0 } }, + .{ .pos = .{ WINDOW_WIDTH / 2 - TRIANGLE_SCALE, WINDOW_HEIGHT / 2 + 0, 0, 1 }, .uv = .{ 1, 0 } }, }; // TODO: Need to ask Ayush about this, ideally we have a square window in this example because it @@ -40,10 +51,6 @@ const FragUniform = struct { }; // TODO texture and sampler, create buffers and use an index field // in FragUniform to tell which texture to read - -// Hard-coded, if you change it remember to change it in the shaders -const num_instances = 3; - const App = @This(); pipeline: gpu.RenderPipeline, @@ -100,7 +107,7 @@ pub fn init(app: *App, engine: *mach.Engine) !void { }; const vbgle = gpu.BindGroupLayout.Entry.buffer(0, .{ .vertex = true }, .uniform, true, 0); - const fbgle = gpu.BindGroupLayout.Entry.buffer(1, .{ .fragment = true }, .uniform, true, 0); + const fbgle = gpu.BindGroupLayout.Entry.buffer(1, .{ .fragment = true }, .read_only_storage, true, 0); const bgl = engine.gpu_driver.device.createBindGroupLayout( &gpu.BindGroupLayout.Descriptor{ .entries = &.{ vbgle, fbgle }, @@ -143,16 +150,16 @@ pub fn init(app: *App, engine: *mach.Engine) !void { const vertex_uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ .usage = .{ .copy_dst = true, .uniform = true }, - .size = @sizeOf(VertexUniform) * num_instances, + .size = @sizeOf(VertexUniform), .mapped_at_creation = false, }); const frag_uniform_buffer = engine.gpu_driver.device.createBuffer(&.{ - .usage = .{ .uniform = true }, - .size = @sizeOf(FragUniform) * num_instances, + .usage = .{ .storage = true }, + .size = @sizeOf(FragUniform) * vertices.len / 3, .mapped_at_creation = true, }); - var frag_uniform_mapped = frag_uniform_buffer.getMappedRange(FragUniform, 0, num_instances); + var frag_uniform_mapped = frag_uniform_buffer.getMappedRange(FragUniform, 0, vertices.len / 3); const tmp_frag_ubo = [_]FragUniform{ .{ .type = 1, @@ -171,8 +178,8 @@ pub fn init(app: *App, engine: *mach.Engine) !void { &gpu.BindGroup.Descriptor{ .layout = bgl, .entries = &.{ - gpu.BindGroup.Entry.buffer(0, vertex_uniform_buffer, 0, @sizeOf(VertexUniform) * num_instances), - gpu.BindGroup.Entry.buffer(1, frag_uniform_buffer, 0, @sizeOf(FragUniform) * num_instances), + gpu.BindGroup.Entry.buffer(0, vertex_uniform_buffer, 0, @sizeOf(VertexUniform)), + gpu.BindGroup.Entry.buffer(1, frag_uniform_buffer, 0, @sizeOf(FragUniform) * vertices.len / 3), }, }, ); @@ -213,6 +220,13 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { }; { + // Using a view allows us to move the camera without having to change the actual + // global poitions of each vertex + const view = zm.lookAtRh( + zm.f32x4(0, 0, 1, 1), + zm.f32x4(0, 0, 0, 1), + zm.f32x4(0, 1, 0, 0), + ); const proj = zm.orthographicRh( @intToFloat(f32, engine.gpu_driver.current_desc.width), @intToFloat(f32, engine.gpu_driver.current_desc.height), @@ -220,21 +234,18 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { 100, ); - // TODO: - // Use better positioning system - const ubos = [_]VertexUniform{ - .{ .mat = zm.mul(zm.translation(250, triangle_half_height, 0), proj) }, - .{ .mat = zm.mul(zm.translation(-250, 0, 0), proj) }, - .{ .mat = zm.mul(zm.translation(250, -triangle_half_height, 0), proj) }, + const mvp = zm.mul(zm.mul(view, proj), zm.translation(-1, -1, 0)); + const ubos = VertexUniform{ + .mat = mvp, }; - encoder.writeBuffer(app.vertex_uniform_buffer, 0, VertexUniform, &ubos); + encoder.writeBuffer(app.vertex_uniform_buffer, 0, VertexUniform, &.{ubos}); } const pass = encoder.beginRenderPass(&render_pass_info); pass.setPipeline(app.pipeline); pass.setVertexBuffer(0, app.vertex_buffer, 0, @sizeOf(Vertex) * vertices.len); pass.setBindGroup(0, app.bind_group, &.{ 0, 0 }); - pass.draw(vertices.len, num_instances, 0, 0); + pass.draw(vertices.len, 1, 0, 0); pass.end(); pass.release(); diff --git a/examples/gkurve/vert.wgsl b/examples/gkurve/vert.wgsl index 5e7cf473..e7fd84a6 100644 --- a/examples/gkurve/vert.wgsl +++ b/examples/gkurve/vert.wgsl @@ -1,29 +1,28 @@ struct VertexUniform { matrix: mat4x4, } -@binding(0) @group(0) var ubos: array; +@binding(0) @group(0) var ubo: VertexUniform; struct VertexOut { @builtin(position) position_clip: vec4, @location(0) frag_uv: vec2, @location(1) frag_bary: vec3, - @interpolate(flat) @location(2) instance_index: u32, + @interpolate(flat) @location(2) triangle_index: u32, } @stage(vertex) fn main( - @builtin(instance_index) instanceIdx: u32, @builtin(vertex_index) vertex_index: u32, @location(0) position: vec4, @location(1) uv: vec2, ) -> VertexOut { var output : VertexOut; - output.position_clip = ubos[instanceIdx].matrix * position; + output.position_clip = ubo.matrix * position; output.frag_uv = uv; output.frag_bary = vec3( f32(vertex_index % 3u == 1u), f32(vertex_index % 3u == 2u), f32(vertex_index % 3u == 0u), ); - output.instance_index = instanceIdx; + output.triangle_index = vertex_index / 3u; return output; }