Practical GPU Graphics with wgpu and Rust
About this Book
wgpu is the next-generation graphics API and future standard in Rust for both native devices and the web, aiming to provide modern 3D graphics and computation capabilities using the GPU acceleration. This book provides all the tools you need to create advanced 3D graphics and GPU computing in Rust using this new wgpu API.
First, this book will take you through the development environment for building wgpu applications in Rust, and then introduce Rust and wgpu basics, shader programs, GPU buffers, and rendering pipelines. Next, you will learn how to create primitives and simple objects in wgpu. As you progress through the chapters, you will get to grips with advanced wgpu topics, including 3D transformations, lighting calculations, colormaps, and textures. At the same time, you will learn how to create advanced 3D wgpu objects, including various 3D wireframes, 3D shapes, and simple and parametric 3D surfaces with colormaps and textures, as well as beautiful 2D and 3D fractal images described by complex functions. In addition, you will explore new wgpu features such as the compute shader and storage buffers, and use them to simulate large particle systems.
By the end of this book, you will have the solid skills you need to build your own GPU-accelerated graphics and computing applications on both native devices and the web in Rust with the wgpu API.
The things you will learn from this book:
- Development environment and tools for creating wgpu apps in Rust.
 - Rust and wgpu basics, WGSL shaders, and rendering pipeline.
 - Primitives and simple shapes in wgpu.
 - 3D transformations, model, viewing, projection, and various coordinate systems.
 - GPU buffers, uniform buffer objects, animation, and camera controls.
 - Normal vectors, lighting model, ambient, diffuse, and specular light calculations.
 - UV coordinates, texture mapping.
 - Color model, colormaps, and color interpolation.
 - 3D shapes, wireframes, surfaces, and 3D charts.
 - 2D and 3D fractal images created in the fragment shader.
 - Compute shaders, storage buffers, and large particle system simulation.
 
