From 7f4042db031abe544b5020786e16bbe257370f14 Mon Sep 17 00:00:00 2001 From: Terry Sun Date: Mon, 19 Oct 2015 23:14:48 -0400 Subject: [PATCH] README + performance. --- README.md | 162 +++++++++++++++++++++++++++++++------ img/perf_raymarch_type.png | Bin 0 -> 13917 bytes img/perf_scaled_times.png | Bin 0 -> 15714 bytes img/perf_scene.png | Bin 0 -> 13680 bytes 4 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 img/perf_raymarch_type.png create mode 100644 img/perf_scaled_times.png create mode 100644 img/perf_scene.png diff --git a/README.md b/README.md index 9b8d7b3..0d3c0fd 100644 --- a/README.md +++ b/README.md @@ -6,48 +6,123 @@ Terry Sun; Google Chrome 45.0, Arch Linux, Intel i5-4670, GTX 750 -### Live on Shadertoy +A ray-marching shader implemented as a fragment shader. For each pixel, a ray is +shot from the camera into the scene. Rather than computing geometry +_intersections_ (as would be typical in a raytracer), this "marches" along the +ray and, at each point, computes the distances away from objects defined in the +scene. Objects are defined implicitly with signed data functions. -[![](img/thumb.png)](https://www.shadertoy.com/view/XISSRc) +### [Live on Shadertoy!][shadertoy] + +The Shadertoy demo includes a large set of debug flags, where you can turn on: + +* `SCENE1/SCENE2`: SCENE2 contains the image below; SCENE1 contains the geometry demo +* `PLANE/HEIGHTMAP`: enable or disable the (distance function-defined) plane below + the scene or the height-mapped terrain (the two options toggled independently) +* `FIXEDCAM`: the camera rotates around the scene if 0 +* `OVERRELAX/SPEHRETRACE/NAIVE`: for different raymarching types +* `DISTANCE/NORMAL/ITERS`: for different debug displays + +[![](img/thumb.png)][shadertoy] + + [shadertoy]: https://www.shadertoy.com/view/XISSRc ### Acknowledgements -This Shadertoy uses *code* from the following resources: +This Shadertoy project uses *code* from the following resources: * Morgan McGuire's *Numerical Methods for Ray Tracing Implicitly Defined Surfaces*. - [PDF](http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf) -* Iñigo Quílez's [Modeling with distance functions] - (http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm) -- - [Shadertoy] (https://www.shadertoy.com/view/Xds3zN) -* Iñigo Quílez's [Terrain Raymarching] - (http://www.iquilezles.org/www/articles/terrainmarching/terrainmarching.htm) + [PDF][mcguire] +* Iñigo Quílez's [Modeling with distance functions][iq-sdf]: [Shadertoy][iq-sdf-st] +* Iñigo Quílez's [Terrain Raymarching][iq-terrain] +* Iñigo Quílez's [Free Penumbra Shadows for Raymarching Distance Fields][iq-shadows] + (Soft shadows) +* Iñigo Quílez's [Menger fractal][menger] + + [mcguire]: http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf + [iq-sdf]: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm + [iq-sdf-st]: https://www.shadertoy.com/view/Xds3zN + [iq-terrain]: http://www.iquilezles.org/www/articles/terrainmarching/terrainmarching.htm + [iq-shadows]: http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm + [iq-menger]: http://www.iquilezles.org/www/articles/menger/menger.htm + +And uses the following as resources only: + * "Enhanced Sphere Tracing." Keinert, Schafer, Korndorf, Ganse, Stamminger. - [PDF](http://erleuchtet.org/~cupe/permanent/enhanced_sphere_tracing.pdf) + [PDF][keinert] + + [keinert]: http://erleuchtet.org/~cupe/permanent/enhanced_sphere_tracing.pdf ### Features -#### Geometries +#### Technique + +1. From the camera, shoot a ray into the scene. Then... + + 1. Naive raymarch: for every *fixed-size* step along a ray, compute the + distance away from all objects in the scene. An object is considered + intersected if it is below some small threshold. + + 2. Sphere tracing raymarch: at any given point along a ray, you have computed the + minimum distance *d* from objects in the scene in order to check for + intersections. Thus, if *d* doesn't indicate an intersection, it is safe to + take a step of length *d* along the ray. + +3. Terrain: If you have traveled some capped maximum distance away from the + camera, consider the ray as not intersecting the scene. However, there is + terrain! Continue the same raymarch, but compute terrain height rather than + object distances. This must be a naive raymarch. -Rererence: iq "Raymarching Primitives", McQuire "Implicitly Defined Surfaces" +4. Shadows: Once the ray has intersected an object or terrain, initiate (yet + another) raymarch from the point of intersection to the light. This will + determine the shadowing factor at that point. + +5. Lighting: Put the above together (intersection point, shadow factor) with a + simple normal calculation for simple Lambert lighting. + +#### Objects + +Rererence: +McGuire ["Implicitly Defined Surfaces"][mcguire], +iq ["Modeling with distance functions"][iq-sdf], +iq ["Menger fractal"][iq-menger] ![](img/geometries.png) +Geometries are defined implicitly with signed distance functions, mostly taken +verbatim out of iq's references. Objects are composed with union and +intersection functions. + #### Soft Shadows -Reference: iq "Modeling with distance functions" +Reference: iq ["Modeling with distance functions"][iq-sdf], iq ["Free Penumbra Shadows for Raymarching Distance Fields"][iq-shadows] ![](img/debug_softshadow_noise.png) +Compute a second raymarch from the intersection point to the light. Take the +minimum over all points along the raymarch of the intersection distance against +all objects in the scene. This yields soft shadows: even without a direct +intersection, things that come _close_ to intersection result in shadows. + #### Height Mapped Terrain -Reference: iq "Terrain Raymarching" +Reference: iq ["Terrain Raymarching"][iq-terrain] ![](img/height.png) +If a ray does not collide with any scene geometry after a max distance from the +camera, instead compute an intersection with a terrain function. The terrain +is defined with a function that takes an (x, z) pair and computes the height at +that location. + +For this raymarch we must use a naive method (with fixed step size), since the +function does not compute a distance from a point on the ray to the terrain (it +only defines the terrain height at a given point). + #### Sphere Overrelaxation -Reference: McQuire "Implicitly Defined Surfaces", Keinert "Enhanced Sphere Tracing" +Reference: McQuire ["Implicitly Defined Surfaces"][mcguire], Keinert ["Enhanced Sphere Tracing"][keinert] The number of ray march iterations displayed as grayscale, with darker areas indicating fewer iterations before the surface is considered intersected. @@ -56,22 +131,61 @@ indicating fewer iterations before the surface is considered intersected. ![](img/iters_overrelax.png) -### Debug images +(This method is not currently working.) -Positions +### Performance -![](img/debug_distance.png) +Render times for different scenes grouped by raymarch type: -Normals +![](img/perf_raymarch_type.png) -![](img/debug_normals.png) +Easy to see why naive raymarching is not done. -### Bloopers +And the transpose, with only sphere tracing times: -Overrelaxation without stepping backwards: +![](img/perf_scene.png) -![](img/bloop_overrelax_gloopy.png) +Main takeaways: + +* Scenes where most of the rays intersect (early) are fast. + +* Terrain is very slow, because all rays which hit terrain did not + intersect and had to complete a full raymarch, and _additionally_ had to go + through a second _naive_ raymarch. + +* Shadows have a small effect. The shadow timing is really the difference + between the all-scene and terrain-only scene. Reasonable: shadows should + involve a (relatively short) raymarch capped at distance from intersection to + light. + +* stats.js wasn't great for finding timing data: all of the shadow-only timings + are actually bound by the 60fps cap. + +* There sphere scene was similar to the close scene in composition, but had only + one object rather than many. The difference in time between those two are + likely due ot repeated distance function computations. + +Since there's no use in directly comparing sphere-traced and naive times, this +is a graph that scales render times by the full version of that raymarch type: + +![](img/perf_scaled.png) + +### Bonus images -Naive ray marching with a step size of 0.1 (too small), got wireframes: +Raw position data, with the sphere at (0, 0, 0) and a plane underneath. + +![](img/debug_distance.png) + +Normals for each geometry, computed with the equation given in McGuire (8). + +![](img/debug_normals.png) + +Naive ray marching with a step size of 0.1 (too large), got wireframes instead +of solid shapes: ![](img/bloop_wireframe.png) + +Overrelaxation without backwards step, resulting in stepping into the middle of +the geometries (and gloopiness): + +![](img/bloop_overrelax_gloopy.png) diff --git a/img/perf_raymarch_type.png b/img/perf_raymarch_type.png new file mode 100644 index 0000000000000000000000000000000000000000..47090831b76daef111f813d39fe1108bc3729b88 GIT binary patch literal 13917 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 A`v3p{ literal 0 HcmV?d00001 diff --git a/img/perf_scaled_times.png b/img/perf_scaled_times.png new file mode 100644 index 0000000000000000000000000000000000000000..990e4a103cc713d91239e039106c46a9c0d0f1ff GIT binary patch literal 15714 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 Qj@(T}LG4_oyfNl~0rvCm?EnA( literal 0 HcmV?d00001 diff --git a/img/perf_scene.png b/img/perf_scene.png new file mode 100644 index 0000000000000000000000000000000000000000..519ef112d2e8cdb15c84e3afcd59e1b9ddf0dbca GIT binary patch literal 13680 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¥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 literal 0 HcmV?d00001