From f74c50e4930a81e60155643507e6b53965a5233f Mon Sep 17 00:00:00 2001 From: Peter Li Date: Sun, 27 Apr 2025 12:58:06 -0700 Subject: [PATCH] > shadow casting lights --- engine/imgui/src/sgpu/backend_impl.zig | 2 + engine/rend/build.zig | 2 + engine/rend/shaders/depthOnly.frag.hlsl | 10 + engine/rend/shaders/depthOnly.frag.json | 15 ++ engine/rend/shaders/lit_mesh.frag.hlsl | 57 ++++- engine/rend/shaders/lit_mesh.frag.json | 30 ++- engine/rend/shaders/meshes.vert.hlsl | 5 + engine/rend/shaders/meshes.vert.json | 28 ++- engine/rend/src/sgpu/DebugDrawSystem.zig | 2 +- engine/rend/src/sgpu/renderer.zig | 232 ++++++++++++++---- extras/readme.md | 5 + lib/sdl3/src/gpu.zig | 2 +- .../content/_shaders/dxil/depthOnly.frag.dxil | Bin 0 -> 2512 bytes .../content/_shaders/dxil/lit_mesh.frag.dxil | Bin 5724 -> 6192 bytes .../content/_shaders/dxil/meshes.vert.dxil | Bin 5680 -> 6172 bytes .../content/_shaders/msl/depthOnly.frag.msl | 17 ++ .../content/_shaders/msl/lit_mesh.frag.msl | 19 +- projects/content/_shaders/msl/meshes.vert.msl | 10 +- .../content/_shaders/spv/depthOnly.frag.spv | Bin 0 -> 320 bytes .../content/_shaders/spv/lit_mesh.frag.spv | Bin 3540 -> 4256 bytes projects/content/_shaders/spv/meshes.vert.spv | Bin 1808 -> 2048 bytes 21 files changed, 368 insertions(+), 68 deletions(-) create mode 100644 engine/rend/shaders/depthOnly.frag.hlsl create mode 100644 engine/rend/shaders/depthOnly.frag.json create mode 100644 projects/content/_shaders/dxil/depthOnly.frag.dxil create mode 100644 projects/content/_shaders/msl/depthOnly.frag.msl create mode 100644 projects/content/_shaders/spv/depthOnly.frag.spv diff --git a/engine/imgui/src/sgpu/backend_impl.zig b/engine/imgui/src/sgpu/backend_impl.zig index 813069b..e8c65d5 100644 --- a/engine/imgui/src/sgpu/backend_impl.zig +++ b/engine/imgui/src/sgpu/backend_impl.zig @@ -77,6 +77,8 @@ pub const Impl = struct { if (ig.begin("renderer debug", &self.rendererDebug, .{})) { _ = ig.sliderFloat("directional light yaw", &rend.context().directionalLightYaw, 0, 360, null, .{}); + _ = ig.sliderFloat("ortho near", &rend.context().shadowOrthoNear, 0, 200, null, .{}); + _ = ig.sliderFloat("ortho far", &rend.context().shadowOrthoFar, 0, 6000, null, .{}); ig.end(); } } diff --git a/engine/rend/build.zig b/engine/rend/build.zig index d00ab36..c1faebd 100644 --- a/engine/rend/build.zig +++ b/engine/rend/build.zig @@ -39,6 +39,8 @@ pub fn build(b: *std.Build) void { 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")); + sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json")); + // ========== tests ========== const tests = b.addTest(.{ .target = target, diff --git a/engine/rend/shaders/depthOnly.frag.hlsl b/engine/rend/shaders/depthOnly.frag.hlsl new file mode 100644 index 0000000..72c2022 --- /dev/null +++ b/engine/rend/shaders/depthOnly.frag.hlsl @@ -0,0 +1,10 @@ +float4 main( + float2 UV : TEXCOORD0, + float3 WorldPos: TEXCOORD1, + float3 Normal: TEXCOORD2, + float4 DirectionalShadowFragPos: TEXCOORD3 + +) : SV_Target0 +{ + return float4(1.0, 1.0, 1.0, 1.0); +} diff --git a/engine/rend/shaders/depthOnly.frag.json b/engine/rend/shaders/depthOnly.frag.json new file mode 100644 index 0000000..ae8d2c0 --- /dev/null +++ b/engine/rend/shaders/depthOnly.frag.json @@ -0,0 +1,15 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_Target0", + "location" : 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 3556204..a97b9e1 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -1,12 +1,16 @@ Texture2D Texture : register(t0, space2); SamplerState Sampler : register(s0, space2); +Texture2D DirectionalShadowDepthMap : register(t1, space2); +SamplerState DirectionalShadowSampler : register(s1, space2); + cbuffer Uniforms : register(b0, space3) { float4 viewPos; float4 lightPosition; float4 directionalLight; float4 directionalLightColor; + float2 screenSize; float time; }; @@ -68,8 +72,26 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo } -float3 DirectionalLight(float3 normal, float3 fragPos) +float shadowCalculation(float3 fragPos, float4 DirectionalShadowFragPos) { + float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w; + shadowProjection = shadowProjection * 0.5 + 0.5 ; + shadowProjection.x = shadowProjection.x; + + float2 uv = shadowProjection.xy; + uv.y = -uv.y; + float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv); + float fragDepth = DirectionalShadowFragPos.z; + + float bias = 0.005; + float shadow = fragDepth - bias > depthSample ? 1.0 : 0.0; + + return shadow; +} + +float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadowFragPos) +{ + float3 lightDir = directionalLight.xyz; float diff = max(dot(lightDir, normal), 0.0); float3 diffuse = diff * directionalLightColor.xyz; @@ -82,13 +104,21 @@ float3 DirectionalLight(float3 normal, float3 fragPos) spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0); float3 specular = spec * directionalLightColor.xyz * 2; + // shadow mapping + + diffuse = diffuse * (1.0 - shadowCalculation(fragPos, DirectionalShadowFragPos)); + return diffuse; } + float4 main( + float4 ScreenPosition: SV_POSITION, + float2 UV : TEXCOORD0, float3 WorldPos: TEXCOORD1, - float3 Normal: TEXCOORD2 + float3 Normal: TEXCOORD2, + float4 DirectionalShadowFragPos: TEXCOORD3 ) : SV_Target0 { float4 s = Texture.Sample(Sampler, UV); @@ -102,14 +132,33 @@ float4 main( float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0); float3 lightColor = float3(0.8, 0.8, 0.5); - float3 ambient = lerp(float3(0.01, 0.01, 0.003), float3(0.004, 0.004, 0.06), dot(Normal, float3(0.0,1.0,0.0)) ) * 5; + float3 ambient = float3(0.1,0.1,0.1); float3 col = s.xyz; - float3 c2 = col * ambient + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor) + col * DirectionalLight(Normal, WorldPos); + float3 c2 = col * ambient + + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor) + + col * DirectionalLight(Normal, WorldPos, DirectionalShadowFragPos); float4 rv = float4(pow(c2, 1.0 / 2.2), alpha); +// === debug bone zone + // float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w; + // shadowProjection = shadowProjection * 0.5 + 0.5 ; + // shadowProjection.x = shadowProjection.x; + + // float2 uv = shadowProjection.xy; + // uv.y = -uv.y; + // float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv); + // float fragDepth = shadowProjection.z; + + // float t = DirectionalShadowFragPos.z; + // t = depthSample; + + // rv = float4(t, t, t, 1.0); + + // rv.x = rv.x + lightPos.x * 0.0001; + return rv; } diff --git a/engine/rend/shaders/lit_mesh.frag.json b/engine/rend/shaders/lit_mesh.frag.json index f40582d..982e4b0 100644 --- a/engine/rend/shaders/lit_mesh.frag.json +++ b/engine/rend/shaders/lit_mesh.frag.json @@ -6,7 +6,7 @@ } ], "types" : { - "_11" : { + "_14" : { "name" : "type.Uniforms", "members" : [ { @@ -29,10 +29,15 @@ "type" : "vec4", "offset" : 48 }, + { + "name" : "screenSize", + "type" : "vec2", + "offset" : 64 + }, { "name" : "time", "type" : "float", - "offset" : 64 + "offset" : 72 } ] } @@ -52,6 +57,11 @@ "type" : "vec3", "name" : "in.var.TEXCOORD2", "location" : 2 + }, + { + "type" : "vec4", + "name" : "in.var.TEXCOORD3", + "location" : 3 } ], "outputs" : [ @@ -67,6 +77,12 @@ "name" : "Texture", "set" : 2, "binding" : 0 + }, + { + "type" : "texture2D", + "name" : "DirectionalShadowDepthMap", + "set" : 2, + "binding" : 1 } ], "separate_samplers" : [ @@ -75,13 +91,19 @@ "name" : "Sampler", "set" : 2, "binding" : 0 + }, + { + "type" : "sampler", + "name" : "DirectionalShadowSampler", + "set" : 2, + "binding" : 1 } ], "ubos" : [ { - "type" : "_11", + "type" : "_14", "name" : "type.Uniforms", - "block_size" : 68, + "block_size" : 76, "set" : 3, "binding" : 0 } diff --git a/engine/rend/shaders/meshes.vert.hlsl b/engine/rend/shaders/meshes.vert.hlsl index 4333206..1a59302 100644 --- a/engine/rend/shaders/meshes.vert.hlsl +++ b/engine/rend/shaders/meshes.vert.hlsl @@ -1,3 +1,5 @@ +// I just reuse this one for the shadow mapping right? + struct Input { float3 Position : TEXCOORD0; @@ -15,6 +17,7 @@ struct Output float2 TexCoord : TEXCOORD0; float3 WorldPos : TEXCOORD1; float3 Normal: TEXCOORD2; + float4 DirectionalShadowFragPos: TEXCOORD3; float4 Position : SV_Position; }; @@ -29,6 +32,7 @@ StructuredBuffer scene: register(t0, space0); cbuffer Uniforms : register(b0, space1) { float4x4 ViewProjection; + float4x4 ShadowMapProjection; float time; }; @@ -46,6 +50,7 @@ Output main(Input input) output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos)); output.WorldPos = WorldPos.xyz; output.Normal = input.Normal; + output.DirectionalShadowFragPos = mul(ShadowMapProjection, WorldPos); return output; } diff --git a/engine/rend/shaders/meshes.vert.json b/engine/rend/shaders/meshes.vert.json index 223906d..c135b46 100644 --- a/engine/rend/shaders/meshes.vert.json +++ b/engine/rend/shaders/meshes.vert.json @@ -6,7 +6,7 @@ } ], "types" : { - "_11" : { + "_12" : { "name" : "Scene", "members" : [ { @@ -18,12 +18,12 @@ } ] }, - "_10" : { + "_11" : { "name" : "type.StructuredBuffer.Scene", "members" : [ { "name" : "_m0", - "type" : "_11", + "type" : "_12", "array" : [ 0 ], @@ -35,7 +35,7 @@ } ] }, - "_13" : { + "_14" : { "name" : "type.Uniforms", "members" : [ { @@ -45,10 +45,17 @@ "matrix_stride" : 16, "row_major" : true }, + { + "name" : "ShadowMapProjection", + "type" : "mat4", + "offset" : 64, + "matrix_stride" : 16, + "row_major" : true + }, { "name" : "time", "type" : "float", - "offset" : 64 + "offset" : 128 } ] } @@ -85,11 +92,16 @@ "type" : "vec3", "name" : "out.var.TEXCOORD2", "location" : 2 + }, + { + "type" : "vec4", + "name" : "out.var.TEXCOORD3", + "location" : 3 } ], "ssbos" : [ { - "type" : "_10", + "type" : "_11", "name" : "scene", "readonly" : true, "block_size" : 0, @@ -99,9 +111,9 @@ ], "ubos" : [ { - "type" : "_13", + "type" : "_14", "name" : "type.Uniforms", - "block_size" : 68, + "block_size" : 132, "set" : 1, "binding" : 0 } diff --git a/engine/rend/src/sgpu/DebugDrawSystem.zig b/engine/rend/src/sgpu/DebugDrawSystem.zig index 8cf20e4..e0a2bda 100644 --- a/engine/rend/src/sgpu/DebugDrawSystem.zig +++ b/engine/rend/src/sgpu/DebugDrawSystem.zig @@ -193,7 +193,7 @@ pub fn createPipeline(self: *@This()) !*gpu.GPUGraphicsPipeline { 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.depth_stencil_format = rend.context().depthFormat; pci.target_info.num_color_targets = 1; pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ .{ diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 6ba28e5..bc93b8f 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -37,9 +37,12 @@ pub const Renderer = struct { preDraws: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{}, depthTexture: *gpu.GPUTexture = undefined, + depthFormat: gpu.GPUTextureFormat = .textureformatD16Unorm, textureList: *TextureList = undefined, + shadowMapProjection: core.Transform = core.zm.identity(), + blockySampler: *gpu.GPUSampler = undefined, defaultTexture: *rend.Texture = undefined, @@ -47,9 +50,17 @@ pub const Renderer = struct { debugDrawSys: *DebugDrawSystem = undefined, + shadowOrthoNear: f32 = -150, + shadowOrthoFar: f32 = 150, + directionalLightYaw: f32 = 0.0, directionalLightColor: core.colors.Color = .{ .r = 0.8, .g = 0.8, .b = 0.9 }, - directionalLightDir: core.Vectorf = core.Vectorf.new(0.5, 0.25, -1).normalize(), + directionalLightDir: core.Vectorf = core.Vectorf.new(0.5, -0.5, 0.0).normalize(), + + shadowDepthFormat: gpu.GPUTextureFormat = .textureformatD16Unorm, + shadowDepthTexture: *gpu.GPUTexture = undefined, + shadowDepthDebugOutput: *gpu.GPUTexture = undefined, + shadowCastingPipeline: *gpu.GPUGraphicsPipeline = undefined, // transients DO NOT TOUCH swapchainTexture: ?*gpu.GPUTexture = undefined, @@ -118,6 +129,13 @@ pub const Renderer = struct { self.defaultTexture = getTexture(&defaultTextureName).?; self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); + + try self.createDirectionalShadowsPipeline(); + } + + pub fn createDirectionalShadowsPipeline(self: *@This()) !void { + try self.createShadowDepthTexture(); + try self.createShadowCastingPipeline(); } pub fn createSamplers(self: *@This()) !void { @@ -174,11 +192,27 @@ pub const Renderer = struct { return object; } + fn createShadowDepthTexture(self: *@This()) !void { + var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo); + + const shadowMapRes = core.configVar(u32, "renderer.shadowmap.resolution", 2048); + gci.type = .texturetype2d; + gci.format = self.shadowDepthFormat; + gci.width = shadowMapRes; + gci.height = shadowMapRes; + gci.layer_count_or_depth = 1; + gci.num_levels = 1; + gci.sample_count = .samplecount1; + gci.usage = .{ .textureusageDepthStencilTarget = true, .textureusageSampler = true }; + + self.shadowDepthTexture = self.device.createGPUTexture(&gci); + } + fn createDepthTexture(self: *@This()) !void { var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo); gci.type = .texturetype2d; - gci.format = .textureformatD32Float; + gci.format = self.depthFormat; gci.width = @intCast(self.scissor.w); gci.height = @intCast(self.scissor.h); gci.layer_count_or_depth = 1; @@ -212,26 +246,31 @@ pub const Renderer = struct { offset.* = offset.* + size; } - pub fn createMeshPipeline(self: *@This()) !void { + pub fn generateVertexAttributeList(self: *@This()) !std.ArrayList(gpu.GPUVertexAttribute) { + var list = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator); + var offset: u32 = 0; + { + try addAttribute(&list, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); + try addAttribute(&list, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); + try addAttribute(&list, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4); + try addAttribute(&list, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2); + try addAttribute(&list, &offset, @sizeOf(u32), .vertexelementformatUint); + } + + return list; + } + + pub fn createShadowCastingPipeline(self: *@This()) !void { const vertex = try self.loadShader("meshes.vert", meshes_vert.LoadArgs); - const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs); + const fragment = try self.loadShader("depthOnly.frag", depthOnly.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); + var attributes = try self.generateVertexAttributeList(); defer attributes.deinit(); - var offset: u32 = 0; - { - try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); - try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3); - try addAttribute(&attributes, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4); - try addAttribute(&attributes, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2); - try addAttribute(&attributes, &offset, @sizeOf(u32), .vertexelementformatUint); - } - pci.vertex_input_state = .{ .num_vertex_buffers = 1, .vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{ @@ -247,7 +286,45 @@ pub const Renderer = struct { 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.depth_stencil_format = self.shadowDepthFormat; + + pci.target_info.num_color_targets = 0; + + // no color targets + pci.rasterizer_state.cull_mode = .cullmodeNone; + pci.rasterizer_state.fill_mode = .fillmodeFill; + pci.rasterizer_state.enable_depth_bias = true; + + self.shadowCastingPipeline = self.device.createGPUGraphicsPipeline(&pci); + } + + pub fn createMeshPipeline(self: *@This()) !void { + const vertex = try self.loadShader("meshes.vert", meshes_vert.LoadArgs); + const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs); + + var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); + pci.vertex_shader = vertex; + pci.fragment_shader = fragment; + + var attributes = try self.generateVertexAttributeList(); + defer attributes.deinit(); + + 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 = self.depthFormat; pci.target_info.num_color_targets = 1; pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ .{ @@ -357,6 +434,8 @@ pub const Renderer = struct { if (self.activeCamera) |camera| { ptr.ViewProjection = @bitCast(camera.final); } + ptr.ShadowMapProjection = @bitCast(self.shadowMapProjection); + // ptr.ViewProjection = @bitCast(self.shadowMapProjection); ptr.time = @floatCast(self.totalTime); @@ -371,8 +450,9 @@ pub const Renderer = struct { if (self.activeCamera) |cam| { position = cam.finalPos; } - const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir); + const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir.fmul(-1)); + ptr.screenSize = @bitCast(platform.context().extent); ptr.viewPos = @bitCast(position.toZm()); ptr.lightPosition = @bitCast(self.lightPosition.toZm()); ptr.directionalLight = @bitCast(resolved.toZm()); @@ -425,32 +505,109 @@ pub const Renderer = struct { const cmd = self.device.acquireGPUCommandBuffer(); self.frameUploads(); - try self.uploadUniforms(cmd); for (self.preDraws.items) |interface| { interface.func(interface.ptr, cmd); } + // mesh pre-iteration + const container = rend.MeshComponent.BaseContainer; + const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); + + for (0..uploadCount) |i| { + const component = &container.dense.items[i].value; + + if (component.mesh == null) { + component.updateMesh(); + } + + if (component.texture == null) { + component.updateTexture(); + } + } + + self.drawDirectionalShadowMap(cmd); + + self.draw(cmd); + } + + // orthographic view projection from the sun towards the center of the thing + pub fn shadowMapOrtho(self: *@This()) core.Transform { + const ortho = core.zm.orthographicLh(200, 200, self.shadowOrthoNear, self.shadowOrthoFar); + var rotation = core.zm.lookAtLh( + .{ 0, 0, 0, 1 }, + self.directionalLightDir.toZm(), + .{ 0, 1, 0, 1 }, + ); + + rotation = core.zm.mul(core.zm.rotationY(core.radians(self.directionalLightYaw)), rotation); + + return core.zm.mul(rotation, ortho); + } + + pub fn drawDirectionalShadowMap(self: *@This(), cmd: *gpu.GPUCommandBuffer) void { + { + var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize); + const ptr: *meshes_vert.Uniforms = @ptrCast(@alignCast(&data)); + self.shadowMapProjection = self.shadowMapOrtho(); + ptr.ViewProjection = @bitCast(self.shadowMapProjection); + + cmd.pushGPUVertexUniformData(0, &data, @sizeOf(meshes_vert.Uniforms)); + } + + // can cache this + const depthTarget = std.mem.zeroInit(gpu.GPUDepthStencilTargetInfo, .{ + .texture = self.shadowDepthTexture, + .load_op = .loadopClear, + .store_op = .storeopStore, + .stencil_load_op = .loadopDontCare, + .stencil_store_op = .storeopDontCare, + .clear_depth = 1.0, + .clear_stencil = 0, + }); + + const renderpass = cmd.beginGPURenderPass(null, 0, &depthTarget); + renderpass.bindGPUGraphicsPipeline(self.shadowCastingPipeline); + renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1); + renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1); + renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit); + + const container = rend.MeshComponent.BaseContainer; + const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); + for (0..uploadCount) |i| { + const component = &container.dense.items[i].value; + if (component.mesh) |mesh| { + renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i)); + } + } + renderpass.endGPURenderPass(); + } + + pub fn draw(self: *@This(), cmd: *gpu.GPUCommandBuffer) void { if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, @ptrCast(&self.swapchainTexture), null, null)) { if (self.swapchainTexture == null) { _ = cmd.submitGPUCommandBuffer(); return; } + try self.uploadUniforms(cmd); - var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo); - targetInfo.texture = self.swapchainTexture.?; - targetInfo.clear_color = .{ .r = 0.1, .g = 0.1, .b = 0.1, .a = 1.0 }; - targetInfo.load_op = .loadopClear; - targetInfo.store_op = .storeopStore; + // can cache this + const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ + .texture = self.swapchainTexture.?, + .clear_color = .{ .r = 0.1, .g = 0.1, .b = 0.1, .a = 1.0 }, + .load_op = .loadopClear, + .store_op = .storeopStore, + }); - var depthTarget = std.mem.zeroes(gpu.GPUDepthStencilTargetInfo); - depthTarget.texture = self.depthTexture; - depthTarget.load_op = .loadopClear; - depthTarget.store_op = .storeopDontCare; - depthTarget.stencil_load_op = .loadopDontCare; - depthTarget.stencil_store_op = .storeopDontCare; - depthTarget.clear_depth = 1.0; - depthTarget.clear_stencil = 0; + const depthTarget = std.mem.zeroInit(gpu.GPUDepthStencilTargetInfo, .{ + .texture = self.depthTexture, + .load_op = .loadopClear, + .store_op = .storeopDontCare, + .stencil_load_op = .loadopDontCare, + .stencil_store_op = .storeopDontCare, + .clear_depth = 1.0, + .clear_stencil = 0, + }); const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget); //renderpass.bindGPUGraphicsPipeline(self.testPipeline); @@ -460,36 +617,26 @@ pub const Renderer = struct { renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1); renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1); renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit); + renderpass.bindGPUFragmentSamplers(1, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1); // todo move into materials system renderpass.setGPUScissor(&self.scissor); - //SDL_BindGPUFragmentSamplers(renderPass, 0, &(SDL_GPUTextureSamplerBinding){ .texture = Texture, .sampler = Samplers[CurrentSamplerIndex] }, 1); //rendering each mesh { const container = rend.MeshComponent.BaseContainer; const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); for (0..uploadCount) |i| { - // core.engine_log("pushing draw {d}", .{i}); const component = &container.dense.items[i].value; - // todo move this to slow tick? only update once every 1 second or so? - if (component.mesh == null) { - component.updateMesh(); - } - - if (component.texture == null) { - component.updateTexture(); - } - var t = component.texture; if (t == null) { t = self.defaultTexture; } + renderpass.bindGPUFragmentSamplers(0, &.{ .texture = t.?.texture, .sampler = self.blockySampler }, 1); if (component.mesh) |mesh| { - // core.engine_log("pushing draw for instance {d}", .{i}); renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i)); } } @@ -543,6 +690,7 @@ const gpu = sdl3.gpu; const meshes_vert = @import("meshes.vert"); const lit_mesh_frag = @import("lit_mesh.frag"); +const depthOnly = @import("depthOnly.frag"); const sample_vert = @import("sample.vert"); const MeshVertices = meshes_vert.Scene; diff --git a/extras/readme.md b/extras/readme.md index e69de29..cd306fa 100644 --- a/extras/readme.md +++ b/extras/readme.md @@ -0,0 +1,5 @@ +extras are like engine plugins + +they have access to all engine modules without having to be upstreamed as part of the engine + +and they don't have to be linked into your project unless you want them to be. diff --git a/lib/sdl3/src/gpu.zig b/lib/sdl3/src/gpu.zig index cf696e9..6852595 100644 --- a/lib/sdl3/src/gpu.zig +++ b/lib/sdl3/src/gpu.zig @@ -620,7 +620,7 @@ pub const GPUColorTargetInfo = extern struct { clear_color: FColor, // The color to clear the color target to at the start of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. load_op: GPULoadOp, // What is done with the contents of the color target at the beginning of the render pass. store_op: GPUStoreOp, // What is done with the results of the render pass. - resolve_texture: *GPUTexture, // The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used. + resolve_texture: ?*GPUTexture, // The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used. resolve_mip_level: u32, // The mip level of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used. resolve_layer: u32, // The layer index of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used. cycle: bool, // true cycles the texture if the texture is bound and load_op is not LOAD diff --git a/projects/content/_shaders/dxil/depthOnly.frag.dxil b/projects/content/_shaders/dxil/depthOnly.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..b03e5455b82fe3eb72cbb9da893c9ab1f8685d38 GIT binary patch literal 2512 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 delta 2657 zcma)6dsGuw8lOpq$s|m|LCvFAc~$!Ef#7UTF=PaJ%iEnw3;mdRT$j1q}}X zu8RO*f|c~7WCCIF*H3c#@8gQu37?hMcwUWB0p``%xKE?JW+c^TDeGk^9S8c;8W0WQ zg8=*f`U&QI&^cf{-44p2h3t%e0)|PZ{c@U|K93IP#nbsbO?3Kt?fObK9Lb_#Y<7l> zc_KZTC$gEb^t(V$@ac`NanSn1a`pxG$N=C1y%A30F*3RlmRrUZ&nL`^6ZmJ(@$Q&MlY$Xv0)D9{`w}ir?L2SK$xr*Q~NH-P~=I88?V}I|I znQ*IEd(LJBQW|g<7=(SYBV|b`y|v-x=P5B?JN7m-;Mf49l{$nxWg6z%;;MLCpL=n1aJ}cmq4Sr% zxbptMi7yVa8EkdfTAAzc<~GLN?MC}a@d(+aDcnwIF{{|?v{C#OgV<%pX>{>d*5P$b zP(Jd=YOrj|sFzDW32kXS`9{<+p^izz_HWZ`QZdnX2azTZ4E6h&^qX?~ITP?_UOzR| z1vO5o5&BDG(4@xi88G(+iBuT<3`V^-KcjASzvFj!MS@Ic8{)4UBwjI*wLCiN^qZd$ zo;Fp7PzS>P<)J8B_jB61^~NsUVfzA$o2PihP@?VyEuBtlfEsP?7kQnbk_m5s+Ulyy ztQ(fSGZZXda_&o_!z1L?oc%*lLlal}`Bk3wwl~$E3wdV;>QYv{tZxd_ZE*hU$7c~Y z&e?1}5rNspz`Vx5{IS4JV4gENKYv%j;w{-Z+ltfeZc)&Y16hYgGH*5vTWYO&I_J1) z-nY3MBI3g%A5vqU%Z(K^2QMuJ#A^yagZMM#a1exK0R~bpgN>J@mA4+)XjYy%d&lESU2<=)}^xeYu5G8 zvaZd>j{_tBPrfzNx1nnKti%CI>1BS3*f@7^uj3brxeNa{xu)6mF3YZEbcbI|98ix} zGHNaE7V@M88f4!gmyM@}zK0souf)iEapE}4>jZ{11}od1m)*lyJ{^hSmelW@6;o^j zcax|y4)3(0(_Qsd1XA9vt?MVdRAnRv=Mr#N5Nf1gxjnb*8i#DKnrRLa7Z_(nA)hGW#~}_-;vy)Am7XqZSZ=F(cHGR zC^;;qsHtHN^v9lw%tyUS?~;dB3+A+7zN%{byDDO3&(3UoMUB@I+}t zfa#L0V{ghOh&8x-EI793^nlF%}njOOSPF% zwQD@JS)PDS6cC#sLj2ju_@uRyFX}!pLoF-D+vAf)uT8wzYlc2uG5#t(39#c+4o0Tk zdUeG=s_1h6XbX$DEK7hezzpGteL@fh3jsUXI;3rei!}n0Fi`-Gz{4SVTh*>Z@9EPD=w2ArykoD zctQ2FXA7JZl~>j($fag&jiOD832kuRtnFdm4Z-__V0hN{RR43E;y4&@n&7gcqTI|e z#P-80Mp1kJ$6 zBrNqf)FgC}UH%IBk*UFn?u$-sf*PHSQ(CK~lm4`>Oh-=Yn$kGV8{uI(Qiah~3>oT?7rjVpWyH3<=|wz6E|eyPKU)pXwk z0}?)a`OUU&FQCEDq3}pJ8qSa*Cb!92 z!Qkv9Q-&UUh-2UR?4qhYdQ95@V{oQAbt>_#>xo${7iRh9`qN!Q)^(o@ J$6gx1zX3fttmgm# diff --git a/projects/content/_shaders/dxil/meshes.vert.dxil b/projects/content/_shaders/dxil/meshes.vert.dxil index ff4f46e96d1889c0ae6c70a29bbf2f6e0e6d85c6..9685fde1f388cebdf9870d078983850589552677 100644 GIT binary patch delta 3010 zcmaJ@3se(V8lFieGYNz^NPv*U8eWQk8W02GV>2PL$fJ#lE+QTi6b$7d4|P%WBq2gk zLn{Up!MXuNu|+osDzVkgB;X>hD_C6dxj`w*ZmCB-+ODTPXZH>yQhWC7J-L}X|Nq_Z z|L-^d{E0dIgg927CX1_lRXgyfXA*h1_}F1VKU`1YzL149sLOUxWEIaH#1J zl;93QTit77uX$R5l>sIbOlq{%sJx6qm<_kp=(xt^ushslTm{c&wE-X42tmdo*vp$* zbWmSlP_ZZvV%!bSg-;oq;2Y&$DC6zQe% zn!KJb3RuYQQ`)7eSz-d$dRQxUQhL-deu}JA#n2bmi?ljk9&=bL-gh|w6(rXj zBdzeL2r9Y8Wg+*K4kxEpO)doxCYb=WRHi@r_`E zpYmZXG%v359|6CU{J4H@^m<8jaD8aah-KhgvW{V~Tpg?!1RS?gJo}{{|Ds4+>mCQ! zqyTeW3TxN|$dZl=KF|1IXk&xm@uOOY_Z0v#T)k@<1kqDig>Wa%8h~TBf5r~x73Jn9 zc;zTp9`(LS)w&tfHdXuK;2r#B?bidltM&uwzpnkxLu?;dy4u9&oS7Xb3uhB-4>*r`f@QmGT*2`Pa7d85 z2mvK@RkT_>n?h~;J$sG>G>Ew0AWbF-(t|X$8Fz8Q;lCMMIR1>@#YBkNc!LwC@!B5% zp4=cxw&*<$9n0D1S5JzuC+jgUMD{c?>kZ?LF!5Wnag7lyhc_BnN)s0wS%DMO0 z(s|rW>HWG49ao|APW1OqC%LJlcl-!<{m5Vx=zoDI3o2JiJIH6P1RrtUU4)0u>iEp5 zJ8hqiS5NY_#Ny1ukcf$*vkZivnc$^Oxs^k(Up=7_l-{c%Xj&1Ew@ZO;cc5Fe)x02x zS*|O>vLS3cgx+_$OAFB=2-{+Ex@#~sjuk1w zh%!N{g^!6pBY#)Rpdst`RWKDXV-JLCJ`$lVELc%_*@=2X@)8I?!yH5!tTa1qx^ll% zm`~Xve($nX%lJxi(zZOyWjjt2OF3r?ZnjH&wkbcM>aRUy0OOl`RL_isGoqL%HC1z8c6*{47d$$A2 z$F(-Fo$EK?f?jlQf-o|Kf_|=><$_+5x|QJd6tq^ucet?LoHI&{2&J$WbsxB}qb9fA zxS7J95U|Vg#1m&p^CzhNq#wI%t9ar7X~w`!^hA;Uq+~*6Ke>2fwf$t&1Yze#xxMm> zkU}`351DO+`4!3@2$tgPfPG9%&84}E#(6scLNf(vo81S;zJq8&u<c2`SNxGru#r|3nGd!jg#_#LN~}k2teXL#g~( zlGVPj&koLLn8PI1Hj!ZtZm%L?P$SD0t)4Mzoe3V5xIu)pu=L^vDLW9wKta85>|b#z zE(z#mRhQ$2Ic%Gn7BS34UB_;loAC5yxhME@K!~gMHU}M@&zm~z_}t{DR$6DjbVVSl zp-L04U?e7F;)cn`O9c7M8`(=v6@`3D(@Zztw4>9c;c3m0dY6`+>H})FE5u)I!F(~( zkV}8-B&zih>&_D5sYd=h|r(NP~<>!wWWX>}U=5$xk+;myzM1OF~yoSCYbRE+fWleQ= z)rXT&KoIrf(PsY&Yj@h=+fHfE5x(_d8X&@C6ifUj#h0!qulc*+CJ<$^Zyn4VV&t0R z)!N>vRughzwQoDg-}lmMs*#!c;x~1nx%=bi8>Tu}fMDk!zkSfRW13)PuKD`rF55Ig zE6Hyf0R$SVi&6}=XzuHkA5Al?=C{A}T^8{!h29*HLJv93a0a9>h)$<)0?qw-C4ZWr mh~EzLv!+w%RRe;kX}p077#TDjKn+slzUSA*Yr(Gp1pOCma`apP delta 2501 zcmZWq4^R_l7XLO`ck^ch3qgz|;v${~1Ky&T__vcypq@x8Rv6>S-2^x_9)eM(o)zcv z4-hmu!PS!!<}N@@?P$FqsGyw9LQtAwiww0?Im%rr!!g=pdYzlIcBc0&fmr7<`(^XJ z_j|wh=DpwdrIGfhuFo_Xj9-Rc?0)75O^sg@B`O^6h!VYeWQ#dQ$Le-QQ%B4^)4RM5^LOXE<0qG3eaCm@3&ZRu>(90Er}#gk2B7(Q)D9y)${=Q2@}v?#Di~wZ4CN>*@-&q~S&L))Gwv zMGj)Z=Na^Hhs-!$#Z@~l2hC0jDD5)gc5IJ7iFV0)^w>U{0mAfQ@?E6%rawcsBrnTk z+_vqlOnK!$E>dyB)%JQS?hA~0qD@7W?G9y^LrGZm9gOOLs9N@M04p8C%EvIFiYOy( zxKdE+%(W=dH=g(l4h&#rxp)~p%zcghF0eN=rTM7z%*y`KtEsgXXYK)crSl18>8Z~8 zSh&gW(pg=F(HXiim#k7XfFyp$Raco^TB}RvcX3f7U59Hfl^LH&g)5yUJ%?KvWe1}k z<^X;{8ALAFQm*{`@~zH{+wHnrV#C8X$eR5w@A>ZPEM=9}?$S|Jj<^gRT_p=Hwma30 z-PK%lE>cfba<>>Nuh7U~B_7GpiUGQ~LfX;*n-_N~(sL}_W`HglsYvyGC858KNyqz#RjCUfsdS;enHxhAT6)3xUHmoOR}cC zr6Cs0@0%`o8XBJ%93AnYnetT|7u=z>cUE<#FxyWMpYDlDb6?H5_RrH--KE*~b4fkr zb()5XE38t}&=8w*9>z|7I~H<|jEqipPeO_bpQy-+z0GqDhQ2x5=Y!^uPmS)+g=Cld zPrtb`dMfR~>9VqHzvNdCb#HWPWD;igp*MKRv{i}+koC33l|_%bx<=o7douo5dCT8; zxvrIl<@<@?RrylTJ}2K^LE9PWzMty1?MEUW(WiTfP?IR+I(b%ss9j6cRk3PRBCWi; z5D4xcOAsYK2jK_AkOB^fP+;Hunzt0=3*sew1WI@fdon66=POYTDcWl^q!J7vLk@@< z#oh10VeS9GN9kcL`WecAU$j?U>Wpbx(VcMY*x4mewS#C=y%r6k zO!lXCTrM|W67H0hS;Th;56v*(8TD}_`MLE$BspOaQpQ; zORuNgrf*+QVe_rqS;8h|=nNp$SW zYC;mw*=Rsz-FQv5A&LBwjo)8{338 zsQMfWkDd>5rxg@rLy?`&zB93(le;;K0i65$vl@i2ui&^Df6I)u zh>={e;_0l-=E3tlGd3b&&ej~jO}4;{aofT<F@qK=dTBz<=25g!L5CNFB6iUi^+Ym;!#+>_pm~QPQqP|hwfCj36C^-6YD#?8bkjWBk3Xwx zh0^{N!sqUp2{UN?@}ydZ4hwR-$y@pFdEqgWwOQHf0`snf2Y+>gkI7Q*An%ZGeFD@Xqu(j7iygYoHy;`cq2 z|3HV2QTFa&a93m2n@@Yf$4p%sBexui-xPy~PocLxE63ZrYdlj432gi+g$$1PeXa8S zFBwo%W7f9GpD>sY#jmT2e#v0(-SrfG?PUo`d +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_Target0 [[color(0)]]; +}; + +fragment main0_out main0() +{ + main0_out out = {}; + out.out_var_SV_Target0 = float4(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 3f54b53..5c4c56f 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -9,9 +9,12 @@ struct type_Uniforms float4 lightPosition; float4 directionalLight; float4 directionalLightColor; + float2 screenSize; float time; }; +constant float3 _56 = {}; + struct main0_out { float4 out_var_SV_Target0 [[color(0)]]; @@ -22,14 +25,15 @@ struct main0_in float2 in_var_TEXCOORD0 [[user(locn0)]]; float3 in_var_TEXCOORD1 [[user(locn1)]]; float3 in_var_TEXCOORD2 [[user(locn2)]]; + float4 in_var_TEXCOORD3 [[user(locn3)]]; }; -fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d Texture [[texture(0)]], sampler Sampler [[sampler(0)]]) +fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d Texture [[texture(0)]], texture2d DirectionalShadowDepthMap [[texture(1)]], sampler Sampler [[sampler(0)]], sampler DirectionalShadowSampler [[sampler(1)]]) { main0_out out = {}; - float4 _61 = Texture.sample(Sampler, in.in_var_TEXCOORD0); - float _62 = _61.w; - if (_62 < 0.00999999977648258209228515625) + float4 _65 = Texture.sample(Sampler, in.in_var_TEXCOORD0); + float _66 = _65.w; + if (_66 < 0.00999999977648258209228515625) { discard_fragment(); } @@ -68,7 +72,12 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo _119 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_100, in.in_var_TEXCOORD2), 0.0)) * _93) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_100 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _93); break; } while(false); - out.out_var_SV_Target0 = float4(powr(_61.xyz * (((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 5.0) + _119) + (Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0))), float3(0.4545454680919647216796875)), _62); + float3 _136 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); + float3 _138; + _138.x = _136.x; + float2 _139 = _138.xy; + _139.y = -_136.y; + out.out_var_SV_Target0 = float4(powr(_65.xyz * ((float3(0.100000001490116119384765625) + _119) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, _139).x)))), float3(0.4545454680919647216796875)), _66); return out; } diff --git a/projects/content/_shaders/msl/meshes.vert.msl b/projects/content/_shaders/msl/meshes.vert.msl index ec6dfbc..187dcb9 100644 --- a/projects/content/_shaders/msl/meshes.vert.msl +++ b/projects/content/_shaders/msl/meshes.vert.msl @@ -16,6 +16,7 @@ struct type_StructuredBuffer_Scene struct type_Uniforms { float4x4 ViewProjection; + float4x4 ShadowMapProjection; float time; }; @@ -24,6 +25,7 @@ struct main0_out float2 out_var_TEXCOORD0 [[user(locn0)]]; float3 out_var_TEXCOORD1 [[user(locn1)]]; float3 out_var_TEXCOORD2 [[user(locn2)]]; + float4 out_var_TEXCOORD3 [[user(locn3)]]; float4 gl_Position [[position]]; }; @@ -37,11 +39,13 @@ struct main0_in 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 = {}; - float4 _44 = float4(in.in_var_TEXCOORD0, 1.0); + float4 _46 = float4(in.in_var_TEXCOORD0, 1.0); + float4 _49 = scene._m0[gl_InstanceIndex].Model * _46; out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3; - out.out_var_TEXCOORD1 = (scene._m0[gl_InstanceIndex].Model * _44).xyz; + out.out_var_TEXCOORD1 = _49.xyz; out.out_var_TEXCOORD2 = in.in_var_TEXCOORD1; - out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _44); + out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _49; + out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _46); return out; } diff --git a/projects/content/_shaders/spv/depthOnly.frag.spv b/projects/content/_shaders/spv/depthOnly.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..7e413c373689c1a6dac6ff05d95c15ea0e8751fe GIT binary patch literal 320 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 literal 1808 zcmZXU*-ukZ5Qh)#Ex02hiyIbjN2}lx6QhDl;KhKVhF1cYq()j(T8(f13I4ghnD~9? z_P|X&WIFSkedZi)wK6{v!cYj|OnAbtXDn3unrg&aN5knud4Idv5>y~PGN=X(LnI5w zpyN=LKlNKU*3g_l?*9CiH#WPS-cGmI$#-A%_V)5lV{<2O<@jXbBt8W)UoB!(;az(- z{|eXV6#O7Yh=*fmG4H2VbFbamKfpdrCq>60d~W7HHahJu`A)alrgQUZbFOZ4KZl{I zv4IduDbS3>8Jn%f_w7#O+2uhJShA};_L&q#bk3Q1Gb0B=APQU?te+G=l%w5 zCe`L%2W?Bymc?1py{xh$_wFtiAhGu$_K3Z^nTQJPJ&N6lcKa8r7u$2$-#*L!_9iy3 z{@&3X*W;qJd!$VP4hbeS6AFoHSR#&74kU0JDEXtE^!^tNw~eJn*rOKF-6@hOd)GmZ%ucj z&Ak|Z0dDW=wO@p5H%9vc*!S(*GRAm&_Dz(r z{|5=zk&EwO;M-b@GnmUW2mPU&Yw+jfa_;Mp{Uv+@*<51xbQ7{av3tA)+24D9y^GtB zIXp>s2U(qUlWw7}v(^R^xZ}H!@%n4`{jFe|hu?$TtMApCa(i&^4M_WMdN9v@$Xx1I z&>8Os(|ah#E%x;(&l0$t$B(6X)Ti8!kkuQz&ezbLJ%+3)d7RU^Ua&du%AF~DPx>l* QNA6bH`!VldBA-J402%6UzW@LL