Table of Contents
Contents	v
Introduction	1
Overview	1
What this Book Includes	3
Is this Book for You?	3
What Do You Need to Use this Book?	4
How this Book Is Organized	4
Using Code Examples	6
Customer Support	6
1	Setting Up Development Tools	7
1.1	Hardware Requirements	7
1.2	Install C++ Build Tools	10
1.3	Install Rust	10
1.4	Install Visual Studio Code	11
1.5	Run a Rust Application	11
1.6	Configuration	12
1.7	Creating a Window	15
1.8	Rust Basics	15
1.8.1	Data Types	17
1.8.2	Functions	17
1.8.3	Control Flows	18
1.8.4	Arrays, Vectors, and Slices	21
1.8.5	Structs	22
1.8.6	Enums	23
1.8.7	Generics	24
2	wgpu Basics	25
2.1	First wgpu Example	25
2.1.1	WGSL Shaders	25
2.1.2	Common Rust Code	26
2.1.3	Rust Main Function	28
2.2	wgpu API	30
2.2.1	wgpu Backend	30
2.2.2	Surface	31
2.2.3	Load Shaders	32
2.2.4	Rendering Pipeline	32
2.2.5	Rendering Output	34
2.3	Shader Program	35
2.3.1	Why Use WGSL Shaders?	36
2.3.2	Writing Shader Code	36
2.4	Triangle with Different Vertex Colors	38
2.4.1	Shader Code	39
2.4.2	Rust Code	39
3	wgpu Primitives	41
3.1	Creating Points	42
3.1.1	Rust Code	42
3.1.2	Shader Code	43
3.1.3	Run Application	44
3.2	Creating Lines	45
3.3	Creating Triangles	47
3.3.1	Rust Code	47
3.3.2	Shader Code	48
3.3.3	Run Application	49
4	GPU Buffers	51
4.1	GPU Buffer	51
4.2	Creating a Colored Triangle	52
4.2.1	Rust Code	53
4.2.2	Shader Code	60
4.2.3	Run Application	60
4.3	Creating a Colored Square	61
4.3.1	Rust Code	62
4.3.2	Run Application	62
4.4	Creating a Square with an Index Buffer	63
4.4.1	Rust Code	63
4.4.2	Run Application	65
5	3D Transformations	67
5.1	Basics of 3D Matrices and Transformations	67
5.1.1	Introducing cgmath	67
5.1.2	3D Vector and Matrix Operations	68
5.1.3	Scaling	69
5.1.4	Translation	71
5.1.5	Rotation	72
5.1.6	Combining Transformations	74
5.2	Projections and Viewing	75
5.2.1	Transforming Coordinates	75
5.2.2	Viewing Transform	76
5.2.3	Perspective Projection	79
5.2.4	Orthographic Projection	83
5.3	Transformations in wgpu	86
6	3D Shapes and Camera	87
6.1	Uniform Buffers and Bind Groups	87
6.2	Creating a 3D Line	89
6.2.1	Common Code	89
6.2.2	Rust Code	92
6.2.3	Shader Program	98
6.2.4	Run Application	98
6.3	Creating a Cube with Distinct Face Colors	100
6.3.1	Create Vertex Data	100
6.3.2	Rust Code	102
6.3.3	Shader Program	109
6.3.4	Run Application	110
6.4	Creating a Cube with Distinct Vertex Colors	111
6.4.1	Create Vertex Data	111
6.4.2	Rust Code	111
6.4.3	Run Application	118
6.5	Rotating Objects	119
6.5.1	Rust Code	119
6.5.2	Run Application	120
6.6	Camera Controls	121
6.6.1	Camera Code	121
6.6.2	Rust Code	123
6.6.3	Run Application	130
7	3D Wireframe Shapes	131
7.1	Common Code	131
7.2	Cube Wireframe	136
7.2.1	Rust File	136
7.2.2	Run Application	137
7.3	Sphere Wireframe	138
7.3.1	Spherical Coordinate System	138
7.3.2	Rust Code	140
7.3.3	Run Application	141
7.4	Cylinder Wireframe	141
7.4.1	Cylindrical Coordinate System	142
7.4.2	Rust Code	143
7.4.3	Run Application	145
7.5	Cone Wireframe	146
7.5.1	Rust Code	147
7.5.2	Run Application	148
7.6	Torus Wireframe	149
7.6.1	Rust Code	150
7.6.2	Run Application	151
8	Lighting in WGPU	153
8.1	Light Components	153
8.2	Normal Vectors	154
8.2.1	Surface Normal of a Cube	155
8.2.2	Surface Normal of a Sphere	155
8.2.3	Surface Normal of a Cylinder	155
8.2.4	Surface Normal of a Polyhedral Surface	155
8.3	Lighting Calculation	156
8.3.1	Diffuse Light	156
8.3.2	Specular Light	157
8.4	Lighting in Shaders	158
8.4.1	Transform Normals	158
8.4.2	Shader with Lighting	159
8.5	Common Code	161
8.6	Cube with Lighting	170
8.6.1	Rust Code	170
8.6.2	Run Application	171
8.7	Sphere with Lighting	171
8.7.1	Vertex and Normal Data	172
8.7.2	Rust Code	173
8.7.3	Run Application	174
8.8	Cylinder with Lighting	174
8.8.1	Vertex and Normal Data	175
8.8.2	Rust Code	177
8.8.3	Run Application	177
8.9	Cone with Lighting	178
8.9.1	Vertex and Normal Data	179
8.9.2	Rust Code	180
8.9.3	Run Application	181
8.10	Torus with Lighting	181
8.10.1	Vertex and Normal Data	182
8.10.2	Rust Code	183
8.10.3	Run Application	183
9	Colormaps and 3D Surfaces	185
9.1	Color Models	185
9.2	Colormaps	186
9.2.1	Colormap Data	186
9.2.2	Color Interpolation	187
9.3	Shaders with Lighting and Vertex Color	188
9.4	Simple 3D Surfaces	190
9.4.1	Position, Normal, and Color Data	191
9.4.2	Common Code	193
9.4.3	Sinc Surface	201
9.4.4	Peaks Surface	203
9.5	Parametric 3D Surfaces	205
9.5.1	Vertex and Normal Data	205
9.5.2	Klein Bottle	206
9.5.3	Wellenkugel Surface	209
9.5.4	Seashell Surface	210
9.5.5	Sievert-Enneper Surface	212
9.5.6	Breather Surface	213
10	Textures	217
10.1	Texture Coordinates	217
10.2	Texture Mapping in WGPU	218
10.3	Shaders with Texture	222
10.4	Common Code	223
10.5	Simple 3D Shapes	232
10.5.1	Cube with Texture	232
10.5.2	Sphere with Texture	235
10.5.3	Cylinder with Texture	237
10.6	Simple 3D Surfaces	241
10.6.1	Sinc Surface with Texture	243
10.6.2	Peaks Surface with Texture	245
10.7	Parametric 3D Surfaces	246
10.7.1	Klein Bottle with Texture	248
10.7.2	Wellenkugel Surface with Texture	250
10.8	Multiple Textures	252
10.8.1	Texture Coordinates	252
10.8.2	Rust Code	254
10.8.3	Run Application	254
11	3D Surface Charts	257
11.1	Wireframe as Texture	258
11.1.1	Square Textures	258
11.1.2	Texture Coordinates	259
11.2	Shaders for 3D Charts	259
11.3	Common Code	261
11.4	Simple 3D Surface Charts	269
11.4.1	Sinc Surface Chart	271
11.4.2	Peaks Surface Chart	274
11.5	Parametric 3D Surface Charts	275
11.5.1	Sphere Surface Chart	277
11.5.2	Torus Surface Chart	278
11.5.3	Klein Bottle Surface Chart	280
11.5.4	Wellenkugel Surface Chart	282
12	Creating Multiple Objects	285
12.1	Creating Two Cubes	285
12.1.1	Rust Code	285
12.1.2	Run Application	292
12.2	Creating Multiple Cubes with Instancing	292
12.2.1	Rust Code	293
12.2.2	Shader Code	300
12.2.3	Run Application	300
12.3	Creating Different Objects	301
12.3.1	Rust Code	301
12.3.2	Run Application	303
12.4	Creating Objects Using Multiple Pipelines	304
12.4.1	Rust Code	304
12.4.2	Run Application	315
12.5	Creating 3D Charts with Multiple Pipelines	315
12.5.1	Create Wireframe Data	316
12.5.2	Modify Shader Program	317
12.5.3	Rust Code	318
12.5.4	Run Application	327
12.6	Charts with Coordinate Axes	329
12.6.1	Shaders for Coordinate Axes	329
12.6.2	Rust Code	330
12.6.3	Run Application	333
12.7	Creating 3D Charts with Multiple Render Passes	334
12.7.1	Rust Code	334
12.7.2	Run Application	337
13	Compute Shaders and Particles	339
13.1	Compute Shader	339
13.1.1	Compute Space and Workgroups	340
13.1.2	Write and Read Buffer	341
13.2	2D Rotation in GPU	343
13.2.1	Rust Code	343
13.2.2	Shader Code	346
13.2.3	Run Application	347
13.3	Compute Boids	347
13.3.1	Rust Code	347
13.3.2	Shader Code	354
13.3.3	Run Application	356
13.4	Particles under Gravity	358
13.4.1	Rust Code	358
13.4.2	Shader Code	366
13.4.3	Run Application	368
13.5	Particle Collision	370
13.5.1	Rust Code	370
13.5.2	Shader Code	378
13.5.3	Run Application	380
14	Visualizing Complex Functions	383
14.1	Complex Functions in Shader	383
14.1.1	Math Operations	384
14.1.2	Commonly Used Functions	384
14.2	Color Functions	386
14.2.1	Color Conversion in Shader	387
14.2.2	Colormaps in Shader	388
14.3	Domain Coloring for Complex Functions	392
14.3.1	Rust Code	392
14.3.2	Shader Code	397
14.3.3	Complex function with id = 0	399
14.3.4	Complex Function with id = 1	400
14.3.5	Complex Function with id = 2	401
14.3.6	Complex Function with id = 3	402
14.3.7	Complex Function with id = 4	402
14.3.8	Complex Function with id = 5	403
14.3.9	Complex Function with id = 6	404
14.3.10	Complex Function with id = 7	404
14.3.11	Complex Function with id = 8	405
14.3.12	Complex Function with id = 9	406
14.3.13	Complex Function with id = 10	406
14.4	Domain Coloring for Iterated Functions	407
14.4.1	Shader Code	407
14.4.2	Iterated Function with id = 0	410
14.4.3	Iterated Function with id = 1	410
14.4.4	Iterated Function with id = 2	411
14.4.5	Iterated Function with id = 3	412
14.4.6	Iterated Function with id = 4	412
14.4.7	Iterated Function with id = 5	413
14.4.8	Iterated Function with id = 6	414
14.4.9	Iterated Function with id = 7	414
14.4.10	Iterated Function with id = 8	415
14.4.11	Iterated Function with id = 9	416
14.4.12	Iterated Function with id = 10	416
14.5	Fractal: Mandelbrot Set	417
14.5.1	Mandelbrot Set Formula	417
14.5.2	Rust Code	418
14.5.3	Shader Code	422
14.5.4	Run Application	424
14.6	Fractal: Julia Set	424
14.6.1	Rust Code	424
14.6.2	Shader Code	429
14.6.3	Run Application	431
14.7	3D Fractals	432
14.7.1	Common Code	432
14.7.2	Mandelbulb	437
14.7.3	Mandelbrot in 3D Space	441
14.7.4	Mandelbox Sweeper	445
Index	451
    
            Introduction
            Overview
    
        What This Book Includes
    
        Is This Book for You
    
        What Do You Need to Use This Book
    
        How This Book is Organized
    
        Using Code Examples
