particle systems update
This commit is contained in:
parent
eaf1d2bcb7
commit
85c18f29ec
|
|
@ -10,9 +10,9 @@ const pod = lua.pod;
|
||||||
// LUA END
|
// LUA END
|
||||||
|
|
||||||
// vector versions.
|
// vector versions.
|
||||||
pub const f32x4 = @Vector(4, f32);
|
pub const f32x4 = @Vector(4, f32); // __m128_int
|
||||||
pub const f32x8 = @Vector(8, f32);
|
pub const f32x8 = @Vector(8, f32); // __m256_int
|
||||||
pub const f32x16 = @Vector(16, f32);
|
pub const f32x16 = @Vector(16, f32); // __m512_int
|
||||||
|
|
||||||
pub const f32x4_zero = std.mem.zeroes(@Vector(4, f32));
|
pub const f32x4_zero = std.mem.zeroes(@Vector(4, f32));
|
||||||
pub const f32x8_zero = std.mem.zeroes(@Vector(8, f32));
|
pub const f32x8_zero = std.mem.zeroes(@Vector(8, f32));
|
||||||
|
|
|
||||||
|
|
@ -85,20 +85,21 @@ Output main(Input input)
|
||||||
if(billboard > 0)
|
if(billboard > 0)
|
||||||
{
|
{
|
||||||
float3 billboardPosition = mul(scene[input.Instance].Model, float4(0,0,0,1)).xyz;
|
float3 billboardPosition = mul(scene[input.Instance].Model, float4(0,0,0,1)).xyz;
|
||||||
float3 toCamera = normalize(billboardPosition - cameraPosition.xyz);
|
float3 toCamera = normalize(cameraPosition.xyz - billboardPosition);
|
||||||
|
|
||||||
float3 up = float3(0,1,0);
|
float3 up = float3(0,1,0);
|
||||||
float3 right = normalize(cross(up, toCamera));
|
float3 right = normalize(cross(up, toCamera));
|
||||||
up = cross(toCamera, right);
|
up = cross(toCamera, right);
|
||||||
|
//toCamera = float3(0, 0, -1);
|
||||||
|
|
||||||
float d = length(cameraPosition.xyz - billboardPosition);
|
float d = length(cameraPosition.xyz - billboardPosition);
|
||||||
float perspectiveScale = d * 0.1f; // adjust multiplier as needed
|
float perspectiveScale = 1.0f; // adjust multiplier as needed
|
||||||
|
|
||||||
float finalSize = scene[input.Instance].float0 * perspectiveScale;
|
float finalSize = scene[input.Instance].float0 * perspectiveScale;
|
||||||
|
|
||||||
float3 wp = billboardPosition +
|
float3 wp = billboardPosition +
|
||||||
mul(mul(right, input.Position.x), finalSize) +
|
mul(mul(right, -input.Position.x), finalSize) +
|
||||||
mul(mul(right, input.Position.y), finalSize);
|
mul(mul(up, input.Position.y), finalSize);
|
||||||
|
|
||||||
WorldPos = float4(wp, 1.0);
|
WorldPos = float4(wp, 1.0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,10 @@ pub const ParticleEmitter = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(self: *@This(), dt: f64) void {
|
pub fn update(self: *@This(), dt: f64) void {
|
||||||
|
if (self.state == .paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (self.state != .dead) {
|
if (self.state != .dead) {
|
||||||
self.updateSpawn(dt);
|
self.updateSpawn(dt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ spans: std.ArrayListUnmanaged(core.Span) = .{},
|
||||||
|
|
||||||
renderInfo: std.ArrayListUnmanaged(SgpuParticleRenderInfo) = .{},
|
renderInfo: std.ArrayListUnmanaged(SgpuParticleRenderInfo) = .{},
|
||||||
|
|
||||||
|
lastParticleCount: u32 = 0,
|
||||||
|
|
||||||
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleRenderer");
|
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "rend.ParticleRenderer");
|
||||||
|
|
||||||
const SgpuParticleRenderInfo = struct {
|
const SgpuParticleRenderInfo = struct {
|
||||||
|
|
@ -58,10 +60,10 @@ pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void {
|
||||||
|
|
||||||
uploadMapped[i + offset] = .{
|
uploadMapped[i + offset] = .{
|
||||||
.Model = final,
|
.Model = final,
|
||||||
.textureMode = 0x2, //0x2, // default 0x2 is fullbright
|
.textureMode = if (emitter.billboard) 0x2 else 0x0, //0x2, // default 0x2 is fullbright
|
||||||
.animation = -1,
|
.animation = -1,
|
||||||
.float0 = size,
|
.float0 = size,
|
||||||
.flags = 0, //0x4,
|
.flags = if (emitter.billboard) 0x4 else 0, //0x4 for billboard mode
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +72,8 @@ pub fn uploadSsbos(self: *@This(), copyPass: *gpu.GPUCopyPass) !void {
|
||||||
offset += emitter.finals.items.len;
|
offset += emitter.finals.items.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.lastParticleCount = @intCast(offset);
|
||||||
|
|
||||||
if (self.renderInfo.items.len == 0)
|
if (self.renderInfo.items.len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -121,7 +125,7 @@ pub fn destroy(self: *@This()) void {
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
const MaxParticleCount = 1_000_000;
|
const MaxParticleCount = 10_000_000;
|
||||||
|
|
||||||
const assets = @import("assets");
|
const assets = @import("assets");
|
||||||
const core = @import("core");
|
const core = @import("core");
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ pub const Renderer = struct {
|
||||||
depthTexture: *gpu.GPUTexture = undefined,
|
depthTexture: *gpu.GPUTexture = undefined,
|
||||||
depthFormat: gpu.GPUTextureFormat = .textureformatD32Float,
|
depthFormat: gpu.GPUTextureFormat = .textureformatD32Float,
|
||||||
|
|
||||||
|
transparentDepthTexture: *gpu.GPUTexture = undefined,
|
||||||
|
|
||||||
textureList: *TextureList = undefined,
|
textureList: *TextureList = undefined,
|
||||||
|
|
||||||
shadowMapProjection: core.Transform = core.zm.identity(),
|
shadowMapProjection: core.Transform = core.zm.identity(),
|
||||||
|
|
@ -398,6 +400,7 @@ pub const Renderer = struct {
|
||||||
gci.usage = .{ .textureusageDepthStencilTarget = true };
|
gci.usage = .{ .textureusageDepthStencilTarget = true };
|
||||||
|
|
||||||
self.depthTexture = self.device.createGPUTexture(&gci);
|
self.depthTexture = self.device.createGPUTexture(&gci);
|
||||||
|
self.transparentDepthTexture = self.device.createGPUTexture(&gci);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discoverFormats(self: *@This()) !void {
|
pub fn discoverFormats(self: *@This()) !void {
|
||||||
|
|
@ -696,6 +699,7 @@ pub const Renderer = struct {
|
||||||
ptr.ViewTransform = @bitCast(camera.transform);
|
ptr.ViewTransform = @bitCast(camera.transform);
|
||||||
ptr.ViewProjection = @bitCast(camera.final);
|
ptr.ViewProjection = @bitCast(camera.final);
|
||||||
ptr.NoTranslateView = @bitCast(camera.noTranslate);
|
ptr.NoTranslateView = @bitCast(camera.noTranslate);
|
||||||
|
ptr.cameraPosition = @bitCast(camera.finalPos.toZm());
|
||||||
}
|
}
|
||||||
ptr.ShadowMapProjection = @bitCast(self.shadowMapProjection);
|
ptr.ShadowMapProjection = @bitCast(self.shadowMapProjection);
|
||||||
// ptr.ViewProjection = @bitCast(self.shadowMapProjection);
|
// ptr.ViewProjection = @bitCast(self.shadowMapProjection);
|
||||||
|
|
@ -963,6 +967,45 @@ pub const Renderer = struct {
|
||||||
self.state.pass = null;
|
self.state.pass = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn renderTransparents(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
|
const targetInfo: [4]gpu.GPUColorTargetInfo = .{
|
||||||
|
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
.texture = self.state.targetTexture,
|
||||||
|
.load_op = .loadopLoad,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
}),
|
||||||
|
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
.texture = self.state.emissiveTarget,
|
||||||
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
}),
|
||||||
|
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
.texture = self.state.positionTarget,
|
||||||
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
}),
|
||||||
|
std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
|
.texture = self.state.normalTarget,
|
||||||
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const depthTarget = std.mem.zeroInit(gpu.GPUDepthStencilTargetInfo, .{
|
||||||
|
.texture = self.transparentDepthTexture,
|
||||||
|
.load_op = .loadopDontCare,
|
||||||
|
.store_op = .storeopDontCare,
|
||||||
|
.stencil_load_op = .loadopDontCare,
|
||||||
|
.stencil_store_op = .storeopDontCare,
|
||||||
|
.clear_depth = 1.0,
|
||||||
|
.clear_stencil = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderpass = cmd.beginGPURenderPass(&targetInfo, 4, &depthTarget);
|
||||||
|
|
||||||
|
renderpass.endGPURenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn drawPostProcess(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
pub fn drawPostProcess(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
const postProcTargetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
const postProcTargetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
.texture = self.state.swapchainTargetTexture.?,
|
.texture = self.state.swapchainTargetTexture.?,
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -60,61 +60,60 @@ 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]])
|
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 = {};
|
main0_out out = {};
|
||||||
float3 _112;
|
float3 _111;
|
||||||
if (scene._m0[gl_InstanceIndex].animation != (-1))
|
if (scene._m0[gl_InstanceIndex].animation != (-1))
|
||||||
{
|
{
|
||||||
float3 _84;
|
float3 _83;
|
||||||
_84 = float3(0.0);
|
_83 = float3(0.0);
|
||||||
for (int _87 = 0; _87 < 4; )
|
for (int _86 = 0; _86 < 4; )
|
||||||
{
|
{
|
||||||
uint _93 = (8u * uint(_87)) & 31u;
|
uint _92 = (8u * uint(_86)) & 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));
|
_83 += ((animationBuffer._m0[uint(scene._m0[gl_InstanceIndex].animation) + ((in.in_var_TEXCOORD4 >> _92) & 255u)].final * float4(in.in_var_TEXCOORD0, 1.0)).xyz * (float((in.in_var_TEXCOORD5 >> _92) & 255u) * 0.0039215688593685626983642578125));
|
||||||
_87++;
|
_86++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_112 = _84;
|
_111 = _83;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_112 = in.in_var_TEXCOORD0;
|
_111 = in.in_var_TEXCOORD0;
|
||||||
}
|
}
|
||||||
float4 _116 = float4(_112, 1.0);
|
float4 _115 = float4(_111, 1.0);
|
||||||
float3 _210;
|
float3 _207;
|
||||||
float3 _211;
|
float3 _208;
|
||||||
float3 _212;
|
float3 _209;
|
||||||
float4 _213;
|
float4 _210;
|
||||||
float4 _214;
|
float4 _211;
|
||||||
if (int(scene._m0[gl_InstanceIndex].flags & 4u) > 0)
|
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 _127 = (scene._m0[gl_InstanceIndex].Model * float4(0.0, 0.0, 0.0, 1.0)).xyz;
|
||||||
float3 _133 = fast::normalize(_128 - Uniforms.cameraPosition.xyz);
|
float3 _132 = fast::normalize(Uniforms.cameraPosition.xyz - _127);
|
||||||
float3 _135 = fast::normalize(cross(float3(0.0, 1.0, 0.0), _133));
|
float3 _134 = fast::normalize(cross(float3(0.0, 1.0, 0.0), _132));
|
||||||
float _141 = scene._m0[gl_InstanceIndex].float0 * (length(Uniforms.cameraPosition.xyz - _128) * 0.100000001490116119384765625);
|
float4 _152 = float4((_127 + ((_134 * (-in.in_var_TEXCOORD0.x)) * scene._m0[gl_InstanceIndex].float0)) + ((cross(_132, _134) * in.in_var_TEXCOORD0.y) * scene._m0[gl_InstanceIndex].float0), 1.0);
|
||||||
float4 _155 = float4((_128 + ((_135 * in.in_var_TEXCOORD0.x) * _141)) + ((_135 * in.in_var_TEXCOORD0.y) * _141), 1.0);
|
_207 = _152.xyz;
|
||||||
_210 = _155.xyz;
|
_208 = _132;
|
||||||
_211 = _133;
|
_209 = float3(0.0, 0.0, 1.0);
|
||||||
_212 = float3(0.0, 0.0, 1.0);
|
_210 = Uniforms.ViewProjection * _152;
|
||||||
_213 = Uniforms.ViewProjection * _155;
|
_211 = _152;
|
||||||
_214 = _155;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float4 _162 = scene._m0[gl_InstanceIndex].Model * _116;
|
float4 _159 = scene._m0[gl_InstanceIndex].Model * _115;
|
||||||
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));
|
float4x4 _194 = 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);
|
float4 _198 = float4(in.in_var_TEXCOORD1, 1.0);
|
||||||
_210 = _162.xyz;
|
_207 = _159.xyz;
|
||||||
_211 = fast::normalize(_201 * _197).xyz;
|
_208 = fast::normalize(_198 * _194).xyz;
|
||||||
_212 = (_201 * (_197 * transpose(Uniforms.NoTranslateView))).xyz;
|
_209 = (_198 * (_194 * transpose(Uniforms.NoTranslateView))).xyz;
|
||||||
_213 = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _116);
|
_210 = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _115);
|
||||||
_214 = _162;
|
_211 = _159;
|
||||||
}
|
}
|
||||||
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3;
|
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3;
|
||||||
out.out_var_TEXCOORD1 = _210;
|
out.out_var_TEXCOORD1 = _207;
|
||||||
out.out_var_TEXCOORD2 = _211;
|
out.out_var_TEXCOORD2 = _208;
|
||||||
out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _214;
|
out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _211;
|
||||||
out.out_var_TEXCOORD4 = gl_InstanceIndex;
|
out.out_var_TEXCOORD4 = gl_InstanceIndex;
|
||||||
out.out_var_TEXCOORD5 = _212;
|
out.out_var_TEXCOORD5 = _209;
|
||||||
out.gl_Position = _213;
|
out.gl_Position = _210;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -99,8 +99,10 @@ pub const ExternGameObject = struct {
|
||||||
pub fn particleDebug(self: *@This()) void {
|
pub fn particleDebug(self: *@This()) void {
|
||||||
if (ig.begin("particleDebugger", null, .{})) {
|
if (ig.begin("particleDebugger", null, .{})) {
|
||||||
var buffer: [256]u8 = undefined;
|
var buffer: [256]u8 = undefined;
|
||||||
|
ig.textFmt("active particles: {d}", .{rend.context().particleRenderer.lastParticleCount}) catch unreachable;
|
||||||
for (rend.ParticleEmitter.BaseContainer.dense.items, 0..) |*emitter, i| {
|
for (rend.ParticleEmitter.BaseContainer.dense.items, 0..) |*emitter, i| {
|
||||||
ig.textFmt("emitter {d}", .{emitter.sparseIndex.index}) catch {};
|
ig.textFmt("emitter {d}", .{emitter.sparseIndex.index}) catch {};
|
||||||
|
ig.sameLine(0, 10);
|
||||||
if (ig.smallButton(std.fmt.bufPrintZ(&buffer, "edit##{d}", .{i}) catch unreachable)) {
|
if (ig.smallButton(std.fmt.bufPrintZ(&buffer, "edit##{d}", .{i}) catch unreachable)) {
|
||||||
self.editParticle = emitter.value.entity;
|
self.editParticle = emitter.value.entity;
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +144,20 @@ pub const ExternGameObject = struct {
|
||||||
|
|
||||||
_ = ig.inputInt("maxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{});
|
_ = ig.inputInt("maxParticles##particleEd", @ptrCast(&emitter.maxParticles), 1, 5, .{});
|
||||||
_ = ig.checkbox("showDebug", &emitter._showDebug);
|
_ = ig.checkbox("showDebug", &emitter._showDebug);
|
||||||
|
_ = ig.checkbox("useLocalScene", &emitter.useLocalScene);
|
||||||
|
_ = ig.checkbox("billboard", &emitter.billboard);
|
||||||
|
|
||||||
|
if (ig.smallButton("alive")) {
|
||||||
|
emitter.state = .alive;
|
||||||
|
}
|
||||||
|
ig.sameLine(0, 10);
|
||||||
|
if (ig.smallButton("kill")) {
|
||||||
|
emitter.state = .dead;
|
||||||
|
}
|
||||||
|
ig.sameLine(0, 10);
|
||||||
|
if (ig.smallButton("pause")) {
|
||||||
|
emitter.state = .paused;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ig.end();
|
ig.end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue