From dde27049a3aa71ab88be3074c40fd9300e470a09 Mon Sep 17 00:00:00 2001 From: TheNumbat Date: Mon, 12 Apr 2021 21:33:37 -0700 Subject: [PATCH] particle instructions --- docs/animation/particles.md | 38 +++++++++++++++++++++-- docs/animation/task4_media/collision.png | Bin 0 -> 21463 bytes docs/animation/task4_media/euler.png | Bin 0 -> 5819 bytes docs/animation/task4_media/fma.png | Bin 0 -> 4197 bytes docs/guide/simulate.md | 2 +- docs/pathtracer/materials.md | 2 +- 6 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 docs/animation/task4_media/collision.png create mode 100644 docs/animation/task4_media/euler.png create mode 100644 docs/animation/task4_media/fma.png diff --git a/docs/animation/particles.md b/docs/animation/particles.md index 22590bb..6840bf7 100644 --- a/docs/animation/particles.md +++ b/docs/animation/particles.md @@ -6,9 +6,41 @@ nav_order: 4 permalink: /animation/particles --- -# Particle Simulation +# Particle Systems -And now for something completely different: physics simulation for particles. +A particle system in Scotty3D is simply a collection of non-interacting, physics-simulated, spherical particles that interact with the rest of the scene. Take a look at the [user guide](../guide/simulate.md) for an overview of how to create and manage them. -## Ray traced physics +In this task, you will implement ``bool Particle::update(const PT::BVH& scene, float dt, float radius)`` found in `student/particles.cpp`. + +## Kinematics + +Each particle is described by a position and a velocity. If we want to know where the particle will be at some future time, we simply have to move it along its velocity vector. If the particle is travelling at constant velocity, this is a very easy expression to compute. + +However, if the particle can have arbitrary forces applied to it, we no longer know exactly how it will move. Since we're interested in physical simulation, we can apply the basic equation governing motion: F = ma. Since acceleration is the time derivative of velocity, we now have a differential equation governing how our particle moves. Unfortunately, it's no longer feasible (in general) to compute this motion analytically, so instead we will use numerical integration to step our particles forward in time. To get realistic behavior from approximate but easy to compute steps, we can simply take many small time steps until we reach the desired destination. + +
+ +There are many different techniques for integrating our equations of motion, including forward, backward, and symplectic Euler, Verlet, Runge-Kutta, and Leapfrog. Each strategy comes with a slightly different way of computing how much to update our velocity and position across a single time-step. In this task, we will use the simplest - forward Euler - as we aren't too concerned with stability or energy conservation for our particle system. Forward Euler simply steps our position forward by our velocity, and then velocity by our acceleration: + +
+ +In `Particle::update`, use this integrator to step the current particle forward for `dt` seconds. Note that the only force we will apply to our particles is gravity, so `acceleration` (a static member of `Particle`) is a constant `-9.8` meters per second squared pointing downward (feel free to play around with this!). Once you've added the update rule, you should already see some interesting behavior - create a particle system and see how the particles travel along nice parabolic trajectories. + +## Collisions + +The more substantial part of this task is colliding each particle with the rest of our scene geometry. Thankfully, you've already done most of the work required here during A3: we can use Scotty3D's ray-tracing capabilities to find collisions along our particles' paths. + +During each timestep, we know that in the absence of a collision, our particle will travel in the direction of velocity for distance `||velocity|| * dt`. We can create a ray representing this position and velocity and use its distance bound to restrict how far we travel this time-step. If the ray intersects with our scene, we know if and when the particle experiences a collision. Note that since we are representing particles as small spheres, you must take `radius` into account when looking for collisions. If the center of our particle can see collisions up to distance `||velocity|| * dt`, what distance can the closest point on the sphere collide up to? + +If our ray hit the scene, we can use its hit distance to figure out at what time our particle hit the surface. Again, be careful about the radius here. (Where was the center of the particle when the closest point started intersecting?) We could just place the particle at the collision point and be done, but we don't want our particles to simply stick the surface! Instead, we will assume all particles collide elastically (and massless-ly) - that is, the magnitude of their velocity should be the same before and after the collision, and its direction should be reflected about the normal of the collision surface. + +Finally, once we have a reflected velocity, we can compute how much of the time step remains after the collision, and step the particle forward that amount. However, what if the particle collided with the scene _again_ before the end of the time-step? If we are using very small time-steps, it might be OK to ignore this possibility, but we want to be able to resolve all collisions. So, we can repeat the ray-casting procedure in a loop until we have used up the entire time-step (up to some epsilon). Remember to only use the remaining portion of the time-step each iteration, and to step forward both the velocity and position at each sub-step. + +
+ +Once you have got collisions working, you should be able to open `particles.dae` and see a randomized collision-fueled waterfall. Try rendering the scene! + +## Lifetime + +Finally, note that `Particle::update` is supposed to return a boolean representing whether or not the particle should be removed from the simulation. Each particle has an `age` member that represents the remaining time it has to live. Each time-step, you should subtract `dt` from `age` and return whether `age` is still greater than zero. diff --git a/docs/animation/task4_media/collision.png b/docs/animation/task4_media/collision.png new file mode 100644 index 0000000000000000000000000000000000000000..3155dde2c43f95a8909037f171142373046a6a05 GIT binary patch literal 21463 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 literal 0 HcmV?d00001 diff --git a/docs/animation/task4_media/euler.png b/docs/animation/task4_media/euler.png new file mode 100644 index 0000000000000000000000000000000000000000..10d269d9f770b824b6ff84960dbba32f21f0b1b7 GIT binary patch literal 5819 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 literal 0 HcmV?d00001 diff --git a/docs/animation/task4_media/fma.png b/docs/animation/task4_media/fma.png new file mode 100644 index 0000000000000000000000000000000000000000..223fccfb11c373fe3c10369aebb406e3e7896d12 GIT binary patch literal 4197 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 To get started take a look at the BSDF interface in `rays/bsdf.h`. There are a number of key methods you should understand in `BSDF class`: -- GitLab