Overview
Welcome to Practical GPU Graphics with wgpu and Rust. The wgpu API is based on the WebGPU standard and is a Rust implementation of the WebGPU API specifications. WebGPU is the next-generation graphics API for the web, which is being developed by the W3C GPU for the Web Community Group with engineers from Apple, Google, Microsoft, Mozilla, and others. It is a future web standard for graphics and compute, aiming to provide modern 3D graphics and computation capabilities with GPU acceleration on the web.
The wgpu API is a cross-platform, safe, pure-Rust graphics API. Even though it is based on the WebGPU standard, it can run not only on the web via WebAssembly, but also natively on Vulkan, Metal, DirectX12, DirectX11, and OpenGLES. This book will provide all the tools you need to help you create advanced 3D graphics and GPU computing in Rust on native devices using this new graphics API. I hope that this book will be useful for web developers, graphics creators, computer graphics programmers, game developers, and students of all skill levels who are interested in graphics development on the web and on devices with native modern graphics APIs.
Unlike WebGL which is based on OpenGL, WebGPU and wgpu are not direct ports of any existing native APIs. They are based on concepts in the Vulkan, Metal, and Direct3D12 APIs and are intended to provide high performance on these modern native graphics APIs across mobile and desktop platforms.
In order to understand wgpu technology, we need to review a brief history of native graphics technologies. The first to come was OpenGL, originally developed in the early 1990s. It is a low-level high performance graphics technology, which WebGL is based on. Since its inception, many graphics applications based on OpenGL have been developed. Modern GPUs actually work very differently from how the original OpenGL did – but many of the core concepts of OpenGL remain the same.
As GPUs became more complex and powerful, the graphics driver ended up having to do a lot of extremely complex work. This made graphics drivers notoriously buggy, and in many cases slower, too, as they had to do all the work on the fly. To improve OpenGL’s performance, Khronos, the group behind OpenGL, proposed a new, completely redesigned modern graphics API called Vulkan, which was released in 2016. Vulkan is even more low-level, faster, and simpler, and is a much better match for modern hardware.
However, using Vulkan also meant that applications had to completely rewrite all their graphics code in order to support it. This kind of tectonic shift in technology takes years to play out, and as a result, there is still a lot of OpenGL out there.
While Vulkan was designed to be a standard API able to work on all systems, as has long been the case with standards, Apple also came up with Metal for iOS and MacOS, while Microsoft came up with DirectX12 for Windows and Xbox. Both are more or less the same idea as Vulkan: new, lower-level APIs that throw out all the historical baggage and start with a clean slate design that much more closely matches how modern GPU hardware works.
With the graphics community moving on to this new generation of APIs, the question then became what to do with the web. WebGL is essentially OpenGL with many of the same pitfalls, while high-performance web game engines still stand to greatly benefit from the new generation of graphics APIs.
Unfortunately, unlike OpenGL, Vulkan has run into trouble achieving true cross-platform reach thanks to Apple. MacOS and iOS only support Metal and have no official support for Vulkan, although there are third-party libraries for it. Furthermore, Vulkan itself is still not very suitable for the web – it is just too low-level, even dealing with minutiae like GPU memory allocators so that AAA game engines can extract the maximum conceivable performance. This is overkill for web platforms, plus security is a much more significant concern in browsers.
So the solution was an all-new API design, high-level enough to be usable and secure in a browser, and able to be implemented on top of any one of Vulkan, Metal and DirectX12. This is WebGPU, which looks like the only truly cross-platform, modern, and low-level graphics API for web applications.
Based on the WebGPU standard, the wgpu API is a native WebGPU implementation in Rust. It can run natively on cross-platform devices with any modern graphics API such as Vulkan, Metal, or DirectX12. It can also run on the web by converting wgpu apps into WebAssembly packages.
Note that WebGPU and wgpu have not been finalized and are still in the early stages of development, so their API interfaces may change frequently before they are officially released. In addition, WebGPU and wgpu use a new shader language called WGSL (WebGPU Shading Language) instead of the traditional GLSL shader language used in OpenGL and WebGL applications.
Practical GPU Graphics with wgpu and Rust provides everything you need to create advanced 3D graphics objects in your wgpu applications using GPU acceleration. In this book, you will learn how to create a variety of 3D graphics and charts that range from simple 3D shapes such as cubes, spheres, cylinders, to complex 3D surface graphics such as 3D wireframes, 3D surface charts, and complex particle systems created using compute shaders. I will try my best to introduce readers to the wgpu API, the next-generation graphics API for native graphics devices, in a simple way – simple enough to be easily followed by programmers who have little experience in developing advanced graphics applications. You can learn from this book how to create a full range of 3D graphics applications using the wgpu API and WGSL shader program.
In fact, there are several bindings of the wgpu-native API in different programming languages, including C, Python, C# .NET, Java, and Julia, to name a few. Here, I use the Rust wrapper – wgpu, because of Rust’s performance and safety features. Rust is a low-level, statically typed, system-programming language, which solves problems that C and C++ have been struggling with for a long time, such as errors and building concurrent programs. Compared to C and C++, Rust has three main benefits: better memory safety due to its compiler, easier concurrency due to a data ownership model that prevents data races, and zero-cost abstraction. According to a recent Stack-Overflow survey, Rust has been the most loved programming language for the last five years in a row (https://insights.stackoverflow.com/survey /2020#technology).
What This Book Includes
This book and its sample code listings, which are available for download at my website at https://drxudotnet.com, provide you with
- A complete, in-depth instruction to practical 3D graphics programming in Rust with wgpu. After reading this book and running the example programs, you will be able to create various sophisticated 3D graphics and charts with GPU acceleration in your native applications.
 - Over 50 ready-to-run example projects that allow you to explore the 3D graphics techniques described in this book. You can use these examples to get a better understanding of how 3D graphics and charts are created using the wgpu API and shader program. You can also modify the programs or add new features to them to form the basis of your own projects. Some of the example code listings provided with this book are already sophisticated chart and graphics projects, and can be directly used in your own real-world applications.
 - • Many functions and components in the sample code listings that you will find useful in your 3D graphics development. These functions and components include 3D transformation, projection, colormaps, lighting models created in fragment shaders, wgpu pipeline settings, WGSL shader code, and many other useful utility functions. You can extract these functions and components and plug them into your own applications.
 
