From cb485cb20baadf7f3ca3569794862b16d5fc87b4 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Sun, 23 Jul 2023 11:11:53 +0200 Subject: [PATCH] ComputeParticlesTest: Improve demo --- assets/shaders/compute/compute_particles.nzsl | 4 +- tests/ComputeParticlesTest/main.cpp | 50 +++++++++++++------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/assets/shaders/compute/compute_particles.nzsl b/assets/shaders/compute/compute_particles.nzsl index be9ddfd70..a24a91f93 100644 --- a/assets/shaders/compute/compute_particles.nzsl +++ b/assets/shaders/compute/compute_particles.nzsl @@ -47,11 +47,11 @@ fn main(input: Input) // Gets pushed by the cursor let attract_pos = sceneData.mousePos; let dist = length(attract_pos - data.particles[index].position); - data.particles[index].velocity -= 10000.0 * sceneData.effectRadius / min(dist, sceneData.effectRadius) * sceneData.deltaTime * (attract_pos - data.particles[index].position) / (dist * dist * dist * dist); + data.particles[index].velocity -= 100000.0 * sceneData.effectRadius / min(dist, sceneData.effectRadius) * sceneData.deltaTime * (attract_pos - data.particles[index].position) / (dist * dist * dist); // But want to return to their original position let dist = length(data.particles[index].targetPosition - data.particles[index].position); - let shouldUseDir = dist > 1.0; + let shouldUseDir = dist > 0.1; data.particles[index].velocity += 100.0 * sceneData.deltaTime * select(shouldUseDir, normalize(data.particles[index].targetPosition - data.particles[index].position), vec2[f32](0.0, 0.0)); // Lose speed with time diff --git a/tests/ComputeParticlesTest/main.cpp b/tests/ComputeParticlesTest/main.cpp index 37bf38e43..a23f39e08 100644 --- a/tests/ComputeParticlesTest/main.cpp +++ b/tests/ComputeParticlesTest/main.cpp @@ -35,7 +35,7 @@ std::shared_ptr GenerateSpriteTexture(Nz::RenderDevice& device, std int main() { - Nz::Vector2ui windowSize = { 1280, 720 }; + Nz::Vector2ui windowSize = { 1920, 1080 }; std::filesystem::path resourceDir = "assets/examples"; if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir)) @@ -99,18 +99,13 @@ int main() std::vector particleBufferInitialData(bufferSize); Nz::AccessByOffset(particleBufferInitialData.data(), particleCountOffset) = particleCount; - std::mt19937 rand(std::random_device{}()); - std::uniform_real_distribution colorDis(0.f, 1.f); - std::uniform_real_distribution posXDis(-float(windowSize.x), windowSize.x * 2.f); - std::uniform_real_distribution posYDis(-float(windowSize.y), windowSize.y * 2.f); - std::uniform_real_distribution velDis(-50.f, 50.f); - Nz::Vector2f logoImageSize(Nz::Vector2ui(logo->GetSize())); - Nz::Vector2f logoSize = Nz::Vector2f(windowSize) * 0.8f; + float logoRatio = logoImageSize.x / logoImageSize.y; + + Nz::Vector2f logoSize = Nz::Vector2f(windowSize.x * 0.8f, windowSize.x * 0.8f / logoRatio); // Center the logo in the canvas Nz::Vector2f posScale = logoSize / logoImageSize; - Nz::Vector2f posOffset = (Nz::Vector2f(windowSize) - logoSize) * 0.5f; // from image space to world space (topleft Y down to bottomleft Y up) @@ -118,6 +113,9 @@ int main() posOffset.y += logoSize.y; // Build particles + std::mt19937 rand(std::random_device{}()); + std::uniform_real_distribution velDis(-50.f, 50.f); + Nz::UInt8* particleBasePtr = particleBufferInitialData.data() + particlesOffset; Nz::SparsePtr particlePosPtr(particleBasePtr + particlePosOffset, particleSize); Nz::SparsePtr particleTargetPosPtr(particleBasePtr + particleTargetPosOffset, particleSize); @@ -127,8 +125,8 @@ int main() { auto&& [pos, color] = logoParticles[i]; - particlePosPtr[i] = Nz::Vector2f(posXDis(rand), posYDis(rand)); particleTargetPosPtr[i] = posScale * Nz::Vector2f(pos) + posOffset; + particlePosPtr[i] = particleTargetPosPtr[i]; particleColorPtr[i] = Nz::Vector3f(color.r, color.g, color.b) * color.a; particleVelPtr[i] = Nz::Vector2f(velDis(rand), velDis(rand)); } @@ -228,6 +226,18 @@ int main() Nz::HighPrecisionClock updateClock; unsigned int fps = 0; + // Smooth mouse position over time + Nz::Vector2f previousMousePos; + Nz::Vector2f newMousePos; + { + Nz::Vector2i mousePos = Nz::Mouse::GetPosition(window); + previousMousePos = Nz::Vector2f(mousePos.x, windowSize.y - mousePos.y); + newMousePos = previousMousePos; + } + + Nz::Time mouseSampleTimer = Nz::Time::Zero(); + constexpr Nz::Time mouseSampleRate = Nz::Time::TickDuration(60); + while (window.IsOpen()) { window.ProcessEvents(); @@ -254,19 +264,31 @@ int main() } } - float deltaTime = updateClock.Restart().AsSeconds(); + Nz::Time deltaTime = updateClock.Restart(); Nz::UploadPool& uploadPool = frame.GetUploadPool(); + mouseSampleTimer += deltaTime; + if (mouseSampleTimer >= mouseSampleRate) + { + mouseSampleTimer %= mouseSampleRate; + + previousMousePos = newMousePos; + Nz::Vector2i mousePos = Nz::Mouse::GetPosition(window); + newMousePos = Nz::Vector2f(mousePos.x, windowSize.y - mousePos.y); + } + frame.Execute([&](Nz::CommandBufferBuilder& builder) { builder.BeginDebugRegion("Upload scene data", Nz::Color::Yellow()); { - Nz::Vector2i mousePos = Nz::Mouse::GetPosition(window); + // Smooth mouse position over time (as this demo runs at a higher framerate than mouse polling) + float mouseInterp = mouseSampleTimer.AsSeconds() / mouseSampleRate.AsSeconds(); + Nz::Vector2f mousePos = Nz::Vector2f::Lerp(previousMousePos, newMousePos, mouseInterp); auto& allocation = uploadPool.Allocate(sceneBufferSize); - Nz::AccessByOffset(allocation.mappedPtr, deltaTimeOffset) = deltaTime; - Nz::AccessByOffset(allocation.mappedPtr, mousePosOffset) = Nz::Vector2f(mousePos.x, windowSize.y - mousePos.y); + Nz::AccessByOffset(allocation.mappedPtr, deltaTimeOffset) = deltaTime.AsSeconds(); + Nz::AccessByOffset(allocation.mappedPtr, mousePosOffset) = mousePos; Nz::AccessByOffset(allocation.mappedPtr, effectRadiusOffset) = (Nz::Mouse::IsButtonPressed(Nz::Mouse::Button::Left)) ? 10000.f : 100.f; builder.PreTransferBarrier();