ComputeParticlesTest: Improve demo

This commit is contained in:
SirLynix 2023-07-23 11:11:53 +02:00
parent e42b2c87fc
commit cb485cb20b
2 changed files with 38 additions and 16 deletions

View File

@ -47,11 +47,11 @@ fn main(input: Input)
// Gets pushed by the cursor // Gets pushed by the cursor
let attract_pos = sceneData.mousePos; let attract_pos = sceneData.mousePos;
let dist = length(attract_pos - data.particles[index].position); 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 // But want to return to their original position
let dist = length(data.particles[index].targetPosition - data.particles[index].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)); 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 // Lose speed with time

View File

@ -35,7 +35,7 @@ std::shared_ptr<Nz::Texture> GenerateSpriteTexture(Nz::RenderDevice& device, std
int main() int main()
{ {
Nz::Vector2ui windowSize = { 1280, 720 }; Nz::Vector2ui windowSize = { 1920, 1080 };
std::filesystem::path resourceDir = "assets/examples"; std::filesystem::path resourceDir = "assets/examples";
if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir)) if (!std::filesystem::is_directory(resourceDir) && std::filesystem::is_directory("../.." / resourceDir))
@ -99,18 +99,13 @@ int main()
std::vector<Nz::UInt8> particleBufferInitialData(bufferSize); std::vector<Nz::UInt8> particleBufferInitialData(bufferSize);
Nz::AccessByOffset<Nz::UInt32&>(particleBufferInitialData.data(), particleCountOffset) = particleCount; Nz::AccessByOffset<Nz::UInt32&>(particleBufferInitialData.data(), particleCountOffset) = particleCount;
std::mt19937 rand(std::random_device{}());
std::uniform_real_distribution<float> colorDis(0.f, 1.f);
std::uniform_real_distribution<float> posXDis(-float(windowSize.x), windowSize.x * 2.f);
std::uniform_real_distribution<float> posYDis(-float(windowSize.y), windowSize.y * 2.f);
std::uniform_real_distribution<float> velDis(-50.f, 50.f);
Nz::Vector2f logoImageSize(Nz::Vector2ui(logo->GetSize())); 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 // Center the logo in the canvas
Nz::Vector2f posScale = logoSize / logoImageSize; Nz::Vector2f posScale = logoSize / logoImageSize;
Nz::Vector2f posOffset = (Nz::Vector2f(windowSize) - logoSize) * 0.5f; Nz::Vector2f posOffset = (Nz::Vector2f(windowSize) - logoSize) * 0.5f;
// from image space to world space (topleft Y down to bottomleft Y up) // from image space to world space (topleft Y down to bottomleft Y up)
@ -118,6 +113,9 @@ int main()
posOffset.y += logoSize.y; posOffset.y += logoSize.y;
// Build particles // Build particles
std::mt19937 rand(std::random_device{}());
std::uniform_real_distribution<float> velDis(-50.f, 50.f);
Nz::UInt8* particleBasePtr = particleBufferInitialData.data() + particlesOffset; Nz::UInt8* particleBasePtr = particleBufferInitialData.data() + particlesOffset;
Nz::SparsePtr<Nz::Vector2f> particlePosPtr(particleBasePtr + particlePosOffset, particleSize); Nz::SparsePtr<Nz::Vector2f> particlePosPtr(particleBasePtr + particlePosOffset, particleSize);
Nz::SparsePtr<Nz::Vector2f> particleTargetPosPtr(particleBasePtr + particleTargetPosOffset, particleSize); Nz::SparsePtr<Nz::Vector2f> particleTargetPosPtr(particleBasePtr + particleTargetPosOffset, particleSize);
@ -127,8 +125,8 @@ int main()
{ {
auto&& [pos, color] = logoParticles[i]; auto&& [pos, color] = logoParticles[i];
particlePosPtr[i] = Nz::Vector2f(posXDis(rand), posYDis(rand));
particleTargetPosPtr[i] = posScale * Nz::Vector2f(pos) + posOffset; particleTargetPosPtr[i] = posScale * Nz::Vector2f(pos) + posOffset;
particlePosPtr[i] = particleTargetPosPtr[i];
particleColorPtr[i] = Nz::Vector3f(color.r, color.g, color.b) * color.a; particleColorPtr[i] = Nz::Vector3f(color.r, color.g, color.b) * color.a;
particleVelPtr[i] = Nz::Vector2f(velDis(rand), velDis(rand)); particleVelPtr[i] = Nz::Vector2f(velDis(rand), velDis(rand));
} }
@ -228,6 +226,18 @@ int main()
Nz::HighPrecisionClock updateClock; Nz::HighPrecisionClock updateClock;
unsigned int fps = 0; 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()) while (window.IsOpen())
{ {
window.ProcessEvents(); window.ProcessEvents();
@ -254,19 +264,31 @@ int main()
} }
} }
float deltaTime = updateClock.Restart().AsSeconds(); Nz::Time deltaTime = updateClock.Restart();
Nz::UploadPool& uploadPool = frame.GetUploadPool(); 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) frame.Execute([&](Nz::CommandBufferBuilder& builder)
{ {
builder.BeginDebugRegion("Upload scene data", Nz::Color::Yellow()); 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); auto& allocation = uploadPool.Allocate(sceneBufferSize);
Nz::AccessByOffset<float&>(allocation.mappedPtr, deltaTimeOffset) = deltaTime; Nz::AccessByOffset<float&>(allocation.mappedPtr, deltaTimeOffset) = deltaTime.AsSeconds();
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, mousePosOffset) = Nz::Vector2f(mousePos.x, windowSize.y - mousePos.y); Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, mousePosOffset) = mousePos;
Nz::AccessByOffset<float&>(allocation.mappedPtr, effectRadiusOffset) = (Nz::Mouse::IsButtonPressed(Nz::Mouse::Button::Left)) ? 10000.f : 100.f; Nz::AccessByOffset<float&>(allocation.mappedPtr, effectRadiusOffset) = (Nz::Mouse::IsButtonPressed(Nz::Mouse::Button::Left)) ? 10000.f : 100.f;
builder.PreTransferBarrier(); builder.PreTransferBarrier();