Is This Book for You
You do not have to be an experienced Rust and graphics developer to use this book. I designed this book to be useful to people of all levels of programming experience. In fact, I believe that if you have some prior experience with programming languages such as Rust, C++, Java, R, Python, VBA, C#, or JavaScript, you will be able to sit down in front of your computer, start up Visual Studio Code, follow the examples provided in this book, and quickly become proficient with modern 3D graphics development using the wgpu API. For those of you who are already experienced Rust programmers or graphics/game developers, I believe this book has much to offer as well. A great deal of the information about wgpu programming in this book is not available in other tutorial and reference books. In addition, you can use most of the example programs in this book directly in your own real-world application development. This book will provide you with a level of detail, explanation, instruction, and sample program code that will enable you to do just about anything related to modern 3D graphics development for native devices and the web using the next-generation wgpu graphics API.
Throughout the book, I will emphasize the usefulness of wgpu graphics programming to real-world applications. If you follow the instructions presented in this book closely, you will easily be able to develop various graphics and chart applications with GPU acceleration from simple 3D shapes to 3D surfaces with powerful colormap, wireframe, and texture mapping. You can also use the compute and fragment shaders to create complicated particle systems, domain coloring for complex functions, and fractal images. At the same time, I will not spend too much time discussing program style and code optimization because there is a plethora of books out there already dealing with those topics. Most of the example programs you will find in this book omit error handlings, which makes the code easier to understand by focusing only on the key concepts and practical applications.
What Do You Need to Use This Book
You will need no special equipment to make the best use of this book and understand its algorithms. This book takes full advantage of open source frameworks and libraries. The sample programs companying this book can run on various operating systems, including Windows, Linux, iOS, and MacOS. This book uses Visual Studio Code (VS Code), Rust, and Cargo package manager for its development environment and tools. VS Code is a lightweight IDE and powerful source code editor that runs on various operating systems. It has support for Rust and WGSL with the help of relevant extensions.
Since the wgpu standard has not been finalized and is still in early development stage, its API may change frequently. This book uses the wgpu crate version 0.11 for implementing wgpu applications.
If you install other versions of the wgpu API, you may still be able to run most of the sample code with few modifications. Please remember, however, that this book is intended for that specific version of the wgpu API, on which all of the example programs were created and tested, so it is best to run the sample code in the same development environment and using the same version of the wgpu API..
In addition, your operating system needs to have a modern GPU as well as the DirectX 12, Metal, or Vulkan API support on your graphics card.
How This Book Is Organized
This book is organized into fourteen chapters, each of which covers a different topic about modern wgpu graphics programming. The following summaries of each chapter should give you an overview of the book’s content:
    Chapter 1, Set Up Development Tools
    
This chapter explains how to set up the packages and tools required for wgpu application development. VS Code, Rust, and Cargo package manager 
    will be used as our development environment and tools. It also provides a brief introduction to Rust programming.
    Chapter 2, WGPU Basics
    
This chapter provides a brief overview on the current wgpu technology, and then uses a simple triangle example to explain key aspects of the wgpu API, 
    including wgpu context, the rendering pipeline, the shader program, and rendering graphics on a window surface.
    Chapter 3, WGPU Primitives
    
This chapter demonstrates how to draw basic shapes in wgpu, including points, lines, and triangles. These basic shapes are referred to as primitives. 
    There is no built-in support for curves or curved surfaces; they must be approximated by primitives. Currently, wgpu includes five primitives.
    Chapter 4, GPU Buffers
    
This chapter introduces GPU buffers that hold vertex data and color information, and explains how to use GPU buffers to create colorful triangle and square
    with each vertex having a distinct color.
    Chapter 5, 3D Transformations
    
This chapter explains how to perform basic 3D transformations, including translation, scaling, and rotation. It also describes how to construct various matrix
    representations used in 3D graphics, including model matrix, viewing matrix, and projection matrix. These matrices will be used to display 3D graphics
    objects on a 2D screen.
    Chapter 6, 3D Shapes and Camera
    
