wgpu/examples/README.md
JustAnotherCodemonkey f738551250
Add Extended Examples (#3885)
* Add the base of the example. May need refining and definitely fact-checking.

* Start change to changelog.

* Complete changelog change for repeated-compute.

* Apply suggestion to fix typos.

Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com>

* Add storage-texture example which currently works native but needs to be changed to work for wasm. [no ci]

* repeated-compute now works on the web. [no ci]

* `storage-texture` now works on the web as well as native.

* Format because I forgot to do that (ugh).

* Add `storage-texture` to changelog.

* Add `render-to-texture` example.

* Not all the files got git added. Fixed it.

* Add `render-to-texture` to changelog.

* Make better readme's and add examples to said readme's.

* Oops. Put the example updates in the wrong place.

* Add `uniform-values` example.

* Apply clippy suggestions.

* Improved readme's and documentation.

* Fmt. Turning into the Joker rn.

* Make instructions for examples on the web more clear. \(Fmt and clippy happy\)

* hello-workgroups It doesn't work.

* Add basic comments and readme to hello-workgroups.

* Add hello-synchronization example. Currently doesn't have any tests but those should be added later.

* Forgot to check wasm compatibility for hello-synchronization. Fixed it.

* Add test for hello-synchronization.

* Make my examples downlevel defaults.

* Make uniform-values downlevel defaults. (Forgot to do that last commit.)

* Fix clippy doc complaints.

* Didn't fully fix the docs last commit. Got it here I think.

* Fix redundant bullet point in examples/hello-workgroups/README.md.

* Trim down the introduction section of examples/hello-workgroups/README.md.

* Add technical links section to examples/hello-workgroups/README.md.

* Use idiomatic Rust comments, break up big text wall into paragraphs, and fix some spelling errors.

* Move output image functions into examples/common and give output_image_wasm some upgrades.

* Modify changelog for moving output_image_native and output_image_wasm into wgpu-example.

* Fix output_image_wasm. (Formerly did not handle pre-existing output image targets.)

* Make a multiline comment be made of single lines to be more ideomatic.

* "Fix" more multiline comments. I think this is actually the last of them.

* Make the window a consistant, square size that's convenient for viewing.

* Make the window on uniform-values not endlessly poll, taking up 100% of the main thread in background at idle. Also, change layout a little and make native use nanos by default for logging.

* Make execute in hello-synchronization return a struct of vecs instead of using out parameters.

* Didn't realize the naming of wgpu_example::framework so I moved my common example utility functions into wgpu_example::utils.

* Add add_web_nothing_to_see_msg function to replace all the instances of adding "open the console" messages across the examples.

* Add small documentation to add_web_nothing_to_see_msg and change it to use h1 instead of p.

* Add documentation to output_image_native and output_image_wasm in examples/common.

* Do better logging for output image functions in wgpu-example::utils.

* Remove redundant append_child'ing of the output image element in wgpu-example::utils::output_image_wasm.

* Fix error regarding log message for having written the image in wgpu-example::utils::output_image_native.

* Fmt.

* In examples/README.md, re-arrange the examples in the graph to be in alphabetical order.

* Fix changlog item regarding wgpu-example::utils and the output image functions.

* Move all the added examples into one changelog item that lists all of them.

* Updated table in examples/README.md with new examples. Added new features to the table to accurately represent the examples.\n\nFor the new features, not all old examples may be fully represented.

* Fix inaccurate comment in hello-workgroups/src/shader.wgsl.

* Update examples/README.md to include basic descriptions of the basic examples as well as hints on how examples build off of each other.

* Remove `capture` example. See changelog entry for reasoning.

* Fix typo in hello-workgroups/shader.wgsl

* Change the method of vertex generation in the shader code of render-to-texture to make it more clear.

* Modify/correct message in repeated-compute/main.rs regarding the output staging buffer.

* Update message in uniform-values/main.rs about writing the app state struct to the input WGSL buffer.

* Add notice in repeated-compute/main.rs about why async channels are necessary (portability to WASM).

* Revise comment in uniform-values/main.rs about why we don't cast the struct using POD to be more clear.

* Change uniform-values to use encase for translating AppState to WGSL bytes.

* Cargo & Clippy: My two best friends.

* Add MIT-0 to the list of allowed liscences.

* Fix docs for wasm.

---------

Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com>
2023-10-08 02:05:51 -04:00

17 KiB

Structure

For the simplest examples without using any helping code (see framework.rs here), check out:

  • hello for printing adapter information
  • hello-triangle for graphics and presentation
  • hello-compute for pure computing

Summary of examples

A summary of the basic examples as split along the graphics and compute "pathways", layed out roughly in order of building on each other. Those further indented and thus more roughly dependant on more other examples tend to be more complicated as well as those further down. It should be noted though that computing examples, even though they are mentioned further down (because rendering to a window is by far the most common use case), tend to be less complex as they require less surrounding context to create and manage a window to render to.

The rest of the example are for demonstrating specific features that you can come back for later when you know what those features are.

General

  • hello - Demonstrates the basics of the WGPU library by getting a default Adapter and debugging it to the screen

Graphics

  • hello-triangle - Provides an example of a bare-bones WGPU workflow using the Winit crate that simply renders a red triangle on a green background.
    • uniform-values - Demonstrates the basics of enabling shaders and the GPU in general to access app state through uniform variables. uniform-values also serves as an example of rudimentary app building as the app stores state and takes window-captured keyboard events. The app displays the Mandelbrot Set in grayscale (similar to storage-texture) but allows the user to navigate and explore it using their arrow keys and scroll wheel.
      • cube - Introduces the user to slightly more advanced models. The example creates a set of triangles to form a cube on the CPU and then uses a vertex and index buffer to send the generated model to the GPU for usage in rendering. It also uses a texture generated on the CPU to shade the sides of the cube and a uniform variable to apply a transformation matrix to the cube in the shader.
      • bunnymark - Demonstrates many things but chief among them, preforming numerous draw calls with different bind groups in one render pass. The example also uses textures for the icon and uniform buffers to transfer both global and per-particle state.
      • skybox - Shows off too many concepts to list here. The name comes from game development where a "skybox" acts as a background for rendering, usually to add a sky texture for immersion although they can also be used for backdrops to give the idea of a world beyond of the game scene. This example does so much more than this though as it uses a car model loaded from a file and uses the user's mouse to rotate the car model in 3d. skybox also makes use of depth textures and similar app patterns to uniform-values.
        • shadow - Likely by far the most complex example (certainly the largest in lines of code) of the official WGPU examples. shadow demonstrates basic scene rendering with the main attraction being lighting and shadows (as the name implies). It is recommended that any user looking into lighting be very familiar with the basic concepts of not only rendering with WGPU but the primary mathematical ideas of computer graphics.
  • render-to-texture - Renders to an image texture offscreen, demonstrating both off-screen rendering as well as how to add a sort of resolution-agnostic screenshot feature to an engine. This example either outputs an image file of your naming (pass command line arguments after specifying a -- like cargo run --bin render-to-texture -- "test.png") or adds an img element containing the image to the page in WASM.

Compute

  • hello-compute - Demonstrates the basic workflow for getting arrays of numbers to the GPU, executing a shader on them, and getting the results back. The operation it preforms is finding the Collatz value (how many iterations of the Collatz equation it takes for the number to either reach 1 or overflow) of a set of numbers and prints the results.
    • repeated-compute - Mostly for going into detail on subjects hello-compute did not. It, too, computes the Collatz conjecture but this time, it automatically loads large arrays of randomly generated numbers, prints them, runs them, and prints the result. It does this cycle 10 times.
      • hello-workgroups - Teaches the user about the basics of compute workgroups; what they are and what they can do.
        • hello-synchronization - Teaches the user about synchronization in WGSL, the ability to force all invocations in a workgroup to synchronize with each other before continuing via a sort of barrier.
      • storage-texture - Demonstrates the use of storage textures as outputs to compute shaders. The example on the outside seems very similar to render-to-texture in that it outputs an image either to the file system or the web page except displaying a grayscale render of the Mandelbrot Set. However, inside, the example dispatches a grid of compute workgroups, one for each pixel which calculates the pixel value and stores it to the corresponding pixel of the output storage texture.

Combined

  • boids - Demonstrates how to combine compute and render workflows by preforming a boid simulation and rendering the boids to the screen as little triangles.

Feature matrix

Feature boids bunnymark conservative-raster cube hello-synchronization hello-workgroups mipmap msaa-line render-to-texture repeated-compute shadow skybox stencil-triangles storage-texture texture-arrays uniform-values water
vertex attributes
instancing
lines and points
dynamic buffer offsets
implicit layout
sampled color textures
storage textures
comparison samplers
subresource views
cubemaps
multisampling
off-screen rendering
stencil testing
depth testing
depth biasing
read-only depth
blending
render bundles
uniform buffers
compute passes
buffer mapping
error scopes
compute workgroups
compute synchronization
optional extensions
- SPIR-V shaders
- binding array
- push constants
- depth clamping
- compressed textures
- polygon mode
- queries
- conservative rasterization
integrations
- staging belt
- typed arena
- obj loading

Additional notes

Note that the examples regarding computing build off of each other; repeated-compute extends hello-compute, hello-workgroups assumes you know the basic workflow of gpu computation, and hello-synchronization assumes you know what a workgroup is. Also note that the computing examples cannot be downleveled to WebGL as WebGL does not allow storage textures. Running these in a browser will require that browser to support WebGPU.

All the examples use WGSL shaders unless specified otherwise.

All framework-based examples render to the window and are reftested against the screenshot in the directory.

Hacking

You can record an API trace any of the framework-based examples by starting them as:

mkdir -p trace && WGPU_TRACE=trace cargo run --features trace --bin <example-name>