From 2046b1d7c806b6acc65778c20a482855de40d9fb Mon Sep 17 00:00:00 2001 From: peterino2 Date: Sun, 21 Sep 2025 00:51:04 -0700 Subject: [PATCH] added example smoke and particle emitter --- engine/rend/shaders/lit_mesh.frag.hlsl | 13 +- engine/rend/shaders/lit_mesh.frag.json | 10 +- engine/rend/shaders/meshes.vert.hlsl | 105 +++++------ engine/rend/shaders/meshes.vert.json | 22 ++- engine/rend/shaders/sceneShared.hlsli | 26 +++ engine/rend/shaders/vertexShared.hlsli | 23 +++ engine/rend/src/particles/particles.zig | 57 +++++- engine/rend/src/sgpu/ParticleRenderer.zig | 137 +++++++++++++++ .../rend/src/sgpu/embedded/texture_white.png | Bin 0 -> 403 bytes engine/rend/src/sgpu/renderer.zig | 37 +++- engine/rend/src/sgpu/ssao.zig | 11 +- .../content/_shaders/dxil/lit_mesh.frag.dxil | Bin 8336 -> 8412 bytes .../content/_shaders/dxil/meshes.vert.dxil | Bin 8584 -> 9256 bytes .../content/_shaders/msl/lit_mesh.frag.msl | 164 +++++++++--------- projects/content/_shaders/msl/meshes.vert.msl | 66 +++++-- .../content/_shaders/spv/lit_mesh.frag.spv | Bin 8044 -> 8096 bytes projects/content/_shaders/spv/meshes.vert.spv | Bin 4936 -> 6300 bytes projects/content/textures/PixelSmoke.aseprite | Bin 0 -> 1280 bytes projects/content/textures/PixelSmoke.png | Bin 0 -> 1378 bytes projects/content/textures/texture_white.png | Bin 0 -> 403 bytes projects/sampleGame/externGame/externGame.zig | 4 +- projects/sampleGame/main.zig | 7 + 22 files changed, 492 insertions(+), 190 deletions(-) create mode 100644 engine/rend/shaders/sceneShared.hlsli create mode 100644 engine/rend/shaders/vertexShared.hlsli create mode 100644 engine/rend/src/sgpu/ParticleRenderer.zig create mode 100644 engine/rend/src/sgpu/embedded/texture_white.png create mode 100644 projects/content/textures/PixelSmoke.aseprite create mode 100644 projects/content/textures/PixelSmoke.png create mode 100644 projects/content/textures/texture_white.png diff --git a/engine/rend/shaders/lit_mesh.frag.hlsl b/engine/rend/shaders/lit_mesh.frag.hlsl index 9e9d451..2bfe7a6 100644 --- a/engine/rend/shaders/lit_mesh.frag.hlsl +++ b/engine/rend/shaders/lit_mesh.frag.hlsl @@ -21,16 +21,7 @@ cbuffer Uniforms : register(b0, space3) float time; }; -struct Scene -{ - float4x4 Model; - - uint textureMode; // 0 = regular triple, - // 0x10 = video yuv, - uint pad0; // 0 = regular triple, - uint pad1; // 0 = regular triple, - uint pad2; // 0 = regular triple, -}; +#include "sceneShared.hlsli" StructuredBuffer scene: register(t4, space2); @@ -247,7 +238,7 @@ PixelOutput main( if((texMode & 0x2) > 0) // full bright no lighting bit { - c2 = col * 2.0; + c2 = pow(col, 1.0/2.2); } // float4 rv = float4(pow(c2, 1.0 / 2.2), alpha); diff --git a/engine/rend/shaders/lit_mesh.frag.json b/engine/rend/shaders/lit_mesh.frag.json index c88358d..3706c00 100644 --- a/engine/rend/shaders/lit_mesh.frag.json +++ b/engine/rend/shaders/lit_mesh.frag.json @@ -62,18 +62,18 @@ "offset" : 64 }, { - "name" : "pad0", - "type" : "uint", + "name" : "animation", + "type" : "int", "offset" : 68 }, { - "name" : "pad1", + "name" : "flags", "type" : "uint", "offset" : 72 }, { - "name" : "pad2", - "type" : "uint", + "name" : "float0", + "type" : "float", "offset" : 76 } ] diff --git a/engine/rend/shaders/meshes.vert.hlsl b/engine/rend/shaders/meshes.vert.hlsl index 09cfea8..9a14135 100644 --- a/engine/rend/shaders/meshes.vert.hlsl +++ b/engine/rend/shaders/meshes.vert.hlsl @@ -5,42 +5,8 @@ uint getCharFromUintArray(uint color, uint index) return uint((color >> 8 * index) & 0xFF); } -struct Input -{ - float3 Position : TEXCOORD0; - float3 Normal : TEXCOORD1; - float4 Color : TEXCOORD2; - float2 UV : TEXCOORD3; - uint Bones : TEXCOORD4; - uint weights : TEXCOORD5; - - uint Instance : SV_InstanceID; -}; - -struct Output -{ - float2 TexCoord : TEXCOORD0; - float3 WorldPos : TEXCOORD1; - float3 Normal: TEXCOORD2; - float4 DirectionalShadowFragPos: TEXCOORD3; - uint Instance: TEXCOORD4; - float3 ScreenNormal: TEXCOORD5; - - float4 Position : SV_Position; -}; - -struct Scene -{ - float4x4 Model; - - uint textureMode; // 0 = regular triple, - // 0x10 = video yuv, - - int animation; // -1 means no animation, any non-zero value means an index into the animationBuffer - uint flags; // 0 -> 0: always in front - // 1 -> 1: useAltCamera - uint pad2; -}; +#include "vertexShared.hlsli" +#include "sceneShared.hlsli" StructuredBuffer scene: register(t0, space0); @@ -55,7 +21,9 @@ cbuffer Uniforms : register(b0, space1) { float4x4 ViewProjection; float4x4 NoTranslateView; + float4x4 ViewTransform; float4x4 ShadowMapProjection; + float4 cameraPosition; float time; }; @@ -110,23 +78,56 @@ Output main(Input input) // pos.x += 0.2 * sin(time * 0.5 ) * pos.y * 0.5; // pos.y += 0.2 * cos(time * 0.5 ) * pos.z * 0.5; + int billboard = scene[input.Instance].flags & 0x4; + + float4 WorldPos; + + if(billboard > 0) + { + float3 billboardPosition = mul(scene[input.Instance].Model, float4(0,0,0,1)).xyz; + float3 toCamera = normalize(billboardPosition - cameraPosition.xyz); + + float3 up = float3(0,1,0); + float3 right = normalize(cross(up, toCamera)); + up = cross(toCamera, right); + + float d = length(cameraPosition.xyz - billboardPosition); + float perspectiveScale = d * 0.1f; // adjust multiplier as needed + + float finalSize = scene[input.Instance].float0 * perspectiveScale; + + float3 wp = billboardPosition + + mul(mul(right, input.Position.x), finalSize) + + mul(mul(right, input.Position.y), finalSize); + + WorldPos = float4(wp, 1.0); + + output.Position = mul(ViewProjection, WorldPos); + output.WorldPos = WorldPos.xyz; + + output.Normal = toCamera; + output.ScreenNormal = float3(0, 0, 1); + } + else + { + // todo. maybe all world position values should be + // transformed into screen space + WorldPos = mul(scene[input.Instance].Model, pos); + output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos)); + output.WorldPos = WorldPos.xyz; + + float4x4 noTranslate = ExtractRotation(scene[input.Instance].Model); + output.Normal = normalize(mul(noTranslate, float4(input.Normal, 1.0))).xyz; + + float4x4 noTranslateScreen = mul(NoTranslateView, noTranslate); + output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz; + + // output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz; + // output.ScreenNormal = input.Normal; + // output.ScreenNormal = float4(input.Normal, 1.0).xyz; + } + - // todo. maybe all world position values should be - // transformed into screen space - float4 WorldPos = mul(scene[input.Instance].Model, pos); - output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos)); - output.WorldPos = WorldPos.xyz; - - float4x4 noTranslate = ExtractRotation(scene[input.Instance].Model); - output.Normal = normalize(mul(noTranslate, float4(input.Normal, 1.0))).xyz; - - float4x4 noTranslateScreen = mul(NoTranslateView, noTranslate); - output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz; - - - // output.ScreenNormal = mul(noTranslateScreen, float4(input.Normal, 1.0)).xyz; - // output.ScreenNormal = input.Normal; - // output.ScreenNormal = float4(input.Normal, 1.0).xyz; output.DirectionalShadowFragPos = mul(ShadowMapProjection, WorldPos); output.Instance = input.Instance; diff --git a/engine/rend/shaders/meshes.vert.json b/engine/rend/shaders/meshes.vert.json index 1d2b116..a855b2f 100644 --- a/engine/rend/shaders/meshes.vert.json +++ b/engine/rend/shaders/meshes.vert.json @@ -32,8 +32,8 @@ "offset" : 72 }, { - "name" : "pad2", - "type" : "uint", + "name" : "float0", + "type" : "float", "offset" : 76 } ] @@ -102,16 +102,28 @@ "row_major" : true }, { - "name" : "ShadowMapProjection", + "name" : "ViewTransform", "type" : "mat4", "offset" : 128, "matrix_stride" : 16, "row_major" : true }, + { + "name" : "ShadowMapProjection", + "type" : "mat4", + "offset" : 192, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "cameraPosition", + "type" : "vec4", + "offset" : 256 + }, { "name" : "time", "type" : "float", - "offset" : 192 + "offset" : 272 } ] } @@ -197,7 +209,7 @@ { "type" : "_22", "name" : "type.Uniforms", - "block_size" : 196, + "block_size" : 276, "set" : 1, "binding" : 0 } diff --git a/engine/rend/shaders/sceneShared.hlsli b/engine/rend/shaders/sceneShared.hlsli new file mode 100644 index 0000000..eaf113d --- /dev/null +++ b/engine/rend/shaders/sceneShared.hlsli @@ -0,0 +1,26 @@ +struct Scene +{ + float4x4 Model; + + uint textureMode; // 0 = regular triple, + // 0x10 = video yuv, + // bit 0 == srgb correction + // bit 1 == fullbright + // bit 2 = reserved + // bit 3 = reserved + // bit 4 - 7 = color space: + // 0 -> regular rgb + // 1 -> regular video yuv // used for decoding video files + + int animation; // -1 means no animation, any non-zero value means an index into the animationBuffer + uint flags; // 0 -> 0: always in front + // 1 -> 1: useAltCamera + // 2 -> 2: billboard (& 0x4) + float float0; // uses: + // in billboard mode: this represents the size +}; + +uint isBillboard(Scene s) +{ + return s.flags & 0x4; +} diff --git a/engine/rend/shaders/vertexShared.hlsli b/engine/rend/shaders/vertexShared.hlsli new file mode 100644 index 0000000..9c9ce33 --- /dev/null +++ b/engine/rend/shaders/vertexShared.hlsli @@ -0,0 +1,23 @@ +struct Input +{ + float3 Position : TEXCOORD0; + float3 Normal : TEXCOORD1; + float4 Color : TEXCOORD2; + float2 UV : TEXCOORD3; + uint Bones : TEXCOORD4; + uint weights : TEXCOORD5; + + uint Instance : SV_InstanceID; +}; + +struct Output +{ + float2 TexCoord : TEXCOORD0; + float3 WorldPos : TEXCOORD1; + float3 Normal: TEXCOORD2; + float4 DirectionalShadowFragPos: TEXCOORD3; + uint Instance: TEXCOORD4; + float3 ScreenNormal: TEXCOORD5; + + float4 Position : SV_Position; +}; diff --git a/engine/rend/src/particles/particles.zig b/engine/rend/src/particles/particles.zig index db01462..c66e43f 100644 --- a/engine/rend/src/particles/particles.zig +++ b/engine/rend/src/particles/particles.zig @@ -74,6 +74,31 @@ pub const Rotationals = struct { pub const RenderInfo = struct { meshIndex: u32 = 0, textureIndex: u32 = 0, + + var quad_mesh: ?rend.IndexedMesh = null; + var default_texture: ?*rend.Texture = null; + + pub fn getMesh(self: @This(), emitter: *const ParticleEmitter) rend.IndexedMesh { + if (emitter.mesh.items.len == 0) { + if (quad_mesh == null) { + quad_mesh = rend.getMesh("m_screenPlane").?; + } + return quad_mesh.?; + } + + return emitter.mesh.items[self.meshIndex]; + } + + pub fn getTexture(self: @This(), emitter: *const ParticleEmitter) *rend.Texture { + if (emitter.texture.items.len == 0) { + if (default_texture == null) { + default_texture = rend.getTexture("t_white").?; + } + return default_texture.?; + } + + return emitter.texture.items[self.textureIndex]; + } }; pub const ParticleEmitter = struct { @@ -85,11 +110,12 @@ pub const ParticleEmitter = struct { life: std.ArrayListUnmanaged(Life) = .{}, particlesPVA: std.ArrayListUnmanaged(ParticlePVA) = .{}, finals: std.ArrayListUnmanaged(core.Mat) = .{}, - renderInfo: std.ArrayListUnmanaged(RenderInfo) = .{}, + size: std.ArrayListUnmanaged(f32) = .{}, particleAcceleration: ParticleRandRangef = .{ .min = 0.0, .max = 0.0 }, particleVelocity: ParticleRandRangef = .{ .min = 8, .max = 10 }, particleLife: ParticleRandRangef = .{ .min = 2, .max = 2 }, + particleSizeSpawn: ParticleRandRangef = .{ .min = 0.8, .max = 1.0 }, spawnRate: ParticleRandRangef = .{ .min = 10, .max = 10 }, nextSpawn: f64 = 0.0, @@ -106,10 +132,10 @@ pub const ParticleEmitter = struct { // and only position and scale will be used to render the particle. // an empty list means that this will use quad_mesh - mesh: std.ArrayListUnmanaged(rend.IndexedMesh) = .{}, + mesh: rend.IndexedMesh = undefined, // empty list means will use t_white - texture: std.ArrayListUnmanaged(*rend.Texture) = .{}, + texture: *rend.Texture = undefined, emitterLife: f64 = 0.0, // 0.0 means this emitter lives forever. emitterMaxLife: f64 = 0.0, @@ -173,7 +199,7 @@ pub const ParticleEmitter = struct { _ = self.life.swapRemove(i); _ = self.particlesPVA.swapRemove(i); _ = self.finals.swapRemove(i); - _ = self.renderInfo.swapRemove(i); + _ = self.size.swapRemove(i); } pub fn updateSpawn(self: *@This(), dt: f64) void { @@ -235,12 +261,9 @@ pub const ParticleEmitter = struct { const life = self.particleLife.getRange(); try self.life.append(gParticleAllocator, .{ .current = life, .max = life }); - try self.particlesPVA.append(gParticleAllocator, pva); - - // renderinfo not used rn - try self.renderInfo.append(gParticleAllocator, .{}); try self.finals.append(gParticleAllocator, std.mem.zeroes(core.Mat)); + try self.size.append(gParticleAllocator, self.particleSizeSpawn.getRange()); } fn updateLife(self: *@This(), dt: f64) void { @@ -264,12 +287,30 @@ pub const ParticleEmitter = struct { self.updatePVA(dt); self.updateParticleLife(dt); self.updateLife(dt); + self.updateFinals(); } + pub fn updateFinals(self: *@This()) void { + const scene = self.entity.fetch(core.Scene).?; + const transform = scene.getPosRot().toTransform(); + + for (self.particlesPVA.items, 0..) |pva, i| { + const p = core.zm.translationV(pva.position); + + self.finals.items[i] = core.zm.mul(p, transform); + } + } + + var t_whiteName: core.Name = core.DefineName("t_white"); + var m_quad: core.Name = core.DefineName("m_screenPlane"); + pub fn initECS(self: *@This(), handle: core.SetHandle) void { // get the mesh component self.entity = core.Entity{ .handle = handle }; + self.texture = rend.getTexture(&t_whiteName).?; + self.mesh = rend.getMeshByName(&m_quad).?; + if (self.entity.fetch(core.Scene)) |scene| { _ = scene; } else { diff --git a/engine/rend/src/sgpu/ParticleRenderer.zig b/engine/rend/src/sgpu/ParticleRenderer.zig new file mode 100644 index 0000000..051a5ea --- /dev/null +++ b/engine/rend/src/sgpu/ParticleRenderer.zig @@ -0,0 +1,137 @@ +allocator: std.mem.Allocator, + +ssboScene: *gpu.GPUBuffer = undefined, +ssboSceneUpload: *gpu.GPUTransferBuffer = undefined, +spans: std.ArrayListUnmanaged(core.Span) = .{}, + +renderInfo: std.ArrayListUnmanaged(SgpuParticleRenderInfo) = .{}, + +pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleRenderer"); + +const SgpuParticleRenderInfo = struct { + mesh: rend.IndexedMesh, + texture: *rend.Texture, +}; + +pub fn create(allocator: std.mem.Allocator) !*@This() { + const self = try allocator.create(@This()); + self.* = .{ + .allocator = allocator, + }; + + const device = rend.context().device; + + self.ssboScene = device.createGPUBuffer(&.{ + .usage = .{ + .bufferusageGraphicsStorageRead = true, + .bufferusageVertex = true, + }, + .size = MaxParticleCount * @sizeOf(meshes_vert.Scene), + .props = 0, + }); + + self.ssboSceneUpload = device.createGPUTransferBuffer(&.{ + .usage = .transferbufferusageUpload, + .size = MaxParticleCount * @sizeOf(meshes_vert.Scene), + .props = 0, + }); + + return self; +} + +pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void { + self.spans.clearRetainingCapacity(); + self.renderInfo.clearRetainingCapacity(); + + var offset: usize = 0; + + const device = rend.context().device; + + const uploadMapped: [*]meshes_vert.Scene = @ptrCast(@alignCast(device.mapGPUTransferBuffer(self.ssboSceneUpload, true))); + defer device.unmapGPUTransferBuffer(self.ssboSceneUpload); + + for (rend.ParticleEmitter.BaseContainer.dense.items) |*c| { + const emitter = &c.value; + + for (emitter.finals.items, 0..) |final, i| { + const size = emitter.size.items[i]; + + uploadMapped[i + offset] = .{ + .Model = final, + .textureMode = 0x2, //0x2, // default 0x2 is fullbright + .animation = -1, + .float0 = size, + .flags = 0, //0x4, + }; + } + + try self.renderInfo.append(self.allocator, .{ .texture = emitter.texture, .mesh = emitter.mesh }); + try self.spans.append(self.allocator, .{ .start = @intCast(offset), .size = @intCast(emitter.finals.items.len) }); + offset += emitter.finals.items.len; + } + + if (self.renderInfo.items.len == 0) + return; + + copyPass.uploadToGPUBuffer(&.{ .transfer_buffer = self.ssboSceneUpload, .offset = 0 }, &.{ + .buffer = self.ssboScene, + .offset = 0, + .size = @intCast(offset * @sizeOf(meshes_vert.Scene)), + }, true); +} + +pub fn postMesh(p: *anyopaque, cmd: *gpu.GPUCommandBuffer, renderpass: *gpu.GPURenderPass) void { + const self: *@This() = @ptrCast(@alignCast(p)); + _ = cmd; + + renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1); + renderpass.bindGPUFragmentStorageBuffers(0, &self.ssboScene, 1); + + const ctx = rend.context(); + + for (self.spans.items, 0..) |span, i| { + const ri = self.renderInfo.items[i]; + const mesh = ri.mesh; + const _t = ri.texture; + + var sampler: *gpu.GPUSampler = undefined; + switch (_t.samplerMode) { + .blocky => { + sampler = ctx.blockySampler; + }, + .linear => { + sampler = ctx.linearSampler; + }, + } + + renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 0); + renderpass.bindGPUFragmentSamplers(0, &.{ .texture = _t.texture, .sampler = sampler }, 1); + renderpass.drawGPUIndexedPrimitives(mesh.index.size, span.size, mesh.index.start, @intCast(mesh.vertex.start), @intCast(span.start)); + } +} + +pub fn setup(self: *@This(), device: *gpu.GPUDevice) !void { + _ = self; + _ = device; +} + +pub fn destroy(self: *@This()) void { + self.spans.deinit(self.allocator); + self.renderInfo.deinit(self.allocator); + self.allocator.destroy(self); +} + +const MaxParticleCount = 1_000_000; + +const assets = @import("assets"); +const core = @import("core"); +const std = @import("std"); + +const rend = @import("../rend.zig"); +const renderer = rend.renderer; + +const particles = rend.particles; +const sdl3 = @import("sdl3"); +const gpu = sdl3.gpu; + +const meshes_vert = @import("meshes.vert"); diff --git a/engine/rend/src/sgpu/embedded/texture_white.png b/engine/rend/src/sgpu/embedded/texture_white.png new file mode 100644 index 0000000000000000000000000000000000000000..41a4854ce547fd849e4f5c5e8ebb6281190418cb GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSjKx9jP7LeL$-D%zeLYzopr0P@g$v;Y7A literal 0 HcmV?d00001 diff --git a/engine/rend/src/sgpu/renderer.zig b/engine/rend/src/sgpu/renderer.zig index 37bd171..7a9080b 100644 --- a/engine/rend/src/sgpu/renderer.zig +++ b/engine/rend/src/sgpu/renderer.zig @@ -86,6 +86,7 @@ pub const Renderer = struct { lightPower: f32 = 4.0, + particleRenderer: *ParticleRenderer = undefined, ssaoSystem: *SsaoSystem = undefined, positionTargetFormat: gpu.GPUTextureFormat = .textureformatR16g16b16a16Float, normalTargetFormat: gpu.GPUTextureFormat = .textureformatR16g16b16a16Float, @@ -174,6 +175,7 @@ pub const Renderer = struct { try self.createSamplers(); _ = try core.fs().installFileBytesMount("embedded:texture_sample.png", @constCast(&texture_sample_png), true); + _ = try core.fs().installFileBytesMount("embedded:texture_white.png", @constCast(&texture_white_png), true); _ = try core.fs().installFileBytesMount("embedded:primitive_box.obj", @constCast(&primitive_box_obj), true); // todo... make these embedded @@ -185,6 +187,14 @@ pub const Renderer = struct { ), ); + try assets.load( + assets.MakeImportRefOptions( + "Texture", + "t_white", + .{ .path = "embedded:texture_white.png" }, + ), + ); + try assets.load( assets.MakeImportRefOptions( "Mesh", @@ -194,11 +204,13 @@ pub const Renderer = struct { ); var defaultTextureName = core.MakeName("t_default"); self.defaultTexture = getTexture(&defaultTextureName).?; - self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); try self.createDirectionalShadowsPipeline(); self.skyboxSystem = try self.createRendererEngineObject(SkyboxSystem); + self.particleRenderer = try self.createRendererEngineObject(ParticleRenderer); + self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem); + _ = try core.fs().installFileBytesMount("embedded:plane.obj", @constCast(&plane_obj), true); _ = try core.fs().installFileBytesMount("embedded:screenPlane.obj", @constCast(&screenPlane_obj), true); @@ -352,9 +364,7 @@ pub const Renderer = struct { pub fn createRendererObject(self: *@This(), T: type) !*T { const object = try T.create(self.device, self.allocator, .{}); - try self.registerRendererObject(T, object); - try self.destroys.append(self.allocator, .{ .ptr = object, .func = T.destroy }); return object; @@ -501,7 +511,16 @@ pub const Renderer = struct { pci.target_info.color_target_descriptions = &[4]gpu.GPUColorTargetDescription{ .{ .format = self.hdrTextureFormat, - .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + //.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + .blend_state = std.mem.zeroInit(gpu.GPUColorTargetBlendState, .{ + .alpha_blend_op = .blendopAdd, + .color_blend_op = .blendopAdd, + .src_color_blendfactor = .blendfactorSrcAlpha, + .dst_color_blendfactor = .blendfactorOneMinusSrcAlpha, + .src_alpha_blendfactor = .blendfactorSrcAlpha, + .dst_alpha_blendfactor = .blendfactorOneMinusSrcAlpha, + .enable_blend = true, + }), }, .{ .format = self.hdrTextureFormat, @@ -559,7 +578,7 @@ pub const Renderer = struct { }); } - pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) !void { + pub fn uploadSSBOs(self: *@This(), copyPass: *gpu.GPUCopyPass) void { const container = rend.MeshComponent.BaseContainer; const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount); { @@ -604,6 +623,8 @@ pub const Renderer = struct { } } + self.particleRenderer.uploadSsbos(copyPass) catch unreachable; + if (uploadCount == 0) return; @@ -672,6 +693,7 @@ pub const Renderer = struct { var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize); const ptr: *meshes_vert.Uniforms = @ptrCast(@alignCast(&data)); if (self.activeCamera) |camera| { + ptr.ViewTransform = @bitCast(camera.transform); ptr.ViewProjection = @bitCast(camera.final); ptr.NoTranslateView = @bitCast(camera.noTranslate); } @@ -727,7 +749,7 @@ pub const Renderer = struct { // .size = 4 * 12, // }, true); - try self.uploadSSBOs(copyPass); + self.uploadSSBOs(copyPass); for (self.uploads.items) |upload| { upload.func(upload.ptr, copyPass); @@ -936,6 +958,7 @@ pub const Renderer = struct { for (self.postMesh.items) |interface| { interface.func(interface.ptr, cmd, renderpass); } + renderpass.endGPURenderPass(); self.state.pass = null; } @@ -1127,6 +1150,7 @@ pub const GPUTextureType = gpu.GPUTexture; const plane_obj align(8) = @embedFile("embedded/plane.obj").*; const screenPlane_obj align(8) = @embedFile("embedded/screenPlane.obj").*; const texture_sample_png align(8) = @embedFile("embedded/texture_sample.png").*; +const texture_white_png align(8) = @embedFile("embedded/texture_white.png").*; const primitive_box_obj align(8) = @embedFile("embedded/primitive_box.obj").*; const tracy = core.tracy; @@ -1134,3 +1158,4 @@ const animationSystem = rend.animationSystem; const builtin = @import("builtin"); pub const SsaoSystem = @import("ssao.zig"); +pub const ParticleRenderer = @import("ParticleRenderer.zig"); diff --git a/engine/rend/src/sgpu/ssao.zig b/engine/rend/src/sgpu/ssao.zig index 6dd86c0..fba73f4 100644 --- a/engine/rend/src/sgpu/ssao.zig +++ b/engine/rend/src/sgpu/ssao.zig @@ -196,7 +196,16 @@ pub fn createPipeline(self: *@This()) !void { pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{ .{ .format = self.ssaoOutputFormat, - .blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + //.blend_state = std.mem.zeroes(gpu.GPUColorTargetBlendState), + .blend_state = std.mem.zeroInit(gpu.GPUColorTargetBlendState, .{ + .alpha_blend_op = .blendopAdd, + .color_blend_op = .blendopAdd, + .src_color_blendfactor = .blendfactorSrcAlpha, + .dst_color_blendfactor = .blendfactorOneMinusSrcAlpha, + .src_alpha_blendfactor = .blendfactorSrcAlpha, + .dst_alpha_blendfactor = .blendfactorOneMinusSrcAlpha, + .enable_blend = true, + }), }, }; diff --git a/projects/content/_shaders/dxil/lit_mesh.frag.dxil b/projects/content/_shaders/dxil/lit_mesh.frag.dxil index 4d326c1bd673c933a2ef073d6540db0b79e4cebc..581026e448eeacdb7c82921c0a8f848838e9a9f1 100644 GIT binary patch delta 2314 zcmY*bYfu~46<)n|7d=-7lf@#iLbl37*n(grY7dowQJuujD8y~Ce>f`%FpjaUI>e=} zrjk}d7E}&vCv^o$#=^J`ZJ-gxsa@BZtONns@f10ocGQgB3W^hVN;-nhG|=&MdS$J^ z=!fn(_dEBycfNDZy-OSK8w;9R8XCWD{QAMxKS$?lY1y7Je&Qnz1VQ)53t*Jb7xbN* zP@#25-RbT9rf#C*SKmmU?fPeLVz8;@`Mn)-2qHo3K|TbfeF!YXfNuu#4UNoSm0}2b zdE)1?qo`yj7lLy6uV~V6)msw0u(sz1?b1f<`ixl2`Ej&5NIs-zPJ(RH)1Gfm(Gn!$DPhRP&Wel5%J&@8%1i$=35kU>x7 zBDFn~Rl)s3>2*f*`}mp)@VArP9jWM=3iv;0(Z_Mo2L$q`1hqefXsxbvZb(8pWW<1YSY4B zlG2}O;o%&P)|yIlZrbgS;@x+f;Wn4_Q5a9zSv8{9_t6ouW8=YY?Rn#4sAKVrCZ=6hyO z^+>7C?&2Jyb!(*qwaZ)_&&mSfNKreXl|`10Z*BPkbzHy|pxa)>8 zfoOwm+CFlMfee^fbIutO*fRF$xsj}?IUmlNqvvl3CjDl*Uw(-wR+)_TCYo}X#A0wJ zrn&bJ!I}qiUd@`;-Zk^J96QmT6L9x&%3>~j1g9yne}gmUcM{L|Ph6NYP;wp*GHN?I zONzd^ZYqr)XG0h{vY7i1Fv%r`-;m&IX0A$Mbk~J2rGwE4LFv!xl zTQ+Z-B#IUAY7k>)(1v<7A0$DWPQp>mf0SW@p0#_;(x~nMB>e>2@6^WaO%_@7a8w^V zd{c>g=TLsJ_ry(ip_kN`Xpy;hj_VO+_&`vwngC_&&|pd1HG^omO6i*QyE&lcTDl^e zBK9UsHl_QFE_Ev{M6t+jtXC%~M`rk@PNP$enAf58#EMP$Tdb-ICN%1xjr= zr$IZYMNdf^9gBs&l|-F*iLJO7c6M1Y$_VNwlPgIW9Yq&xJw$N@yqdrwGd{GwwkhSz zhSyF#9e!SN?Wynpt^wO}-cTGKlC8RA9?&r9b8y-f$K|)CSQ%~%<+}xK%8QvqhP#F< zxuR1I_4%Etah*Z1+Cs!;=84SbxTT+aS|JVz&;vzj1sm&c9jh38%*B>TnP zP{BRJr!It+vyOc#r2su+cx=)Z8og&y`*eA8a`AWb{;qWVQ8L}l&pbCF=JuPx-hqWZ z)tT2&`0k>AAeeKO*Z?PERco*l;J42%PGz32Qu|faVXL~XnSCm_-`aIj-QJ*@+yLu0 zZGcaz9{?c(3EWRU3c%n00g@#e*#H0l delta 2238 zcmY+Fe@q+a8OP6e=6pUIu!#b%3&V%6APNqg2}_`3&YhtyONdH-s3X(5UT{W8lM*ZI zw2(Qq<xECU#rK7>iV3`9U;V*$b`Gvb1MIYB$On(sdfzNa7?`ODm*#bZWztX1l}Z zko@&N@B6&Z=Xv#g-uHRunINNUYO^#>8A$8Y&-?=u2gZQ)xnG}=K@b!S>rhO-h~U8s zBv!Aef6j@h|Mm^O@WV0wm(|9+x~8@twG?R~h!yreD~BL)4hex8VJ;WeEsgxm5;X*w zFZ?EVKbCEPA!v#Da#@Gy;cWC+z4qZM(u{8WbUVG5t1RA*cgfOR3pNqF6Wqc23XxWTIFurp^WD&qg{e&`t_}dR{XCgR3=i z3)P;22q%Vq`t%}mtmIkXiPZU#Vvo4b4;n-jKg&4^p}&9K9{~f6^$QW;FO&1W2qG|> z|CLhM5~eM>fk^!+L_Z(~wP_V86P%NV&;hz#8?D8T?t5dCpCDe$sYi*eHS$DcRTyOJ)HY#XPD;|5E^aZkd97a}n1f;$YEYH>Qv9mJshU`?BD^1#vE%6vS7`$fWYFkYS z*`6k3EmBNdrOC9mu}i%0uN6k@@^E2v zkRPW%m-2lUa?=vI&Mmd!v^$TCJ?5siuSx$sBd3-9u8#xpW>fkr+dMpr4c%|Wr^|7Zp01Y){|C9>ww6RQEKcwo}EZ#93E+>}S2c_cyL{zJkFpiTf73ReLM Z0nmJ472p;Dp+^8GMF0vzS>l%t{U81~`yT)R diff --git a/projects/content/_shaders/dxil/meshes.vert.dxil b/projects/content/_shaders/dxil/meshes.vert.dxil index 60fe6bf237262123f69ce26c7ac6b8db19d8cdad..dd3a943528b915dd36fd385b481ee983d3620f48 100644 GIT binary patch delta 4781 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 DNaKW+ diff --git a/projects/content/_shaders/msl/lit_mesh.frag.msl b/projects/content/_shaders/msl/lit_mesh.frag.msl index b72c673..e8da403 100644 --- a/projects/content/_shaders/msl/lit_mesh.frag.msl +++ b/projects/content/_shaders/msl/lit_mesh.frag.msl @@ -18,9 +18,9 @@ struct Scene { float4x4 Model; uint textureMode; - uint pad0; - uint pad1; - uint pad2; + int animation; + uint flags; + float float0; }; struct type_StructuredBuffer_Scene @@ -28,8 +28,8 @@ struct type_StructuredBuffer_Scene Scene _m0[1]; }; -constant float4 _90 = {}; -constant float3 _92 = {}; +constant float4 _92 = {}; +constant float3 _94 = {}; struct main0_out { @@ -52,145 +52,145 @@ struct main0_in fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], texture2d Texture0 [[texture(0)]], texture2d Texture1 [[texture(1)]], texture2d Texture2 [[texture(2)]], texture2d DirectionalShadowDepthMap [[texture(3)]], sampler Sampler0 [[sampler(0)]], sampler Sampler1 [[sampler(1)]], sampler Sampler2 [[sampler(2)]], sampler DirectionalShadowSampler [[sampler(3)]]) { main0_out out = {}; - int _102 = int(scene._m0[in.in_var_TEXCOORD4].textureMode); - int _103 = _102 & 240; - float4 _137; - if (_103 == 16) + int _104 = int(scene._m0[in.in_var_TEXCOORD4].textureMode); + int _105 = _104 & 240; + float4 _139; + if (_105 == 16) { - float3 _124 = float3(Texture0.sample(Sampler0, in.in_var_TEXCOORD0).x, Texture1.sample(Sampler1, in.in_var_TEXCOORD0).x, Texture2.sample(Sampler2, in.in_var_TEXCOORD0).x) + float3(-0.0625, -0.5, -0.5); - _137 = float4(dot(_124, float3(1.164000034332275390625, 0.0, 1.7929999828338623046875)), dot(_124, float3(1.164000034332275390625, -0.212999999523162841796875, -0.53299999237060546875)), dot(_124, float3(1.164000034332275390625, 2.111999988555908203125, 0.0)), 1.0); + float3 _126 = float3(Texture0.sample(Sampler0, in.in_var_TEXCOORD0).x, Texture1.sample(Sampler1, in.in_var_TEXCOORD0).x, Texture2.sample(Sampler2, in.in_var_TEXCOORD0).x) + float3(-0.0625, -0.5, -0.5); + _139 = float4(dot(_126, float3(1.164000034332275390625, 0.0, 1.7929999828338623046875)), dot(_126, float3(1.164000034332275390625, -0.212999999523162841796875, -0.53299999237060546875)), dot(_126, float3(1.164000034332275390625, 2.111999988555908203125, 0.0)), 1.0); } else { - float4 _136; - if (_103 == 0) + float4 _138; + if (_105 == 0) { - _136 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0); + _138 = Texture0.sample(Sampler0, in.in_var_TEXCOORD0); } else { - _136 = _90; + _138 = _92; } - _137 = _136; + _139 = _138; } - float4 _143; - if ((_102 & 1) == 1) + float4 _145; + if ((_104 & 1) == 1) { - _143 = powr(_137, float4(2.2000000476837158203125)); + _145 = powr(_139, float4(2.2000000476837158203125)); } else { - _143 = _137; + _145 = _139; } - if (_143.w < 0.00999999977648258209228515625) + if (_145.w < 0.00999999977648258209228515625) { discard_fragment(); } - float3 _153 = float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * Uniforms.lightPower; - float3 _200; + float3 _155 = float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * Uniforms.lightPower; + float3 _202; do { - float3 _157 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; - float _158 = length(_157); - float _159 = _158 * _158; - float _165; - if (_158 > 2.0) + float3 _159 = Uniforms.lightPosition.xyz - in.in_var_TEXCOORD1; + float _160 = length(_159); + float _161 = _160 * _160; + float _167; + if (_160 > 2.0) { - _165 = 0.5 / _159; + _167 = 0.5 / _161; } else { - _165 = 1.0 / _159; + _167 = 1.0 / _161; } - float _170; - if (_158 > 4.0) + float _172; + if (_160 > 4.0) { - _170 = _165 * 0.5; + _172 = _167 * 0.5; } else { - _170 = _165; + _172 = _167; } - float _172 = (_158 > 15.0) ? 0.0 : _170; - float _174 = (_172 > 1.0) ? 1.0 : _172; + float _174 = (_160 > 15.0) ? 0.0 : _172; + float _176 = (_174 > 1.0) ? 1.0 : _174; if (length(in.in_var_TEXCOORD2) < 0.100000001490116119384765625) { - _200 = (in.in_var_TEXCOORD1 * _153) * _174; + _202 = (in.in_var_TEXCOORD1 * _155) * _176; break; } - float3 _181 = fast::normalize(_157); - _200 = ((_153 * precise::max(dot(_181, in.in_var_TEXCOORD2), 0.0)) * _174) + (((_153 * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_181 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _174); + float3 _183 = fast::normalize(_159); + _202 = ((_155 * precise::max(dot(_183, in.in_var_TEXCOORD2), 0.0)) * _176) + (((_155 * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_183 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _176); break; } while(false); - float3 _217 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); - float3 _219; - _219.x = _217.x; - float2 _220 = _219.xy; - _220.y = -_217.y; - float _227; - int _230; + float3 _219 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5); + float3 _221; + _221.x = _219.x; + float2 _222 = _221.xy; + _222.y = -_219.y; + float _229; int _232; - _227 = 0.0; - _230 = 0; - _232 = -2; - float _228; - int _231; - for (; _232 <= 2; _227 = _228, _230 = _231, _232++) + int _234; + _229 = 0.0; + _232 = 0; + _234 = -2; + float _230; + int _233; + for (; _234 <= 2; _229 = _230, _232 = _233, _234++) { - _231 = _230; - _228 = _227; - for (int _241 = -2; _241 <= 2; ) + _233 = _232; + _230 = _229; + for (int _243 = -2; _243 <= 2; ) { - _231++; - _228 += float((in.in_var_TEXCOORD3.z - 0.0030000000260770320892333984375) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_220 + float2(float(_241) * 0.000244140625, float(_232) * 0.000244140625))).x); - _241++; + _233++; + _230 += float((in.in_var_TEXCOORD3.z - 0.0030000000260770320892333984375) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, (_222 + float2(float(_243) * 0.000244140625, float(_234) * 0.000244140625))).x); + _243++; continue; } } - float3 _270; - if ((_102 & 2) > 0) + float3 _272; + if ((_104 & 2) > 0) { - _270 = _143.xyz * 2.0; + _272 = powr(_145.xyz, float3(0.4545454680919647216796875)); } else { - _270 = _143.xyz * ((float3(0.100000001490116119384765625) + _200) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - (_227 / float(_230))))); + _272 = _145.xyz * ((float3(0.100000001490116119384765625) + _202) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - (_229 / float(_232))))); } - float4 _287; - if (_270.x > 1.0) + float4 _289; + if (_272.x > 1.0) { - float4 _286 = float4(0.0, 0.0, 0.0, 1.0); - _286.x = _270.x; - _287 = _286; + float4 _288 = float4(0.0, 0.0, 0.0, 1.0); + _288.x = _272.x; + _289 = _288; } else { - _287 = float4(0.0, 0.0, 0.0, 1.0); + _289 = float4(0.0, 0.0, 0.0, 1.0); } - float4 _292; - if (_270.y > 1.0) + float4 _294; + if (_272.y > 1.0) { - float4 _291 = _287; - _291.y = _270.y; - _292 = _291; + float4 _293 = _289; + _293.y = _272.y; + _294 = _293; } else { - _292 = _287; + _294 = _289; } - float4 _297; - if (_270.z > 1.0) + float4 _299; + if (_272.z > 1.0) { - float4 _296 = _292; - _296.z = _270.z; - _297 = _296; + float4 _298 = _294; + _298.z = _272.z; + _299 = _298; } else { - _297 = _292; + _299 = _294; } - out.out_var_SV_Target0 = float4(_270, _143.w); - out.out_var_SV_Target1 = _297; + out.out_var_SV_Target0 = float4(_272, _145.w); + out.out_var_SV_Target1 = _299; out.out_var_SV_Target2 = float4(in.in_var_TEXCOORD1, 1.0); out.out_var_SV_Target3 = float4(in.in_var_TEXCOORD5, 1.0); return out; diff --git a/projects/content/_shaders/msl/meshes.vert.msl b/projects/content/_shaders/msl/meshes.vert.msl index 5cb0413..4cff0f8 100644 --- a/projects/content/_shaders/msl/meshes.vert.msl +++ b/projects/content/_shaders/msl/meshes.vert.msl @@ -9,7 +9,7 @@ struct Scene uint textureMode; int animation; uint flags; - uint pad2; + float float0; }; struct type_StructuredBuffer_Scene @@ -31,7 +31,9 @@ struct type_Uniforms { float4x4 ViewProjection; float4x4 NoTranslateView; + float4x4 ViewTransform; float4x4 ShadowMapProjection; + float4 cameraPosition; float time; }; @@ -58,35 +60,61 @@ 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)]], const device type_StructuredBuffer_BoneTransform& animationBuffer [[buffer(2)]], uint gl_InstanceIndex [[instance_id]]) { main0_out out = {}; - float3 _103; + float3 _112; if (scene._m0[gl_InstanceIndex].animation != (-1)) { - float3 _75; - _75 = float3(0.0); - for (int _78 = 0; _78 < 4; ) + float3 _84; + _84 = float3(0.0); + for (int _87 = 0; _87 < 4; ) { - uint _84 = (8u * uint(_78)) & 31u; - _75 += ((animationBuffer._m0[uint(scene._m0[gl_InstanceIndex].animation) + ((in.in_var_TEXCOORD4 >> _84) & 255u)].final * float4(in.in_var_TEXCOORD0, 1.0)).xyz * (float((in.in_var_TEXCOORD5 >> _84) & 255u) * 0.0039215688593685626983642578125)); - _78++; + uint _93 = (8u * uint(_87)) & 31u; + _84 += ((animationBuffer._m0[uint(scene._m0[gl_InstanceIndex].animation) + ((in.in_var_TEXCOORD4 >> _93) & 255u)].final * float4(in.in_var_TEXCOORD0, 1.0)).xyz * (float((in.in_var_TEXCOORD5 >> _93) & 255u) * 0.0039215688593685626983642578125)); + _87++; continue; } - _103 = _75; + _112 = _84; } else { - _103 = in.in_var_TEXCOORD0; + _112 = in.in_var_TEXCOORD0; + } + float4 _116 = float4(_112, 1.0); + float3 _210; + float3 _211; + float3 _212; + float4 _213; + float4 _214; + if (int(scene._m0[gl_InstanceIndex].flags & 4u) > 0) + { + float3 _128 = (scene._m0[gl_InstanceIndex].Model * float4(0.0, 0.0, 0.0, 1.0)).xyz; + float3 _133 = fast::normalize(_128 - Uniforms.cameraPosition.xyz); + float3 _135 = fast::normalize(cross(float3(0.0, 1.0, 0.0), _133)); + float _141 = scene._m0[gl_InstanceIndex].float0 * (length(Uniforms.cameraPosition.xyz - _128) * 0.100000001490116119384765625); + float4 _155 = float4((_128 + ((_135 * in.in_var_TEXCOORD0.x) * _141)) + ((_135 * in.in_var_TEXCOORD0.y) * _141), 1.0); + _210 = _155.xyz; + _211 = _133; + _212 = float3(0.0, 0.0, 1.0); + _213 = Uniforms.ViewProjection * _155; + _214 = _155; + } + else + { + float4 _162 = scene._m0[gl_InstanceIndex].Model * _116; + float4x4 _197 = float4x4(float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][0], scene._m0[gl_InstanceIndex].Model[1][0], scene._m0[gl_InstanceIndex].Model[2][0])), 0.0), float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][1], scene._m0[gl_InstanceIndex].Model[1][1], scene._m0[gl_InstanceIndex].Model[2][1])), 0.0), float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][2], scene._m0[gl_InstanceIndex].Model[1][2], scene._m0[gl_InstanceIndex].Model[2][2])), 0.0), float4(0.0, 0.0, 0.0, 1.0)); + float4 _201 = float4(in.in_var_TEXCOORD1, 1.0); + _210 = _162.xyz; + _211 = fast::normalize(_201 * _197).xyz; + _212 = (_201 * (_197 * transpose(Uniforms.NoTranslateView))).xyz; + _213 = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _116); + _214 = _162; } - float4 _107 = float4(_103, 1.0); - float4 _110 = scene._m0[gl_InstanceIndex].Model * _107; - float4x4 _145 = float4x4(float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][0], scene._m0[gl_InstanceIndex].Model[1][0], scene._m0[gl_InstanceIndex].Model[2][0])), 0.0), float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][1], scene._m0[gl_InstanceIndex].Model[1][1], scene._m0[gl_InstanceIndex].Model[2][1])), 0.0), float4(fast::normalize(float3(scene._m0[gl_InstanceIndex].Model[0][2], scene._m0[gl_InstanceIndex].Model[1][2], scene._m0[gl_InstanceIndex].Model[2][2])), 0.0), float4(0.0, 0.0, 0.0, 1.0)); - float4 _149 = float4(in.in_var_TEXCOORD1, 1.0); out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3; - out.out_var_TEXCOORD1 = _110.xyz; - out.out_var_TEXCOORD2 = fast::normalize(_149 * _145).xyz; - out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _110; + out.out_var_TEXCOORD1 = _210; + out.out_var_TEXCOORD2 = _211; + out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _214; out.out_var_TEXCOORD4 = gl_InstanceIndex; - out.out_var_TEXCOORD5 = (_149 * (_145 * transpose(Uniforms.NoTranslateView))).xyz; - out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _107); + out.out_var_TEXCOORD5 = _212; + out.gl_Position = _213; return out; } diff --git a/projects/content/_shaders/spv/lit_mesh.frag.spv b/projects/content/_shaders/spv/lit_mesh.frag.spv index c6e2acf04b349452e91c28b9b6d79dc16d781118..59dfd2a3a089bf03b70c0b0dae4836c75bcd0611 100644 GIT binary patch literal 8096 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 Ly$ky|-Ra;t_D3>u literal 8044 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

{-tpvB_4U6MYm4m8AUdacwl45 z;>N~Vw2-YSx#BD$?>Lxw_i)F&6UQL2Sb-l02)vk8;s0EM7xOCqKX@M8T*m1Wd0s#^ zk2zd{zla=on*XH)PxHSFZZ6~Wi9D|$n@3+);IASFp5~uO@HGDkaB~?q0nK1O75HnA z@mnDG82IZ6Zf}8~OmK6?9Xo|=E>~c0AV>bd-Yl`Ax8i$z3(R=^wO<2;|J%s+;tK2? zdsB8AxTgPSn9fKtU8+gXn-w%oxtlkx~lY(E_$~C@p9|G%|5$ zZyDPFu^^;~GAb<$xUhD)WPTKq z832ql5`a^9kpKb!0AJz#Z}8pH5_ku%|0Ab70Kj4McxA;A@WtDc^h)_3T`tZZOV^Qb zSWk+K3!*Tix0a=lP5GOK>zS4t7oC4aRZo1Li-hm^F)uME>|o-CZItMkn1b+()3m%% zQ08Lj#_t+lxLht-OV>BzvpKoBsVN8fd(U0lwr!XS4hqy|Rr}9z!{1*rk=*h5IxZYM zfdiSxvyPIs_TewfNK41K0WP=KUy1-eP*h_cPRhw%!mUsG=kMI_{?@EPYAuzG`5zcebn@dZ0_-$A9h^mhMUeZ0%a;C}=TI-K${&f= z)78>O+t3N(a!zm81sojfCGLV|fg%!f9)FoGLBovmH+Oc|6(8Bis%~quN?SDf8yQps z6};*s*dRZD$E6{;cA&dkg>HXD9MgdBrMW`kY}N&9b6dFzEgKb58J)zt#A(f83UUY| zJDQ;j+OJJXS}bupB2%GfI5lH}EDD0jvLzO~X|fgSt->x&P>>?i7qpHU`w-mX zm&eE+i6A!Fp{!X5Me5YeOq#JOM=_`SIe_stb`*J|XP*Ua76!tY|4f!Y%W%c+CjQ~$ z;do)HHrZg?J+F&m4qq3=x;7s)FxN(Kf)N6^hS4$e?3jcr4ZBXyOq?-BDl;_Gk}q8y z=L-yzNOkek!$Q%dbAqeCj7qsDO)Ifnq-im|F5sDeRC*_8`ut-nFQ9{ad*^R!GVgWh z{?xS^qn@;F?74BkAX!v9FX0x&LMSnTU8)TktVBM9Wk@o}AFN=9K}nqDe$?)yIfQ`G zSIFP*Mg}z=yC6Q?_OH^^o^9x~N}C z(`Ga3BNTyGwm8xf=}e+~O|7upmm?$$cxkiGRwA*i5-S-CDIP%LBoP{}^$1%sbe`vX zgb@MW6yIwPu{O@G^lPXsoR8OWgeUhtPnZZM7o&64<5GQP5N6)3SN4DpyV~<}46GFn z{xL7rPw=njVoi++=C0Mego*@Cmp6~vA8+=7)LkDn@OMG#n5kq#z1-5r(}zB7au%%Z zjAQDJ%?ZYyUDGdnE4@2!4IP#9i8Qf39lKMCa@oHm%cPrQz!ML43SN5hrHd{90G8@j ABLDyZ literal 0 HcmV?d00001 diff --git a/projects/content/textures/PixelSmoke.png b/projects/content/textures/PixelSmoke.png new file mode 100644 index 0000000000000000000000000000000000000000..d6cb0ca44751f9413a6beb1468b7beaad6365aa8 GIT binary patch literal 1378 zcmV-o1)chdP)Px)97#k$RCt{2oy&FHFbqYhoOI%~D@dbh$Q5|)S|*#&hfzd{A3WfJ#9iAK#dis4 zC~2Hh5ClOG1UqtA4`4N3uh*}c-#?DyLvAz;$J0F6s?3I7LqmoTU=UR3HBd5y0G((D ze@0q_5TFt3;7cSWa4kSjC^M7B6n=?>2<`-s2%~l4Sc5N_mB57n$RMsJ&_nPgGZIh> z;4KJCMkSyXAj0owL;@-SK%u{P{`@Ck3~KaBU@m}A=)EEL;7*7h34UUSQb!Em-$UpndAxKY+@VqdI>YxCd<_Z_ zo~pnP^Z+&uKY2M9Xbb2F-^FANK;IT%Eg-`G4>Jkw+5n^iG={%R@EOW#Abt%H;Xguk z?xHOq!tX-064cs&SOtjiyP=p1_{YEkiW4Tod`?6JXjuK`CrXUz+)N7);fr84N9Yz1 z;kRQlS5x}{53Aog{I`yu{Q{1ohj;By2dJ%JtMGe5ul=6245|_!1ketDH1w9gXDtJq z;cEbbr*_`};aeQz3bjQfeG#ZNaP3f*l|ZruXbjjQi1V?RY70XZz^MFNhF_vN4)~&y zY60khvV@;u8_z9w&jV=Q3mAoUvbDwqU0f0ZAP2}AeujN~k1$sNFOy3>PV=XN2ce$S z3((_*RoPhqtoQqw@Fs0aq!qyBL^9IyY8aaU-orr~jVp5nF0Vr0?j<5)@A_%FwFT9`Hz>EM?FF6KdFjRmj|AsIKurl;= z&k7K2zyWvH0Z{=qM?!$80*;ZY03iW6wKfnfU~?n|h$`Tar~sQIDL_0QK+e^507C^> z>QyUmFbJ?R^m2y)o5Lai{YqIC76DcSA@%e}?em3T2(UTB0sx*1j5c6EQ~(T=<^Kvc z0ip^hGbI4%@o?`FxEeoO1@I0keAtaPRsmeCBF{_<0DMcxn*`p*n-Xya$atAlKw1zb@EB+(kI0#|>x z0wutw;bY>XGFY#2lNW0s0vyNj@p`=y!Mg(1p|)c7Ruy_5AYK=H#&nJ}HiANeI_7f& z6X5ib(ELORp_miRtze21Cc$hj&U-ab0WLO%c9-CjZ4NAM22o9bB9!NSXdI;S^(59G z5w)NR{%Wh<@^&!I!~mf`N9*SS=z5|cF3wA(1*Ep`u3xDo(1l;SQ_FNSC{LPa5$J+{ zLahaKJS*U}EqEL=RRuUxPAGF#pb!3T@u^({WCZ^8JcA7Mp_fnzkYpstXv*L!^vqN1 zWo`j2oI{Zm!e!vSm{foyTLpp&)c-m*{`DLOW)&b4l>kHQ0<+!q>$hnsZUJq1jy_xg5<|#w*q8#6G3{f#JvES9YjEElr1AbW>pbT zyQIqrkXc0p^!E6&0%SakpmA?xc>yw>M9{n`wv7N8W)UpzhHfW734;vQx4^d+phQy! k>(EO=fC|z=Foj<72leu2D_R$OQvd(}07*qoM6N<$f_NlI;Q#;t literal 0 HcmV?d00001 diff --git a/projects/content/textures/texture_white.png b/projects/content/textures/texture_white.png new file mode 100644 index 0000000000000000000000000000000000000000..41a4854ce547fd849e4f5c5e8ebb6281190418cb GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSjKx9jP7LeL$-D%zeLYzopr0P@g$v;Y7A literal 0 HcmV?d00001 diff --git a/projects/sampleGame/externGame/externGame.zig b/projects/sampleGame/externGame/externGame.zig index c05f6e5..0d8e72c 100644 --- a/projects/sampleGame/externGame/externGame.zig +++ b/projects/sampleGame/externGame/externGame.zig @@ -116,6 +116,7 @@ pub const ExternGameObject = struct { displayRandRangeImgui("Acceleration", &emitter.particleAcceleration); displayRandRangeImgui("Velocity", &emitter.particleVelocity); displayRandRangeImgui("Life", &emitter.particleLife); + displayRandRangeImgui("Size", &emitter.particleSizeSpawn); displayRandRangeImgui("spawnRate", &emitter.spawnRate); if (emitter.gravity != null) { @@ -139,7 +140,8 @@ pub const ExternGameObject = struct { editVector("gravity", &emitter.gravity.?); } - _ = ig.inputInt("maaxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{}); + _ = ig.inputInt("maxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{}); + _ = ig.checkbox("showDebug", &emitter._showDebug); } ig.end(); } diff --git a/projects/sampleGame/main.zig b/projects/sampleGame/main.zig index 42d0e52..ec1edf7 100644 --- a/projects/sampleGame/main.zig +++ b/projects/sampleGame/main.zig @@ -68,6 +68,11 @@ const assetReferences = [_]assets.AssetImportReference{ "t_fox", .{ .path = "gltf-samples/Fox/glTF/Texture.png" }, ), + assets.MakeImportRefOptions( + "Texture", + "t_pixelSmoke", + .{ .path = "textures/PixelSmoke.png" }, + ), assets.MakeImportRefOptions("Texture", "t_crate", .{ .path = "textures/Crate.png", }), @@ -126,6 +131,8 @@ pub const ParticleObject = struct { particle._showDebug = true; particle.start(); particle.gravity = .{ .y = -9.8 }; + var name = core.MakeName("t_pixelSmoke"); + particle.texture = rend.getTexture(&name).?; self.entity = e;