This chapter shows how to use transformation, viewing, projection matrices, and the camera to create real-world 3D shapes – a 3D line and two cubes: 
    one with distinct face colors and the other with distinct vertex colors. In doing so, you will learn two important concepts in wgpu: bind groups and 
    uniform buffer objects.
    Chapter 7, 3D Wireframe Shapes
    
A wireframe model is a visual representation of 3D objects used in computer graphics. It is created by drawing just the outlines of the polygons that make
    up the object. This chapter explains how to create wireframe models in wgpu for various 3D shapes, including cube, sphere, cylinder, cone, and torus.
    The key to create 3D wireframe shapes is to specify correct coordinates for their vertices.
    Chapter 8, Lighting in WebGPU
    
This chapter demonstrates how to build a simple lighting model in wgpu and how to use it to simulate light sources and the way that the light that they emit
    interacts with your objects on the scene. Here, I will discuss three light sources: ambient light, diffuse light, and specular light.
    Chapter 9, Colormaps and 3D surfaces
    
This chapter explains how to use the color model and colormap to render the simple and parametric 3D surfaces by specifying various mathematical functions. 
    Surfaces play an important role in various applications, including computer graphics, virtual reality, computer games, and 3D data visualization.
    Chapter 10, Textures
    
This chapter discusses 2D image textures that can be applied to a surface to make the color of the surface vary from point to point, something like painting
    a copy of the image onto the surface. It shows how to map 2D textures onto various surfaces in wgpu.
    Chapter 11, 3D Surface Charts
    
