From 3419f1e28eb2ea012670a9409525639a61b2fdee Mon Sep 17 00:00:00 2001 From: Peter Li Date: Mon, 21 Apr 2025 21:47:05 -0700 Subject: [PATCH] debug draw sysstem!!!11 --- engine/rend/build.zig | 3 + engine/rend/shaders/debug.frag.hlsl | 4 + engine/rend/shaders/debug.frag.json | 22 ++ engine/rend/shaders/debug.vert.hlsl | 38 ++ engine/rend/shaders/debug.vert.json | 89 +++++ engine/rend/shaders/lit_mesh.frag.hlsl | 24 +- engine/rend/src/sgpu/DebugDrawSystem.zig | 350 ++++++++++++++++-- engine/rend/src/sgpu/mesh-pool.zig | 1 - engine/rend/src/sgpu/renderer.zig | 78 ++-- .../content/_shaders/dxil/debug.frag.dxil | Bin 0 -> 2844 bytes .../content/_shaders/dxil/debug.vert.dxil | Bin 0 -> 5080 bytes .../content/_shaders/dxil/lit_mesh.frag.dxil | Bin 5200 -> 5164 bytes projects/content/_shaders/msl/debug.frag.msl | 22 ++ projects/content/_shaders/msl/debug.vert.msl | 40 ++ .../content/_shaders/msl/lit_mesh.frag.msl | 29 +- projects/content/_shaders/spv/debug.frag.spv | Bin 0 -> 492 bytes projects/content/_shaders/spv/debug.vert.spv | Bin 0 -> 1456 bytes .../content/_shaders/spv/lit_mesh.frag.spv | Bin 2496 -> 2288 bytes projects/sampleGame/main.zig | 5 +- 19 files changed, 592 insertions(+), 113 deletions(-) create mode 100644 engine/rend/shaders/debug.frag.hlsl create mode 100644 engine/rend/shaders/debug.frag.json create mode 100644 engine/rend/shaders/debug.vert.hlsl create mode 100644 engine/rend/shaders/debug.vert.json create mode 100644 projects/content/_shaders/dxil/debug.frag.dxil create mode 100644 projects/content/_shaders/dxil/debug.vert.dxil create mode 100644 projects/content/_shaders/msl/debug.frag.msl create mode 100644 projects/content/_shaders/msl/debug.vert.msl create mode 100644 projects/content/_shaders/spv/debug.frag.spv create mode 100644 projects/content/_shaders/spv/debug.vert.spv diff --git a/engine/rend/build.zig b/engine/rend/build.zig index 3e3f47e..d00ab36 100644 --- a/engine/rend/build.zig +++ b/engine/rend/build.zig @@ -36,6 +36,9 @@ pub fn build(b: *std.Build) void { sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "meshes.vert", b.path("shaders/meshes.vert.json")); sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "lit_mesh.frag", b.path("shaders/lit_mesh.frag.json")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.frag", b.path("shaders/debug.frag.json")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.vert", b.path("shaders/debug.vert.json")); + // ========== tests ========== const tests = b.addTest(.{ .target = target, diff --git a/engine/rend/shaders/debug.frag.hlsl b/engine/rend/shaders/debug.frag.hlsl new file mode 100644 index 0000000..0fb7dea --- /dev/null +++ b/engine/rend/shaders/debug.frag.hlsl @@ -0,0 +1,4 @@ +float4 main(float3 Color : TEXCOORD0) : SV_Target0 +{ + return float4(Color, 1.0); +} diff --git a/engine/rend/shaders/debug.frag.json b/engine/rend/shaders/debug.frag.json new file mode 100644 index 0000000..3691330 --- /dev/null +++ b/engine/rend/shaders/debug.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec3", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_Target0", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/rend/shaders/debug.vert.hlsl b/engine/rend/shaders/debug.vert.hlsl new file mode 100644 index 0000000..032bcf0 --- /dev/null +++ b/engine/rend/shaders/debug.vert.hlsl @@ -0,0 +1,38 @@ +struct Input +{ + float3 Position : TEXCOORD0; + + uint Instance : SV_InstanceID; +}; + +struct Output +{ + float3 Color : TEXCOORD0; + float4 Position : SV_Position; +}; + +struct Scene +{ + float4x4 Model; + float3 Color; +}; + +StructuredBuffer scene: register(t0, space0); + +cbuffer Uniforms : register(b0, space1) +{ + float4x4 ViewProjection; +}; + +Output main(Input input) +{ + Output output; + + float4 pos = float4(input.Position, 1.0); + + output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos)); + output.Color = scene[input.Instance].Color; + + return output; +} + diff --git a/engine/rend/shaders/debug.vert.json b/engine/rend/shaders/debug.vert.json new file mode 100644 index 0000000..f3b65c7 --- /dev/null +++ b/engine/rend/shaders/debug.vert.json @@ -0,0 +1,89 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_7" : { + "name" : "Scene", + "members" : [ + { + "name" : "Model", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "Color", + "type" : "vec3", + "offset" : 64 + } + ] + }, + "_6" : { + "name" : "type.StructuredBuffer.Scene", + "members" : [ + { + "name" : "_m0", + "type" : "_7", + "array" : [ + 0 + ], + "array_size_is_literal" : [ + true + ], + "offset" : 0, + "array_stride" : 80 + } + ] + }, + "_9" : { + "name" : "type.Uniforms", + "members" : [ + { + "name" : "ViewProjection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + } + ] + } + }, + "inputs" : [ + { + "type" : "vec3", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec3", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ssbos" : [ + { + "type" : "_6", + "name" : "scene", + "readonly" : true, + "block_size" : 0, + "set" : 0, + "binding" : 0 + } + ], + "ubos" : [ + { + "type" : "_9", + "name" : "type.Uniforms", + "block_size" : 64, + "set" : 1, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl index ec0888f..eeffff9 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -30,18 +30,18 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo float cutoffFactor = 0.5; float dist = length(lightPos - fragPos); float attenuation = 1.0 / (dist * 2); - if (dist > cutoff1) - { - attenuation *= cutoffFactor; - } - if (dist > cutoff2) - { - attenuation *= cutoffFactor; - } - if (dist > maxDist) - { - attenuation = 0; - } + //if (dist > cutoff1) + //{ + // attenuation *= cutoffFactor; + //} + //if (dist > cutoff2) + //{ + // attenuation *= cutoffFactor; + //} + //if (dist > maxDist) + //{ + // attenuation = 0; + //} diffuse *= attenuation; diff --git a/engine/rend/src/sgpu/DebugDrawSystem.zig b/engine/rend/src/sgpu/DebugDrawSystem.zig index 371baad..807bc43 100644 --- a/engine/rend/src/sgpu/DebugDrawSystem.zig +++ b/engine/rend/src/sgpu/DebugDrawSystem.zig @@ -1,7 +1,21 @@ pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This()); allocator: std.mem.Allocator, +debugDraws: core.RingQueueU(DebugPrimitive), + device: *gpu.GPUDevice = undefined, +renderer: *Renderer = undefined, +pipeline: *gpu.GPUGraphicsPipeline = undefined, + +ssbo: *gpu.GPUBuffer = undefined, +ssobUpload: *gpu.GPUTransferBuffer = undefined, + +meshes: [@as(usize, @intCast(@intFromEnum(DebugPrimitiveType.box) + 1))]?rend.IndexedMesh = .{ null, null, null }, +deltaTime: f64 = 0, + +drawsThisFrame: std.ArrayListUnmanaged(DebugPrimitive) = .{}, + +pub const MaxObjectCount = 4096; const assetReferences = [_]assets.AssetImportReference{ assets.MakeImportRefOptions( @@ -24,6 +38,7 @@ const assetReferences = [_]assets.AssetImportReference{ pub fn create(allocator: std.mem.Allocator) !*@This() { const self = try allocator.create(@This()); self.* = .{ + .debugDraws = try core.RingQueueU(DebugPrimitive).init(allocator, MaxObjectCount), .allocator = allocator, }; core.engine_logs("[DebugDrawSystem] starting up..."); @@ -34,53 +49,327 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { try assets.loadList(assetReferences); + gDebugDrawSys = self; + return self; } +pub fn updateMeshes(self: *@This()) void { + + // line = 0, + // sphere = 1, + // box = 2, + const list: [3][]const u8 = .{ + "m_debug_line", // 0 + "m_debug_sphere", // 1 + "m_debug_box", // 2 + }; + + for (list, 0..) |path, i| { + self.meshes[i] = rend.getMesh(path); + } +} + +pub fn tick(self: *@This(), dt: f64) void { + self.deltaTime = dt; + + if (self.meshes[0] == null) { + self.updateMeshes(); + } +} + +// ========= Rendering section ========= +pub fn onUpload(p: *anyopaque, copyPass: *gpu.GPUCopyPass) void { + const self: *@This() = @ptrCast(@alignCast(p)); + + const count = self.debugDraws.count(); + { + const uploadMapped: [*]debug_vert.Scene = @ptrCast(@alignCast(self.device.mapGPUTransferBuffer(self.ssobUpload, true))); + defer self.device.unmapGPUTransferBuffer(self.ssobUpload); + + var offset: usize = 0; + + self.drawsThisFrame.clearRetainingCapacity(); + + while (offset < count) { + var primitive: DebugPrimitive = self.debugDraws.pop().?; + uploadMapped[offset] = .{ + .Model = primitive.resolve(), + .Color = @bitCast(primitive.color), + }; + + self.drawsThisFrame.append(self.allocator, primitive) catch unreachable; + + primitive.duration -= @as(f32, @floatCast(self.deltaTime)); + offset += 1; + if (primitive.duration >= 0) { + // push this primitive so that it goes to the next frame + self.debugDraws.push(primitive) catch continue; + } + } + } + + if (count > 0) { + copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.ssobUpload, .offset = 0 }, &.{ + .buffer = self.ssbo, + .offset = 0, + .size = @intCast(count * @sizeOf(debug_vert.Scene)), + }, true); + } +} + +pub fn postMesh(p: *anyopaque, cmd: *gpu.GPUCommandBuffer, renderpass: *gpu.GPURenderPass) void { + const self: *@This() = @ptrCast(@alignCast(p)); + + if (self.meshes[0] == null) { + return; + } + + renderpass.bindGPUGraphicsPipeline(self.pipeline); + renderpass.bindGPUVertexStorageBuffers(0, &self.ssbo, 1); + + for (self.drawsThisFrame.items, 0..) |draw, i| { + var mesh: rend.IndexedMesh = undefined; + switch (draw.primitive) { + .box => { + mesh = self.meshes[2].?; + }, + .sphere => { + mesh = self.meshes[1].?; + }, + .line => { + mesh = self.meshes[0].?; + }, + } + + renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i)); + } + _ = cmd; +} +// ========= End of Rendering section ========= + +pub fn createBuffers(self: *@This()) !void { + self.ssbo = self.device.createGPUBuffer(&.{ + .usage = .{ .bufferusageGraphicsStorageRead = true, .bufferusageVertex = true }, + .size = MaxObjectCount * @sizeOf(debug_vert.Scene), + .props = 0, + }); + + self.ssobUpload = self.device.createGPUTransferBuffer(&.{ + .usage = .transferbufferusageUpload, + .size = MaxObjectCount * @sizeOf(debug_vert.Scene), + .props = 0, + }); +} + +pub fn createPipeline(self: *@This()) !*gpu.GPUGraphicsPipeline { + const vertex = try rend.context().loadShader("debug.vert", debug_vert.LoadArgs); + const fragment = try rend.context().loadShader("debug.frag", debug_frag.LoadArgs); + + var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); + pci.vertex_shader = vertex; + pci.fragment_shader = fragment; + + var attributes = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator); + defer attributes.deinit(); + + var offset: u32 = 0; + { + try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); + } + + pci.vertex_input_state = .{ + .num_vertex_buffers = 1, + .vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{ + .{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 }, + }, + .num_vertex_attributes = @intCast(attributes.items.len), + .vertex_attributes = @ptrCast(attributes.items.ptr), + }; + + pci.depth_stencil_state.compare_op = .compareopLess; + pci.depth_stencil_state.enable_depth_test = true; + pci.depth_stencil_state.enable_depth_write = true; + pci.depth_stencil_state.write_mask = 0xff; + + pci.target_info.has_depth_stencil_target = true; + pci.target_info.depth_stencil_format = .textureformatD32Float; + pci.target_info.num_color_targets = 1; + pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ + .{ + .format = self.device.getGPUSwapchainTextureFormat(rend.context().window), + .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + }, + }; + + pci.rasterizer_state.fill_mode = .fillmodeLine; + const pipe = self.device.createGPUGraphicsPipeline(&pci); + + return pipe; +} + +fn addAttribute(list: *std.ArrayList(gpu.GPUVertexAttribute), offset: *u32, size: u32, format: gpu.GPUVertexElementFormat) !void { + try list.append(.{ .location = @intCast(list.items.len), .offset = offset.*, .format = format, .buffer_slot = 0 }); + offset.* = offset.* + size; +} + pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void { + core.engine_logs("[DebugDrawSystem] registering to renderer..."); self.device = device; + self.renderer = rend.context(); + self.pipeline = try self.createPipeline(); + try self.createBuffers(); + + //core.installDebugDrawInterface(self.allocator, newInterface: DebugDrawInterface); + try core.installDebugDrawInterface(self.allocator, .{ + .debugSphereFn = debugSphere, // : *const fn (pos: core.Vectorf, radius: f32, DebugDrawParams) void, + .debugBoxFn = debugBox, // : *const fn (pos: core.Vectorf, extents: core.Vectorf, DebugDrawParams) void, + .debugLineFn = debugLine, // : *const fn (start: core.Vectorf, end: core.Vectorf, DebugDrawParams) void, + }); } pub fn destroy(self: *@This()) void { + self.debugDraws.deinit(self.allocator); + self.drawsThisFrame.deinit(self.allocator); self.allocator.destroy(self); } +// ==================== Primitives =================== + +pub const DebugLine = struct { + start: core.Vectorf, + end: core.Vectorf, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + var delta = self.start.sub(self.end); + const d = delta.normalize(); + const axz = std.math.atan2(-d.z, d.x) + core.radians(180.0); + const ay = -std.math.asin(d.y); + const mat1 = core.zm.matFromRollPitchYaw(0, 0, ay); + const mat2 = core.zm.rotationY(axz); + const len = delta.length(); + return core.zm.mul(core.zm.mul( + core.zm.mul(mat1, mat2), + core.zm.scaling(len, len, len), + ), core.zm.translationV(self.start.toZm())); + } +}; + +pub const DebugSphere = struct { + position: core.Vectorf, + radius: f32, + rotation: core.Quat, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + return core.zm.mul(core.zm.mul( + core.zm.matFromQuat(self.rotation), + core.zm.scaling(self.radius, self.radius, self.radius), + ), core.zm.translationV(self.position.toZm())); + } +}; + +pub const DebugBox = struct { + position: core.Vectorf, + extents: core.Vectorf, + rotation: core.Quat, + + pub fn resolve(self: @This(), _: anytype) core.Transform { + return core.zm.mul(core.zm.mul( + core.zm.matFromQuat(self.rotation), + core.zm.scalingV(self.extents.toZm()), + ), core.zm.translationV(self.position.toZm())); + } +}; + +const DebugPrimitiveType = enum(u8) { + line = 0, + sphere = 1, + box = 2, +}; + +pub const DebugPrimitive = struct { + primitive: union(DebugPrimitiveType) { + line: DebugLine, + sphere: DebugSphere, + box: DebugBox, + }, + color: core.Vectorf = .{ .x = 0.0, .y = 1.0, .z = 0.0 }, + duration: f32 = 0.0, + + pub fn resolve(self: @This()) core.Transform { + // comptime core.asserts(@sizeOf(DebugPrimitiveGpu) == DebugPrimitiveGpu.TargetSize, ""); + + switch (self.primitive) { + .line => |inner| { + return inner.resolve(.{}); + }, + .sphere => |inner| { + return inner.resolve(.{}); + }, + .box => |inner| { + return inner.resolve(.{}); + }, + } + unreachable; + + // return core.implement_func_for_tagged_union_nonull(self.primitive, "resolve", core.Transform, .{}); + } +}; + +const DebugPrimitiveGpu = struct { + const UnpaddedSize = @sizeOf(core.Transform) + @sizeOf(core.Vectorf); + const TargetSize = 80; + + model: core.Transform, + color: core.Vectorf, + + pad: [TargetSize - UnpaddedSize]u8 = std.mem.zeroes([TargetSize - UnpaddedSize]u8), +}; + +const DebugDrawSharedInstance = struct {}; + +const DebugSharedData = struct { + drawsThisFrame: std.ArrayListUnmanaged(DebugPrimitive) = .{}, + lock: std.Thread.Mutex = .{}, + + pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void { + self.drawsThisFrame.deinit(allocator); + } +}; + +const objectCount = 2048; + +// ==================== End of primitives ============ + +var gDebugDrawSys: *@This() = undefined; + pub fn debugSphere(position: core.Vectorf, radius: f32, params: DebugDrawParams) void { - _ = position; - _ = radius; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ .sphere = .{ .position = position, .radius = radius, .rotation = params.rotation } }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ .sphere = .{ .position = position, .radius = radius, .rotation = params.rotation } }, + .color = params.color, + .duration = params.duration, + }) catch return; } pub fn debugLine(start: core.Vectorf, end: core.Vectorf, params: DebugDrawParams) void { - _ = start; - _ = end; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ .line = .{ - // .start = start, - // .end = end, - // } }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ .line = .{ + .start = start, + .end = end, + } }, + .color = params.color, + .duration = params.duration, + }) catch return; } pub fn debugBox(position: core.Vectorf, extents: core.Vectorf, params: DebugDrawParams) void { - _ = position; - _ = extents; - _ = params; - // gDebugDrawSys.debugDraws.push(.{ - // .primitive = .{ - // .box = .{ .position = position, .extents = extents, .rotation = params.rotation }, - // }, - // .color = params.color, - // .duration = params.duration, - // }) catch return; + gDebugDrawSys.debugDraws.push(.{ + .primitive = .{ + .box = .{ .position = position, .extents = extents, .rotation = params.rotation }, + }, + .color = params.color, + .duration = params.duration, + }) catch return; } const DebugDrawParams = core.DebugDrawParams; @@ -93,6 +382,9 @@ const sdl3 = @import("sdl3"); const gpu = sdl3.gpu; const std = @import("std"); +const debug_frag = @import("debug.frag"); +const debug_vert = @import("debug.vert"); +const Renderer = @import("renderer.zig").Renderer; const primitive_box align(8) = @embedFile("embedded/primitive_box.obj").*; const primitive_line align(8) = @embedFile("embedded/primitive_line.obj").*; const primitive_sphere align(8) = @embedFile("embedded/primitive_sphere.obj").*; diff --git a/engine/rend/src/sgpu/mesh-pool.zig b/engine/rend/src/sgpu/mesh-pool.zig index 26c219b..cd69af1 100644 --- a/engine/rend/src/sgpu/mesh-pool.zig +++ b/engine/rend/src/sgpu/mesh-pool.zig @@ -170,7 +170,6 @@ pub fn getMesh(name: []const u8) ?rend.IndexedMesh { } pub fn getMeshByName(name: *core.Name) ?rend.IndexedMesh { - core.engine_log("getMeshByName {d}", .{name.handle()}); return gMeshPool.installedMeshes.get(name.handle()); } diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 2ed8dbc..a38f5cc 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -31,6 +31,7 @@ pub const Renderer = struct { uploads: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCopyPass) void }) = .{}, uploadCleanup: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque) void }) = .{}, + postMesh: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer, *gpu.GPURenderPass) void }) = .{}, postRenders: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{}, destroys: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque) void }) = .{}, preDraws: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{}, @@ -80,8 +81,8 @@ pub const Renderer = struct { core.engine_log("sgpu device created, using shader format: {s}", .{self.shaderSuffix}); - // try self.createPipeline(); try self.createMeshPipeline(); + try self.createBuffers(); try self.createDepthTexture(); self.meshPool = try self.createRendererObject(MeshPool); @@ -108,7 +109,7 @@ pub const Renderer = struct { var defaultTextureName = core.MakeName("t_default"); self.defaultTexture = getTexture(&defaultTextureName).?; - self.debugDrawSys = try core.createObject(DebugDrawSystem, .{}); + self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); } pub fn createSamplers(self: *@This()) !void { @@ -137,6 +138,10 @@ pub const Renderer = struct { try self.postRenders.append(self.allocator, .{ .ptr = object, .func = T.postRender }); } + if (@hasDecl(T, "postMesh")) { + try self.postMesh.append(self.allocator, .{ .ptr = object, .func = T.postMesh }); + } + if (@hasDecl(T, "onPreDraw")) { try self.preDraws.append(self.allocator, .{ .ptr = object, .func = T.onPreDraw }); } @@ -146,6 +151,8 @@ pub const Renderer = struct { const object = try core.createObject(T, .{}); try object.setup(self.device); + try self.registerRendererObject(T, object); + return object; } @@ -243,6 +250,9 @@ pub const Renderer = struct { pci.rasterizer_state.fill_mode = .fillmodeFill; self.meshPipe = self.device.createGPUGraphicsPipeline(&pci); + } + + pub fn createBuffers(self: *@This()) !void { // ssbo buffer @@ -261,20 +271,23 @@ pub const Renderer = struct { } pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) !void { - const uploadMapped: [*]meshes_vert.Scene = @ptrCast(@alignCast(self.device.mapGPUTransferBuffer(self.ssboSceneUpload, true))); - self.device.unmapGPUTransferBuffer(self.ssboSceneUpload); - const container = rend.MeshComponent.BaseContainer; const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); - for (0..uploadCount) |i| { - // const object = &container.dense.items[i].value; - const objectId = container.dense.items[i].sparseIndex; - var transform = core.zm.identity(); + { + const uploadMapped: [*]meshes_vert.Scene = @ptrCast(@alignCast(self.device.mapGPUTransferBuffer(self.ssboSceneUpload, true))); + defer self.device.unmapGPUTransferBuffer(self.ssboSceneUpload); - if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| { - transform = repr.transform; + // iterate over MeshComponents + for (0..uploadCount) |i| { + // const object = &container.dense.items[i].value; + const objectId = container.dense.items[i].sparseIndex; + var transform = core.zm.identity(); + + if (core.Scene.SceneObjectContainer.get(objectId, ._repr)) |repr| { + transform = repr.transform; + } + uploadMapped[i].Model = @bitCast(transform); } - uploadMapped[i].Model = @bitCast(transform); } if (uploadCount == 0) @@ -287,40 +300,6 @@ pub const Renderer = struct { }, true); } - pub fn createPipeline(self: *@This()) !void { - const vertex = try self.loadShader("sample.vert", sample_vert.LoadArgs); - const fragment = try self.loadShader("sample.frag", .{}); - - var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); - pci.fragment_shader = fragment; - pci.vertex_shader = vertex; - - pci.target_info.num_color_targets = 1; - pci.target_info.has_depth_stencil_target = true; - pci.target_info.depth_stencil_format = .textureformatD32Float; - pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ - .{ - .format = self.device.getGPUSwapchainTextureFormat(self.window), - .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), - }, - }; - - pci.rasterizer_state.fill_mode = .fillmodeFill; - self.testPipeline = self.device.createGPUGraphicsPipeline(&pci); - - self.colorBuffer = self.device.createGPUBuffer(&.{ - .usage = .{ .bufferusageVertex = true, .bufferusageGraphicsStorageRead = true }, - .size = 8192 * 2, - .props = 0, - }); - - self.colorBufferTransfer = self.device.createGPUTransferBuffer(&.{ - .usage = .transferbufferusageUpload, - .size = 8192 * 2, - .props = 0, - }); - } - pub fn loadShader( self: *@This(), shaderName: []const u8, @@ -458,6 +437,7 @@ pub const Renderer = struct { const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget); //renderpass.bindGPUGraphicsPipeline(self.testPipeline); + renderpass.bindGPUGraphicsPipeline(self.meshPipe); renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1); @@ -498,6 +478,10 @@ pub const Renderer = struct { } } + for (self.postMesh.items) |interface| { + interface.func(interface.ptr, cmd, renderpass); + } + renderpass.endGPURenderPass(); for (self.postRenders.items) |interface| { @@ -517,6 +501,8 @@ pub const Renderer = struct { for (self.destroys.items) |d| { d.func(d.ptr); } + + self.postMesh.deinit(self.allocator); self.uploadCleanup.deinit(self.allocator); self.preDraws.deinit(self.allocator); self.postRenders.deinit(self.allocator); diff --git a/projects/content/_shaders/dxil/debug.frag.dxil b/projects/content/_shaders/dxil/debug.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..75770c40ed6abb8cf37807d05168b7a92601217f GIT binary patch literal 2844 zcmeHJeM}o=7=PP4dIie$7-cI^mMb5%Ok_vdC`d`#9_?T&8M9>)v&9z1WD&YjItHlm z`Z2DX)pQJ{+tkqMaB8A1E^g>dkRsN~CYw{)oXQ--X>j7=qDG^>$H$_^m}sJZ`K0gj zJn!%Mxc8p-@=Gh~^t7O`@4NoGXQoPvzv~Ns<{jq&0Az^(V9;vdGQs7CYXq)37?cVC zSOu5aSVajTwkTERHHE9-hO1x1m5V`Wkp&;)8bh%d>ge_B@2KGX^?y;Th4IB&F_#R* zyzy>}&3R9w3;H$YjZ^?y?%97Pzd+$|9*_I|UJ@3z1ZQs^sKvI;KK~vZ%*7V#cz^~7 zpF`(`2Pz2eY+Rg!(Rmn{Ejr5yxUs^00Ss2uRhhUXu2(Y`|sfKZk8@O+}&IAPjy^r3o&F!1#~iFzNQl9ULg>k?FYe`QcY(nkMbkfzd4 zRpPPcvK zL&eQkl_iWPx9mbwvYz%qb=emVN|u=XfkdCrL{Qlv7wk!6O8HbMTf3*Q!cwtOL>@{X zb~E{~K1JdjVqI3YxQXp-LZF}YVh!Fhj(0%~#9b8T?8n+jtR;xIE;=2HPOBB;62=8z z{3fkki*;Es*SKJsz}n|CtvKv3pE(Uf{TR$?nZ#kAg${EF{p8J$5P)utfVg>wqE3Rm zc~Mb54_*UMEe}c3l1;%tykgBLN*`Jxe zo*)S{?!;g`e?zkr_k~E|kiZ(z=D*X;oTo%if}DK?c8Yf^sx~W@WEm1Q^4Ck7OTTMBSB5V~3x3;OO2np><_H z9(d{?NyG#Z(P@zM(yAKoist6_mV#|t8tpE#r#~U>$%i)Yzqskb!H;^GCVltk^~*-L z-lCl@NXHsNTgpr{6^;Kuxu+8H<#wk7(>dVba? zvd$3O8FJ@eo5in9;x~ry849V7hGkP>+1Q-EXp_a{vJrP?%qI9CNS8+G($Jhf5h>}V zOZ-S#Z)7EW=ue)qb4b}skw8?A-S0r01l#67xOcI#jwrkH2-X#HYo-{nT`Rsaj?cn* zwUUrupj}EO^?j}R`7_|1(43oEcD#lEzT=0}m)Gq}Nmi~dpF;qOkV!CgPAYZgO38w6 zL}FuNJWcV%>681f_vOCAaoOYox0U>X+oHeWww3>L+rP(c3wHy}KjJojz0&Jcil6I& zJm*meD+=e7_@yeY6z%Ar%$gs>sPR-Tc)q)tSaEMeuc^tYMhq1nc7q00;|)WqV&_Jq znxj3A)%;t$H9H{fd5iPXOR}yPqn~!m5yVQLDX{@iJ25eHVbj@Y?Bdk{RF|sKEPG8g zICxBbJdbzACwlkIg21U4O!l?bbMi>remXJx)_wPOW#8Ixa7oUN=5RgK_Xl;#z4oGu=(8F_P)?N|K cr!$+@)XEpq$qzTwRxhMScUV$sl4}co1sW1XlK=n! literal 0 HcmV?d00001 diff --git a/projects/content/_shaders/dxil/debug.vert.dxil b/projects/content/_shaders/dxil/debug.vert.dxil new file mode 100644 index 0000000000000000000000000000000000000000..89a9c46e35302ac71215e2ad4aab2e3c8b8316f6 GIT binary patch literal 5080 zcmeHLeN+=y7M~=;%mk7!F<=7$IuT64q7JCw2ii;$5jCu#_<@3_6Dl;dBt}sb?Y1FA z5^S{5Vnt9-z)Cr7*T$9>v0q6*o8~}^mez=@2P?YNgDz`rYtQM~?wgQM+rM`I*gy7c z-PL_12O1xn`7@teaq0jIf}ns1f>6-sfT{+y1Jned zNMJ*diVHzBsD-)9NesxtWqIMU3>v%u2o#p*g_WS^gvKc2I8+KkJ%eZF4OXTBW%be` z<*HRrs-VKPPc1i8Zr2)~E?cgGpjH3wJmDaKukbvKYbFk+j|P<~56`37Qu*xmXSWy_ zxu$R}`2h5DK@Ek(h$qW0pfGYan|Xd)!1e|AK^*EIw&#bS@NZ3^sL(rO^J`F((do6% z8Ybhw0VM2`1t}-@mN8|qC^n;uWL`iC>K_V_#ZqxNVDfRG3s(mBBhx%o3RhFB32;_4 z@ZbXuRYl9y%%sfR7?3NJ?rTyW1bqTzQD!2zUS{2BP4Yp?2QNqP%ms&77T)v-EG`Lt zsnjH1%2phTQuN@NG4nC;%E-)8Tb?6^Q0CfBL2;RikvxGznB1eG3To`vYj5s@Gjfpv zuo=uTO6(zJ<8If#%&%<&V?e&p<9@nJ^-a%kmD-KQNS}3HZ$>>7^3j= za(_Yh%~b(q-jdFO^DERZY`tm|*J+*KoVb4Pu`y}N6L6DOs_Bn0OB2i|p5*nAyqG>A zeBKD`WvzzzSuc8%6!+FCHq?K%%pi${DO{D7?v-Na5VqizHro{0i`_DXq|WAeZU2nO zX$lrKNU}3hSUUsP^S)%$f_XoQe!xGuO6(P7Oo?20@1ChK8HxbwjM?V4Zl|qTI%~C# z1IGNfH3EIVU^i%?=-ni`&52eLsNNyi8XoKl54O@M1L#M-eF#=1M|acc_I~6Rj#f<| zX#wysfxHD&P84AD!vf$Zy)8ims(_cgPeTM(1`%mH>y^aE4$@Dg1! zNL{EJL~z}eZAk8g2ozpwza^6)&&Xa+FH_=b9NT1; zr${U{0Ro33KIr1ITPnl?OCwQH>Mk|B)%%wUvpiigMX??$r7>FBuf~^d=uj8?Gca3^i}KBHlRI zd=;+I$uP^iTDR*tvph!xvzrL~A_AW|txnD|)Z#lNNb5Zr#&)p+B(B8~2|FV|@@Ntf z!6a78r{WyCsFjt;iZzyb_wT1HolB*j<|=CRn2oDAsK-0>-3lia-|hjA8?nT9u$t4} zd^@Fc!8x+?%sVNqTt!PhzE5w~7$vYi;Noq8(5)_HGwJg_WDZ zE>;VocbEBZN8Q%X+CS?~AF$glf)#^=uG*!IyG!r`G=H3S*HZlZbS;hUacSE*OCTAh z9oFO669J9M6L+8WJvz5HaLqegwR zIU!MaF7w0L?{|{#aM{{3?JFx!HeVgKm{aZSv<7q9F?L;K@r-uw4BeVQU~I7DlFvUh z+6GgxnK_SqklEGMk=>cbx@h5jaekJ)@3h*mLNg%kt~{!YN`Cy6=XNJQ{&e#cqRcm5 zGUC5=?e@q8|E)H-a5}I(mvij;jbIMmlXy*<5RfK%wMpe<{h|+R7xgO_ zbZ~M$tj)1-7WIzDRDqMxq1ig?Hqe@^Mu*i%qgAPB)q@D&cBjeu6lUEjwr*>*RyWq9 z-yIj+9Tt4=7L1XcQeR8LNJ~O*upQDS_@xOwHHm&L^0h;`z^7c$7;MjW&u>u9w{aFV zbk7Ep{%l?}z**$#w)>>$^G41#+*)bmFl(W$MxS+OJG#5ECTGMHZIDOb>=!VcwUvM% z@IX~^{*k}uydaN_5FQqg4}5xwC#&S+?;a>Zk_HP4YkX?x{kXjDn~Pqat%6CRw4WEH zWqoP<>GK=21*EM{nGZhEWhCS0pWi^Wft-Pn3D+aLg6_GG?-r|9gM>_Qpml(+^ z)m*9E^3!>}1oA+64CO$1RACe$S!AzLxYz(#i9;7{_}#k?O=}`zF2XI2EVu`5 zX#`|Bhayh!%|GgkZ0f6L^`kaEFQ8uk=jmO27x#AUKRjKSk4J7cYgUUa-a%qlcU>7? zn?Z045FY~j~YvXl^ok({) zuUJxnUvl%ac)D@K4NG}0K3j-N_C?ilRtVm3ow@Q}*J}q4cU{cqnrCdC*Fuk&3i0~oysb8Km>;5CKl=YkxkD1;uHuo z*J#lrlCzY!V!{zU#QFi*LLw!?SM6c~=sok$A>po*T$YA|BqJD@%Xr1}I;ym7g$l=i`pw(WFjm3me^1KGo7!k%$9XA$|y=X!Tok7_uu{$Jdbs=l}gR)DL zvQxvzdI)7~*TjW!?KoOO24#V?u)jCu=u>o1)*K(koi?JS_y`kA!>33%zVuNl4t}1A zITkU1JqxbmqT*2}H6AqI1fh#2mU4Nf$r}&1GSD5!wlMTtZ|Ye}6UjuhS&oLi&TdpB z!0in5E2Jt6tx?YCr(6uwXduVVcwDa|-AVDhJ>}%sL67S(@FM2zx#s$mzh}^8#k_+V*JKchit6f@~tOY~G%3S2pjtzzp9rJrGNd^IBg>MJr;> zLh#$3B5gl=5?pJrbhq>Az~hq$M;63^g7EvD$@p8SK`Xal4G?)v+_|;shqyx<$XZ1(_MYF8n07hb|OP zhU3bs|1>I>heNQ3m=blk=zTi08)u5@IZ?ecI6qBfEwy^;Oldt8+RuaQ&sx5Vm^gL( z`1zHoCG`6ENuM3IdOt6`2?GjQYX%mYVZ%#Db#8(@%^#UFksJlZ18^I-WWfwq8MLB- zI5_0?qx1RlO}KsHPEC6x%QLkiW9m+F;>ztS3Bbj!^Q!`(`$!LSS;h>&N;R4 zb#aKsb~@=reVynM;pxM|#lVmNRM^PGzyRVi0Cfof`ENKG7@V9B+*9OXV5r#a$+e!1 z_cTygn8i^CBrQ9cRZwBFk)TNZjJ-22-IZwUy1x8Hui%ws`nT^%INqGCdB0b%L4jk{ z0|PgPCWVgXgA$A!O$r=b$_&XY3LH%z%-ud5%X?F23^a;?L79z{p($a)QO8iW{10q* zIvklA6eLoL5+*Xr9B?#Gn!upI!FE$7CQX37@IkMH3Ij(|<3{$&(kB?DJe2FfdJ{e{ zva%O{@P(L^@WoM-y<`I06^Ka^bqO~eW!E^GLQFa)A5)&do|FJJiIGb}?hd1L3{-22 zQyY851GXDbt&0{sb(EXpXqNN=4i;l$9R#!-JTh!Q4N4RGMVo5YNIXeyW|x-LcgGFjgA5H&l?VG9}JBI9wZ-&^rYb=|cX4DAL~?xH!N`mVp5P)}S8+ delta 940 zcmY*YZAcSg9Di=R-JNsOo2J~DZl_x|bJ>k@BG%Z=VF`YSKE$Gk^CcQJ%FrTewB5Pn z7>iAUD8ICdD0(4RUxXrdy4reQ=!Xh12_Xa_lRjt|^lZC=?$hu2z3}{=|MT2^YtE|o zc-T=+$9~VvoIR`+ZRtqKUg4lP5(%q7Xu$e-%ifNZt{q3S=49htg2A zMs-hekyLB%?7cBbjIen(_%`v_UiJ zQ`o(?(wXLs&dZHI^mZ>G(cxWHZ#Yt5iB63Mpc1`TZmZ6P5~FGsUO;NAr*|cocoBCWN$pC?ExmkByc*y`L@;Y zO!GXx586pVr&PkcIL}rqniOl^x@;!GI^}vZ9kwOjxFF^G7V3RaHlsI~UM_#DqdRkM zj&I5yk+%#?Tu2GtcuZ9jumR;7^&u!_6n41x1Ta+&AkKzWKHy(gu6>-xSM+u!KW3k0 zvWF@{(USfP?^s^+jPunCeH~k}8SDTY1D_v*r;#t4lHumjf3WE~goS5EZ&`v9DAt4ODEhmrwquuamM~l#}JRL-3C&e18DVVl9gR diff --git a/projects/content/_shaders/msl/debug.frag.msl b/projects/content/_shaders/msl/debug.frag.msl new file mode 100644 index 0000000..ecf7cb2 --- /dev/null +++ b/projects/content/_shaders/msl/debug.frag.msl @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_Target0 [[color(0)]]; +}; + +struct main0_in +{ + float3 in_var_TEXCOORD0 [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.out_var_SV_Target0 = float4(in.in_var_TEXCOORD0, 1.0); + return out; +} + diff --git a/projects/content/_shaders/msl/debug.vert.msl b/projects/content/_shaders/msl/debug.vert.msl new file mode 100644 index 0000000..482ac8a --- /dev/null +++ b/projects/content/_shaders/msl/debug.vert.msl @@ -0,0 +1,40 @@ +#include +#include + +using namespace metal; + +struct Scene +{ + float4x4 Model; + float3 Color; +}; + +struct type_StructuredBuffer_Scene +{ + Scene _m0[1]; +}; + +struct type_Uniforms +{ + float4x4 ViewProjection; +}; + +struct main0_out +{ + float3 out_var_TEXCOORD0 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float3 in_var_TEXCOORD0 [[attribute(0)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], uint gl_InstanceIndex [[instance_id]]) +{ + main0_out out = {}; + out.out_var_TEXCOORD0 = scene._m0[gl_InstanceIndex].Color; + out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * float4(in.in_var_TEXCOORD0, 1.0)); + return out; +} + diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl index e8c494d..766471f 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -24,30 +24,11 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d Texture [[texture(0)]], sampler Sampler [[sampler(0)]]) { main0_out out = {}; - float4 _54 = Texture.sample(Sampler, in.in_var_TEXCOORD0); - float3 _57 = float3(0.0, 16.0, -5.0) - in.in_var_TEXCOORD1; - float3 _58 = fast::normalize(_57); - float _73 = length(_57); - float _79; - if (_73 > 2.0) - { - _79 = 0.25 / _73; - } - else - { - _79 = 0.5 / _73; - } - float _84; - if (_73 > 4.0) - { - _84 = _79 * 0.5; - } - else - { - _84 = _79; - } - float _86 = (_73 > 5.0) ? 0.0 : _84; - out.out_var_SV_Target0 = float4(powr(_54.xyz * (float3(0.00200000009499490261077880859375, 0.00200000009499490261077880859375, 0.000600000028498470783233642578125) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_58, in.in_var_TEXCOORD2), 0.0)) * _86) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_58 + fast::normalize(in.in_var_TEXCOORD1 - float3(Uniforms.viewPos)))), 0.0), 30.0)) * 2.0) * _86))), float3(0.4545454680919647216796875)), _54.w); + float4 _56 = Texture.sample(Sampler, in.in_var_TEXCOORD0); + float3 _59 = float3(0.0, 16.0, -5.0) - in.in_var_TEXCOORD1; + float3 _60 = fast::normalize(_59); + float _76 = 0.5 / length(_59); + out.out_var_SV_Target0 = float4(powr(_56.xyz * (mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_60, in.in_var_TEXCOORD2), 0.0)) * _76) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_60 + fast::normalize(in.in_var_TEXCOORD1 - float3(Uniforms.viewPos)))), 0.0), 30.0)) * 2.0) * _76))), float3(0.4545454680919647216796875)), _56.w); return out; } diff --git a/projects/content/_shaders/spv/debug.frag.spv b/projects/content/_shaders/spv/debug.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..4de2ab7f5619d8539945a454e0ce1c96846e4909 GIT binary patch literal 492 zcmYk2O-n*i5Qe9Fz1g=~P`glE2GUA`s1_A1?L)$y+=YmX6vSHhv)c$g&-LEuz?_+R z-+5=|oHXgyBeo*qD2};3tw>5FEppjL)T4$s{>W!@i3GEv$t_MJqBJu62r>h)W;XAA z<;&jiadbZzygpn46`b0|=c*vz-p9jyIi0LvGba6?^F(f+bA=ppwN-vf=5B55g2>n% zBEIj=$hL{Z)U=7*)BfV}J9zm`k6P>!TPuFTz`O4({y26KPegU`tj~k~L0%jk$Gwx4>JYy4vmd=8|C;R$`#I{H{GEqWqm!A8 zcj^zi-*=1dr*}K+TU#IBK7kf%-ZLK!|0}9TeQ7QmVCQlH>tJH%BX)_M-Eu@Fws#$S zztvh@yi&tzx9++26Q}xSR7--@E?ubSocU#JlYPc6&rckCy6-h+Z*}`y_AoiduG8L) zliVWt4Q?;T8OSeRPMv?6t7}O-wb(=KoaWGQ5#Pep)~WC%V%I#}DSQjFW;~6B@at9L zdSCZ0P@loe@tj4zSMcV<)@Sk7)xQi@qa5=~WSxh(Wn%9sZo#{XSFbs1>UW>DIlMJ< z;(5G!?CJd$VxCX*4Rj^FCI1>&J@Vauy~66ArSlE^3XGe0V>wHB&rBM8Ut)Var>SY-;}#u<<#2amvJU{F!#&1?t56HuQR!ec~9SuXFH#JnE5sK%ejv^ z8#(H#b02`M|E8a3J;XfEe9CpIynXHI>>pwEp1#R6i^o;{B@=L_Vq@oNufN>*8TJpO CJW&Gx literal 0 HcmV?d00001 diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv index 57d6a4f1262da89ca6441e5f08b62eed05d993c0..a77c1438576c5e24c2a1ac34cd0737da110599b8 100644 GIT binary patch literal 2288 zcmZvc%TJR*6vaP^1%b*_K)?qD-(XP$M9WjaqE=gIdF)IRDrsUVX$$I3Lrh%h#+@5i z{t>Q>YhC*S{)NU6LP85_S2-|W>g`CN`QdLiMerHa)1_2hOU`6$*!X3gZhaqAoMAEYBSyY4twu+VUGkeX z_sfRF;=so-e&Fo2>JG!VDo*4Wk%{4OO;L8rP9{m-~=y@yfS2c6L#5=Uh zkmj%=!lBNWj*tzD>jM1~ejj{Lc>zhVAR*ndU8^kGy+jPsK2jo)-}I4qaF^3g5H;6J#!r{%*@dq~;Siy7HrAE@E*JAdc)o)zXB zMl-J%?_f^G-S*3@zw`3vWR}xi`Q$^~a$1njIphTY+MTf|pPb-Li^jC@mj6BZ6YH zd;o5J1+IJmd=D?ZF{lZN-?zKhIAJGi_WJ$ST6-P#e@|cUku53pq?CqIjbGQ!)SH=Y zX&~=2vx~FU_4e)R$y0A>A4+|0*|t4xP0yhBBF$Q3RbH!HKQe&qfYDAOw7$%*K=fmk zYkzmQULCt#Z8U3l>fnB&pJiXFf7`y-s%O8g;kRCE-u=4X0%pJG*cS`sdE3J8`fB5= zwN`T-Jbo+?x(R@y>oyarx#_t#zl~=2Uy{o~1dS$2ZStv-i%RX7F{^hdh)e zwjQy4iLF8GnPT&H`#a~Cy6oan#HGLU?Y4`%?aoWPb?7e+`(?7n+>gM!g0nt3>zyH5 zKWp5JKEz%@j$&2cj<^Ev$Y^6a@Xm}M{I(DOVRU1x=NR3JcOjl(oW2pa8~yi3vy*}M zfLW6fw-=y~qHPc7?_;kZ)*o>%pr3g7$3(=9faOB;Gj2c99d`hn(x06^Ud%X6#kmJF ze$c_2_qH)L!khEm*r(??w^(9Vg`9^s)$F?;FW-=SrSRfIU}x`H&Pw|zyJyNfQ}0*1 zoObW62ay-QT(I%_zrwD+cdPwXcJD)e7pJ_&J__?XyZQlizj1rg{|$C?dERccH`&MG z?Z@xaC9bghJ-WoB?0$d7imlVUJq25*HFaa(M_}vpeHasWa1?!QxNki0G4R5bgJj0F>#tVV2{@1vgf}+C)m$XjWhJm#GGP#_7B851COCwr`Q?2gE$AV zcX$$U4$F8s$5V(t@;B(nxt~Vl&E>j=uXpq=qRsqsoNE3vg_CzVAM5{t813&NzA5V* zEN|>Ax_*}s?Z1@s$I-Rf!ywh0^L<3$c|^N!^XGE*IdtEhKGSf13loU<>idbAOcp+B zngUyoeAG0J9yLv&e_wK(N4F;J;d=o+e6>gY7tyU}_`dYts>kr!p=-RARKi_!t zHiK?&`UH0wUEa5EEzai(;u+TAEPpDq{1Dy$A?*+0d>0=TZ2V(xahBcnFW-i?tB9Q6 zoO+z~F?tp8tbeeDkNaQcp61Za>9?xC@sZcwjrBjtyw})W=GC@<$eCCD$I`> {any}", .{scene.getPosRot().position}); } + core.debugSphere(.{ .y = 0 }, 4, .{}); + var show: bool = true; ig.showDemoWindow(&show);