glsl-quasiquote-0.2 was released early this morning. This new version provides a more stable public API. Two major changes: The glsl_str! proc-macro would have only survived the 0.1 version. It’s now deprecated and will be removed soon. The glsl! proc-macro now supports GLSL pragmas (both #version and #extension).
Games and Graphics
Building games with Rust and other graphics related work.
When triangle meshes are rendered by a GPU, there are pipeline stages that need to load and process vertex and index data. The efficiency of this process will depend on the layout of the data, and how the GPU is designed. There is an excellent library from Arseny Kapoulkine called meshoptimizer, which provides a variety of algorithms for optimizing geometry for the GPU.
With this article, I want to introduce you to game development. I want to give you a little tour of where to start, how to explore possibilities and revive my journey a little bit at the same time. I will try to construct different games from the ground up while writing this article, so you can experience game-dev live.
For the last two parts of this tutorial, all we’ve had to look at on-screen is a single blueish triangle. In this part, we want to display a more complex shape, with more variation in color. To do this, we’ll have to stop hard-coding our triangle mesh in the vertex shader. (And start hard-coding it in the source code!)
We want to share some of the progress being made on Amethyst! As we've had a lot of expansion, we've also revamped the way we manage the project and we have some very interesting new features being worked on.
Ralph Levien recently published A crate I want: 2d graphics on his blog, which started some interesting discussions on reddit. At the same time there is a nascent discussion on the draw2d repository (which doesn't have any code at this point) about a potential 2d graphics crate.
The Rust ecosystem has lot of excellent crates, and many more new ones being published. I believe one is missing, though, and I’d really like to see it happen: a cross-platform abstraction for 2D graphics. In this post I will set out what I want.
glsl-quasiquote-0.1 was released today! The crate provides you with two macros: glsl! and glsl_str!. Both are procedural macros that requires a nightly compiler and the proc_macro_non_items feature. They will both output a TranslationUnit, that represents a whole shader AST.
We’re going to walk through a Rust application that I’ve built, which is essentially a basic Roguelike in most regards.
In this second blog post I’m showing how I implemented objects - things the player can interact with - for a text adventure written in Rust. As usual, the full code is available on GitHub.
A bunch of stuff has happened since I published my post on The State of GPGPU in Rust. Most importantly, Denys Zariaiev (@denzp) released his work on a custom linker for Rust CUDA kernels, and a build.rs helper crate to make it easier to use.
These two crates eliminate many of the problems I referred to in my previous post. The linker solves most of the “invalid PTX file” problems, while the ptx-builder crate does all of the magic that Accel was doing behind the scenes.
I’m attempting to write a (very simple, at least initally) text adventure in Rust, so I’m going to share progress on my blog starting today. This first post is about the sections, that to day is the rooms of a house for example.
It’s been a while since my last post! Lately I’ve been quite demotivated to actually produce something worth while for doing a writeup about. Instead I offer you some thoughts on my recent findings using rust and some crates I found particularly useful for computer graphics.
I said in my talk that I would post a potentially more interesting long-form version of the talk that includes things that I couldn’t fit into the 30-ish minute time slot. What I’ve included below is my original long-form version of this talk, but my original intention was not to post this as-is. Originally I wanted to clean this up a bit more and make this into something that wasn’t so much a giant wall of text, but after I started doing this I realized that I was just rewriting it entirely, and at that rate I would never get around to releasing it, which I promised I would do in a timely manner.
After improving functionality and performance of gfx-portability’s Metal backend through benchmarking Dota2, and verifying certain functionality through the Vulkan Conformance Test Suite (CTS), we decided to expand our testing to other projects. We quickly found two projects which matched our criteria: RPCS3 and Dolphin.
I have made four rust programs for programmatically generating artwork in different styles. Here is a sample in each style, along with an explanation of the algorithms.
This tutorial builds on the code we wrote in the previous part. You can find the new code here with comments explaining everything that’s changed, and run it to see what the end result will look like. Last time we got a single triangle rendering on screen. This time we’re going to look at what we need to do to allow window resizing to work properly.
I realized after my first post of this series that it’s not just a journey into rust but also OpenGL. I’ve used other Graphics API’s before but never actually got my hands dirty into OpenGL. Someone on the rust user forums (they are awesome, go check it out!) suggested using compute shaders instead. At the time I had never used compute shaders for a project so I decided to take some time to refactor the program to use a compute shader. This post is a follow up on that remark and will explore the possibilities of using a rust together with OpenGL to run compute shaders.
One of my favorite game jams is Ludum Dare: It’s just you, a theme, and 48 hours to make a game. Pure and challenging, and I’ve participated in several of them from time to time with a variety of tools. Usually my go-to is Unity3D, though arguably my best game was in Python+Pygame. This time though, for Ludum Dare 42 on August 2018, I finally had both the energy and ability to write my game in Rust, using ggez. So I decided to write about it!
Eight part series on using gfx-hal for low level graphics programming.
A Vulkan game from scratch in nine days. Using minimal libraries and pure Rust.
I enjoy using OpenGL a lot, but when I switched from C++ to Rust I found it to be less fun to use. This is because the OpenGL (from gl-rs) code never really fit alongside the rest of my Rust code, due to unsafe blocks, PascalCase function names, hacky conversions to c_void pointers etc. So, to make my life easier in the future when using OpenGL in Rust, I made this crate.
UniverCity is a university management game being programmed in the Rust programming language. As stated above, the game is in early access and is not complete. There will be changes and additions down the line and finishing it may take some time. You may wish to wait until its further along before buying it.
For this years GSoC I (@fkaa) worked on implementing the DirectX 11 backend for gfx, a graphics API which translates to Vulkan, DirectX 12 and Metal.
At work a few months ago, we started experimenting with GPU-acceleration. My boss asked if I was interested. I didn’t know anything about programming GPUs, so of course I said “Heck yes, I’m interested!“. I needed to learn about GPUs in a hurry, and that led to my GPU Path Tracer series. That was a lot of fun, but it showed me that CUDA support in Rust is pretty poor.
gfx-rs is a Rust project aiming to make graphics programming more accessible and portable, focusing on exposing a universal Vulkan-like API. It’s a single Rust API with multiple backends that implement it: Direct3D 12/11, Metal, Vulkan, and even OpenGL. We are also building a Vulkan Portability implementation based on it, which allows non-Rust applications using Vulkan to run everywhere. This post is focused on the Metal backend only.
A modern z-machine for the classics. Encrusted is an interpreter for Infocom-era interactive fiction games like Zork. Run the web interface here ↑, or get it for your terminal.
The language rust has been popping up on my twitter feed and my personal life more and more. It’s been promoted and presented as the ultra safe language, so naturally I decided to check it out. The upcoming series of posts “Journey into rust” will describe and document my experiences using rust, hopefully explaining certain concepts that rust does differently. This will all be written from a C++ programmers standpoint that was thought writing Object Oriented code. I encourage you the reader to think critically and correct where necessary.
On to the actual first post! After reading “the Rust Programming Language” I wanted to get my hands dirty and actually write some code. I like graphical applications and using low level graphics API’s so I decided to implement a cellular automation in rust. But just implementing cellular automation isn’t very exciting, is it? What if we could do this on the GPU…And off I went on my journey to create Conway’s game of life in rust.
I’m excited to announce the brand new website/user-guide for the nphysics2d and nphysics3d crates: pure-rust 2D and 3D real-time physics engines with rigid bodies and joints! Online wasm-based demos are also provided (see for example the Multibody joints 34 demo).
With a brand new tutorial and a ton of new features, including prefabs, controller support, MP3 audio, localisation and an even better ergonomics!
Up to now, all the rendering code has been in the game loop in the main function. The rendering code is simple and straightforward, so, while it should have been extracted into its own function, there wasn't a pressing need to do so. Now that I'm going to enhance the UI, the rendering needs to be extracted.
I now have a map, and a bunch of monsters on the map, able to attack and be attacked by the player. To provide for different kinds of monsters, I needed to add stats like combat strength and HP.
I titled this post “from scratch”, because I am going to assume little knowledge of Rust and basic knowledge of 3D graphics and OpenGL.
Therefore, this tutorial may teach you basic Rust and how to get Rust working with OpenGL, however for in-depth OpenGL learning you will need another tutorial or book.
“From Scratch” also means that we will try to build abstractions ourselves, so that we get better knowledge of Rust. In addition to that, we will able to follow existing OpenGL tutorials, because we will know exactly what OpenGL functions we are calling.
Procedural generation is a technique which allows content to be created programmatically, rather than everything in a game being specifically placed by a designer. Procedural generation doesn't mean completely randomised, rather randomised elements are used as long as they make sense.
This tutorial will show how to create a tilemap-based level with rooms connected by straight corridors, using Rust. We'll also cover how to use seeds to reproduce specific layouts and serialise the output into JSON. The rooms will be placed at random within the level, and corridors are drawn horizontally and vertically to connect the centres of the rooms.
I now have the game up to the point where the player has a random dungeon to explore. It's time to make it more interesting by adding some threats - namely, some monsters.
In the current implementation, the player can see the entire layout of the dungeon from the beginning. The next step is to change the game to start off with the dungeon hidden, so the player will actually have some rooms to explore.
It's time to start making some rooms and connecting them together. These will require making modifications to the map, so I guess it's time to finally refactor the map code into its own legitimate class.
Wikipedia states that flocking is a behavior exhibited when a group of birds, called a flock, are foraging or in flight. Flocking simulation are basically softwares which simulate this flocking behavior of birds. The original algorithm is developed by Craig Reynolds in 1986.
Cheddar is a GLSL superset language. What it means is that most of the GLSL constructs and syntax you’re used to is valid in Cheddar – not all of it; most of it. Cheddar adds a set of features that I think are lacking to GLSL. Among them: Some non-valid GLSL constructions made valid in Cheddar to ease the writing of certain shader stages; A more functional approach to programming shaders on the GPU; Structures, types and GLSL-specific constructs sharing; Imports and modules with live reloading and transitive dependencies.
Hello! Welcome to my third and final post on my GPU-accelerated Path Tracer in Rust. In the last post, we implemented all of the logic necessary to build a true path tracer. Problem is, even on the GPU it’s terrifically slow. This post is (mostly) about fixing that.
But first, we need to fix a bug or two, because I goofed. *sad trombone*
Step -1: Fixing Bugs /u/anderslanglands on Reddit pointed out that, since I’m using Cosine-weighted Importance Sampling, I need to do some extra math to avoid biasing the results.
Hello, and welcome to part two of my series on writing a GPU-accelerated path tracer in Rust. I’d meant to have this post up sooner, but nothing ruins my productivity quite like Games Done Quick. I’m back now, though, so it’s time to turn the GPU ray-tracer from the last post into a real path tracer.
Tracing Paths As mentioned last time, Path Tracing is an extension to Ray Tracing which attempts to simulate global illumination.
In the past few years, I've heard a lot about Rust. As someone that hacks on computer graphics and low-level infrastructure libraries, it seems relevant to my interests. I decided to make a small demo – of a procedural planet generator – and see how it went.
As I mentioned in the last post, until I got a better handle on the off screen console code, I temporarily made all the Rust bindings call out to the default root console. Now that there's a bit of discussion on how the off screen consoles work, it's time to refactor the code to enable their use.
When we built the original Monsters and Sprites demo, we only had 9 days to get it working before the Playcrafting expo we had signed up for, so we had to cut a lot of corners. Since then I’ve been doing bug fixes and working on a lot of miscellaneous engine/language features that I either couldn’t get done in time for the demo, or didn’t realize were important until I started building it. We’ve made a few game updates since then (we now have sound!), but this post is specifically going to explore some language updates I’ve made.
In my first post about my journey to the center of the NES, I was at the point where I was still working on the CPU; implementing new addressing modes and instructions as I made my way through the nestest ROM. Well, I finally finished the CPU, including a handful of the illegal opcodes. The last of the illegal opcodes just need some placeholders, because, as I understand it, very few games use them.
This game was coded in Rust and is playable in web browsers by means of WebAssembly, WebGL and Howler.js. The software I developed is partly open source in the form of Gate, which is the Rust library that powers this game and can power other similar games. Special thanks to the tools I used to create assets: Gimp, FL Studio and BFXR.
In my last post on optimising my Rust path tracer with SIMD I had got withing 10% of my performance target, that is Aras’s C++ SSE4.1 path tracer. From profiling I had determined that the main differences were MSVC using SSE versions of sinf and cosf and differences between Rayon and enkiTS thread pools. The first thing I tried was implement an SSE2 version of sin_cos based off of Julien Pommier’s code that I found via a bit of googling. This was enough to get my SSE4.1 implementation to match the performance of Aras’s SSE4.1 code. I had a slight advantage in that I just call sin_cos as a single function versus separate sin and cos functions, but meh, I’m calling my performance target reached.
The other part of this post is about Rust’s runtime and compile time CPU feature detection and some wrong turns I took along the way.
I gave a talk about lyon at RustFest Paris. This post is the introduction of the talk, wherein I introduce vector graphics and try to get the audience somewhat excited about it. Things will get technical in the follow-up posts.
For the past month or so, I’ve been working on a follow-up to my series on Writing a Raytracer in Rust. This time around, I’ll be talking about writing a GPU-accelerated Path Tracer. As always, I’m writing it in Rust - including the GPU kernel code. Compiling Rust for GPUs at this point is difficult and error-prone, so I thought it would be good to start with some documentation on that aspect of the problem before diving into path tracing.
These early posts will mostly be me trying to work out how to use gfx-rs. I was previously using glium which is fantastic, but is sadly no longer being developed. So my choices are: Learn Vulkan, Use raw OpenGL bindings, Use gfx.
I opted to use the current released version (v0.17.1) but it’s currently undergoing a significant rearchitecture so I may move to that whenever it releases.
I was inspired to work through Peter Shirley’s Ray Tracing in a Weekend mini book (for brevity RTIAW) but I wanted to write it in Rust instead of the C++ that’s used in the book. I found out about the book via @aras_p’s blog series about a toy path tracer he’s been building.
Chucklefish, an independent game studio based in London, publishes hit video games like Stardew Valley and Starbound. Now, the company is developing its next game, code-named Witchbrook, using the Rust programming language instead of C++. Why the switch? Two main reasons: to get better performance on multiprocessor hardware and to have fewer crashes during game play.
I wrote the NES emulator with Rust and WebAssembly to learn Rust. It’s not perfect and have some audio bugs, but it’s good enough to play Super Mario bros.
This is part 2 of a story on taking the long road towards Rust bindings to Faiss. You may wish to read part 1 first for a motivation section and a deeper understanding of how I built a plain C API on top of the C++ library.
Game Development is one of the fields in which Rust can gain a lot of traction. Let’s look at the current ecosystem and let’s see what the community has to offer.
Perhaps you have once wondered how search engines such as Google and TinEye enable their users to search for images which are similar to one that you provide, or how they can identify a building from nothing but a picture. Content-based image retrieval (CBIR) is the backbone concept, and provides exciting new ways to search for useful information. While the concept is no longer novel, the requirements imposed on systems for CBIR are ever increasing due to the increasingly larger amounts of data and demand for higher quality of retrieval.
The short version is: I have some shapes. I want to find their intersection.
Really, I want more than that: I want to drop them all on a canvas, intersect everything with everything, and pluck out all the resulting polygons. The input is a set of cookie cutters, and I want to press them all down on the same sheet of dough and figure out what all the resulting contiguous pieces are. And I want to know which cookie cutter(s) each piece came from.
But intersection is a good start.
Hello! This tutorial will show you how to write a roguelike in the Rust programming language and the libtcod library.
UniverCity is a university management game being programmed in the Rust programming language. This month was spent mostly on the business side of things, including going through the steam partner process.
My nice brother Johannes Ridderstedt sent me some old files a few weeks ago (in late 2017), stuff that he had preserved from an age-old computer of ours. One of these was the file named gameland.zip (not published yet, but I might put it up here some day.) I managed to get this running, and liked what I saw (you'll find the YouTube link to it further down on this page.) Around this time I was reading a bit about WebAssembly which I think will redefine and help reshape the web as we see it today. I was also looking at the Hello, Rust web page, and the "FizzleFade effect using a Feistel network" page in particular.
This is a follow up post. RLSL is a Rust to SPIR-V compiler. SPIR-V is the shading language for Vulkan, similar to other shading languages like GLSL, HLSL but more low level. OpenGL, DX9/11/12, Vulkan, Metal are all graphic APIs that are able to use the GPU to draw pixels on the screen. Those APIs have certain stages that can be controlled by the developer by using the correct shading language.
Last month I was working on a lot of new test scenes for my Rust implementation of the PBRT renderer. But a big chunk of my time went into implementing the curve shape needed for the geometry of hair, and a material, which implements a hair scattering model.
Lyon is a side-project that I have been working on for quite a while. The goal is to play with rendering 2D vector graphics on the GPU, and it's been a lot of fun so far. I haven't talked a lot about it online (except for a couple of reddit threads a year or two ago) so I figured it would be a good topic to get this blog started.