Surface charts are plots of 3D data. Rather than displaying the individual data points, surface charts show a functional relationship between a dependent
    variable y, and two independent variables x and z. This chapter explains how to create real-word 3D surface charts with colormaps, and how to add wireframe
    to the surface charts by mapping transparent square images onto the surface.
    Chapter 12, Creating Multiple Objects
    
This chapter explains several approaches used to create multiple objects in a scene. One approach is to use uniform transformations or instancing to 
    render the same object multiple times. Another approach is to combine the vertex data of different objects together and render them as a single object. 
    The third approach is to use different pipelines or different render passes to render different objects.
    Chapter 13, Compute Shaders and Particles
    
This chapter introduces the compute shader and describes how to use it in a simple 2D rotation example. It then applies the compute shader to 
    particle systems – one system mimics the flocking behavior of birds, another simulates the effect of gravity on particles, and the third one models 
    particle kinematics.
    Chapter 14, Visualizing Complex Functions
    
This chapter illustrates how to generate domain coloring in wgpu for various complex functions. It also explains how to create fractal images for 
    the Mandelbrot and Julia sets, as well as some 3D fractal shapes by writing the computation-intensive code directly in the fragment shaders.
Using Code Examples
You may use the code in this book in your own applications and documentation. You do not need to contact the author or the publisher for permission unless you are reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing the example code listings does require permission. Incorporating a significant amount of example code from this book into your applications and documentation also requires permission. Integrating the example code from this book into commercial products is not allowed without written permission of the author.
