From 5fb3689a3c83143f5f02e975f7d6706bcd7991e4 Mon Sep 17 00:00:00 2001 From: "Spencer C. Imbleau" Date: Thu, 4 Jan 2024 00:34:43 -0500 Subject: [PATCH] fix: wasm demo --- _includes/iframe.html | 2 ++ _includes/youtubePlayer.html | 2 +- .../2023-11-20-using-vello-for-video-games.md | 26 ++++++++++++++----- assets/Tessellation.svg | 25 +++++++++++------- 4 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 _includes/iframe.html diff --git a/_includes/iframe.html b/_includes/iframe.html new file mode 100644 index 0000000..fcdc0fd --- /dev/null +++ b/_includes/iframe.html @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/_includes/youtubePlayer.html b/_includes/youtubePlayer.html index 6ef25ba..c0b5c23 100644 --- a/_includes/youtubePlayer.html +++ b/_includes/youtubePlayer.html @@ -1,2 +1,2 @@ - \ No newline at end of file diff --git a/_posts/2023-11-20-using-vello-for-video-games.md b/_posts/2023-11-20-using-vello-for-video-games.md index 04b2919..2ba0bca 100644 --- a/_posts/2023-11-20-using-vello-for-video-games.md +++ b/_posts/2023-11-20-using-vello-for-video-games.md @@ -5,6 +5,7 @@ description: "A look at the first compute-centric vector graphic 2d video game a date: 2023-11-20 categories: rust graphics youtubeId: hNu5oF18j5g +vongDemo: https://simbleau.github.io/vong/ --- Vector images are notoriously unfit for modern GPU architecture because of an inherent locality issue. In contrast to raster graphics where color and fill information is explicitly encoded, rendering a pixel in a vector image requires knowledge of the entire image. Solving the fill of every pixel efficiently is a unique challenge, and *hard*. With the rising accessibility of compute kernels and low-level GPU architecture access over the past few years, especially from projects like [wgpu](https://wgpu.rs/), friction with general purpose GPU computing is fading. Projects like [vello](https://github.com/linebender/vello) are pioneering the 2d vector graphics space, and furthering the experimental research inspired by projects like [pathfinder](https://github.com/servo/pathfinder). @@ -19,8 +20,6 @@ There are many compelling reasons I have gravitated towards the imaging model: p Why is there no *κ*urvature in modern games? Needing to satisfy the understanding of why I've never seen a [Kurzgesagt-styled](https://www.behance.net/kurzgesagt) vector game led to creating one. So the decision to start by creating the classic game of Pong was deliberate, providing a foundational exploration of Vello's capabilities in rendering vector graphics dynamically. It felt appropriate to call the project *Vong*, joining "Vector" and "Pong". -![Vong Closeup](/assets/vong-closeup.png) - ### Rendering When starting the proof of concept, [bevy](https://bevyengine.org/) was an obvious solution for an open-source game engine. It is both code-first and Rust, a win-win. However, standing in the way of seeing my first [Ghostscript Tiger](https://commons.wikimedia.org/wiki/File:Ghostscript_tiger_(original_background).svg) was an integration to render vector assets in bevy with vello. @@ -56,20 +55,33 @@ Strategically, it made sense to pursue both formats, but a painful lesson learne Once rendering was solved, another thorny issue with pong is physics: collision detection between arbitrarily curved shapes is *hard*. While algorithms exist, none today are *obviously* good. -Eventually I settled on tessellation as a decent proxy for physics. The technique is quite simple in concept: Flatten curves into line segments, generate a triangle mesh, and keep only a convex hull of the shape as a hitbox. +Eventually I settled on tessellation as a decent proxy for physics. The technique is quite simple in concept: Flatten curves into line segments, generate a triangle mesh, and keep only a convex hull of the shape as a hitbox. Below is a figure of that algorithm. + ![Tessellation](/assets/Tessellation.svg) -This is obviously not true collision detection between arbitrary curves with infinitessimal precision, but was rather a compromise given a lack of algorithmically efficient alternatives. +This is obviously not true collision detection between arbitrary curves with infinitessimal precision, but was rather a compromise given a lack of algorithmically efficient collision detection between curves. + +As with most things in game development, this is a hack, but a good one! Even when using a liberal tolerance for curve flattening, physics yield a high level of collision fidelity, nearly indistinguishable from the true underlying curves. Granted, this only works great since my egg is convex by nature. + +![Vong Closeup](/assets/vong-closeup.png) A less important, but fun quirk of vong is that the "pong ball" (egg) exhibits linear velocity and angular momentum provided by [`bevy_rapier`](https://rapier.rs/). ### Demo -You may find the source code [here](https://github.com/simbleau/vong). +**Is the frame immediately below solid black?** Vong uses compute shaders. Make sure your browser is updated to [Chrome M113](https://chromestatus.com/feature/6213121689518080) or another browser compatible with [WebGPU](https://caniuse.com/?search=webgpu)! + +{% include iframe.html src=page.vongDemo %} + +Controls: -Right now I'm working on a porting the demo to web, so in a few days this gif should be replaced with the web demo. You can still build and play it natively from source with `cargo run`. +- `Up`/`Down` (Arrow keys): Scale camera +- `PgUp`/`PgDown`/`Home`/`End`: Free camera +- `W`/`S`: Left bacon +- `I`/`J`: Right bacon +- `C`: Watch egg intensely -![Vong](https://user-images.githubusercontent.com/48108917/220213333-9490b8f5-56f7-42e2-a26e-b73bd387e24e.gif) +You may find the source code [here](https://github.com/simbleau/vong). You may also build and play this natively with `cargo run`. ## What now? diff --git a/assets/Tessellation.svg b/assets/Tessellation.svg index a3fa490..fa1114d 100644 --- a/assets/Tessellation.svg +++ b/assets/Tessellation.svg @@ -26,17 +26,17 @@ guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" - inkscape:window-width="2048" - inkscape:window-height="1152" + inkscape:window-width="1841" + inkscape:window-height="1009" id="namedview232" showgrid="false" - inkscape:zoom="0.86542007" - inkscape:cx="493.40201" - inkscape:cy="181.41479" - inkscape:window-x="0" - inkscape:window-y="0" + inkscape:zoom="0.91743056" + inkscape:cx="285.0352" + inkscape:cy="111.72508" + inkscape:window-x="207" + inkscape:window-y="25" inkscape:window-maximized="0" - inkscape:current-layer="g343" + inkscape:current-layer="g180-3" inkscape:showpageshadow="2" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" /> @@ -212,8 +212,13 @@ id="path178-8" d="m 333.2,965.3 -15.1,-48.7 13,-34.4 -11.5,-54.2 26.7,-37.1 73.2,-19.2 114.4,30.4 -17,38 1.2,15.3 13.2,-8 14.8,6.8 -5.2,48.2 -16.8,4.8 -11.4,43.5 -40.4,29.9 -31.3,-3 v 28.2 l 19,8.3 -44.2,19 -10.6,-25.1 9.9,-3.8 V 976 Z" transform="translate(-432.1,-902.4)" - style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ff5555;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - +