ShaderToy clone in Rust, currently supporting MacOS.

Overview

ShaderRoy

ShaderToy clone in Rust, currently supporting MacOS.

Demo Youtube Video

Features

  1. cargo run <rust project dir> displays a single macOS window filled with a Metal framework fragment shader.
  2. You can edit and save the Rust project source code (in VS code or any other editor) to change the fragment shader output and the window will update in real time.
  3. You write the shader in Rust but it is compiled to Metal Shading Language (a variation of C++)
  4. In the shader source you can reference the const INPUT struct which provides inputs for each frame, similarly to Input Uniforms in ShaderToy. You don't need to thread these values through your functions as arguments, despite Metal having no concept of global uniforms like WebGL does.
  5. You can split the shader across multiple files using mod <name> and use <name>::*.
  6. You can pause, restart and even run another shader file from the command line while the window is open.

Instructions

  1. clone this repo
  2. run cargo run raymarching_eyes
  3. edit examples/raymarching_eyes.rs

Why Rust for the shader source? Better syntax, better editor integration and because it's a fun hack. It should feel exactly like writing Rust (which feels awesome!). Unlike in ShaderToy the Rust typechecker warns immediately about most errors one might make.

Metal Shading Rust Language

In general you will write Rust that closely resembles the C++ Metal Shading Language API, except for a few differences.

The INPUT struct is documented in shader_roy_metal_sl_interface.

API MSL (C++) Rust
Scalar Types
float foo() {
  return 3.0;
}

Use standard Rust types that correspond to the Metal types.

fn foo() -> f32 {
  3.0
}
Vector Types
void foo(float3 a, uint2 b) {}

Use the generic Vec type. Its default type argument is f32, for convenience.

fn foo(a: Vec3, b: Vec2<u32>) {}
Constructors

vector constructors (float4 etc.) can take arbitrary number of vector/scalar arguments, as long as they combine to the right length vector

auto x = float2(1.0);
float4(x, x);

uint2(0, 0);

In Rust, these follow the type names. You need to call these as methods.

let x = 1.0.vec2();
(x, x).vec4();

vec2u32(0, 0);
Access Constructors

vector component selection constructors (xxy etc.) allows permutation and/or repetition of components:

auto pos = float2(1.0, 2.0);
auto foo = pos.yyxy;
// => float4(2.0, 2.0, 1.0, 2.0)

In Rust you need to call these as methods:

let pos = (1.0, 2.0).vec2();
let foo = pos.yyxy();
// => (2.0, 2.0, 1.0, 2.0).vec4()
Functions
min(x, y);

Math, geometric and common functions need to be called as methods

x.min(y)
Renamed functions
clamp(x, 0.3, 0.4);
length(x);
length_squared(x);
normalize(x);
faceforward(x, incident, surface);
reflect(x, normal);
refract(x, normal, eta);
fmin(x, y);
fmax(x, y);

Names follow vek

x.clamped(0.3, 0.4);
x.magnitude();
x.magnitude_squared();
x.normalized();
x.face_forward(incident, surface);
x.reflected(normal);
x.refracted(normal, eta);
x.min(y);
x.max(y);
Methods with different argument order
mix(0.3, 0.4, a);
smoothstep(0.3, 0.4, x);
step(0.3, x);

When one argument is special from the others it is used as the receiver of the method call.

a.mix(0.3, 0.4);
x.smoothstep(0.3, 0.4);
x.step(0.3);

Limitations

Modules

Right now only modules in the same directory as the main file will be watched. Only files in the same directory are supported for mod <name>s, <name>/mod.rs is not supported. There is no support for path attribute on mods.

Let bindings

Variables cannot be redeclared. (for now)

Constructors

In Rust we could use a single generic vec2 constructor for all Vec2s. But this would require actually using rustc to compile the constructors to the concrete Metal C++ constructors. To keep things simpler, the Rust bindings here require specifying the constructors directly (vec2bool -> bool2).

Development

Print the compiled shader without opening the window:

cargo test -- --nocapture
You might also like...
High performance Rust ECS library
High performance Rust ECS library

Legion aims to be a feature rich high performance Entity component system (ECS) library for Rust game projects with minimal boilerplate. Getting Start

A refreshingly simple data-driven game engine built in Rust

What is Bevy? Bevy is a refreshingly simple data-driven game engine built in Rust. It is free and open-source forever! WARNING Bevy is still in the ve

Rust library to create a Good Game Easily

ggez What is this? ggez is a Rust library to create a Good Game Easily. The current version is 0.6.0-rc0. This is a RELEASE CANDIDATE version, which m

RTS game/engine in Rust and WebGPU
RTS game/engine in Rust and WebGPU

What is this? A real time strategy game/engine written with Rust and WebGPU. Eventually it will be able to run in a web browser thanks to WebGPU. This

unrust - A pure rust based (webgl 2.0 / native) game engine

unrust A pure rust based (webgl 2.0 / native) game engine Current Version : 0.1.1 This project is under heavily development, all api are very unstable

Rust bindings for GDNative

GDNative bindings for Rust Rust bindings to the Godot game engine. Website | User Guide | API Documentation Stability The bindings cover most of the e

SDL bindings for Rust

Rust-SDL Bindings for SDL in Rust Overview Rust-SDL is a library for talking to SDL from Rust. Low-level C components are wrapped in Rust code to make

SDL2 bindings for Rust

Rust-SDL2 Bindings for SDL2 in Rust Changelog for 0.34.2 Overview Rust-SDL2 is a library for talking to the new SDL2.0 libraries from Rust. Low-level

SFML bindings for Rust

rust-sfml Rust bindings for SFML, the Simple and Fast Multimedia Library. Requirements Linux, Windows, or OS X Rust 1.42 or later SFML 2.5 CSFML 2.5 D

Owner
Michal Srb
Michal Srb
This is the core library with the full abstraction and implementation of the Minecraft protocol and logic. (Currently WIP)

MineRust (WIP) This is the core library with the full abstraction and implementation of the Minecraft protocol and logic. This project is currently WI

MineRust Project Suite 2 Nov 20, 2022
Tools for working with Retro game formats. Currently only supports Metroid Prime Remastered.

retrotool Warning Under active development, not guaranteed to be useful or even function. Tools for working with Retro game formats. Currently only su

null 4 Feb 19, 2023
A highly customizable snake clone made in Rust with the Bevy engine, named after the Japanese word for snake, 蛇.

Hebi ?? A highly customizable snake clone made in Rust with the Bevy engine, named after the Japanese word for snake, 蛇(へび). Configuration One of the

Elnu 79 Dec 7, 2022
Port of my AST3 asteroids clone Bevy/rust from Unity/C#.

Port of my AST3 asteroids clone Bevy/rust from Unity/C#. This is my first rust program. Be gentle. Still working on it, but actually playable. You can

Jorge Monasterio 2 Mar 24, 2022
Clone of Soldat engine written in Rust

Soldank ?? open source clone of Soldat engine written in Rust ?? Screenshot Goals Fully authentic look and feel bugs feature-complete port of Soldat b

Tomasz Sterna 48 Dec 5, 2022
Rust-raytracer - πŸ”­ A simple ray tracer in Rust πŸ¦€

rust-raytracer An implementation of a very simple raytracer based on Ray Tracing in One Weekend by Peter Shirley in Rust. I used this project to learn

David Singleton 159 Nov 28, 2022
Rust-and-opengl-lessons - Collection of example code for learning OpenGL in Rust

rust-and-opengl-lessons Project requires Rust 1.31 Collection of example code for learning OpenGL in Rust 00 - Setup 01 - Window 02 - OpenGL Context 0

Nerijus Arlauskas 348 Dec 11, 2022
Simple retro game made using Rust bracket-lib by following "Herbert Wolverson's Hands on Rust" book.

Flappy Dragon Code from This program is a result of a tutorial i followed from Herbert Wolverson's Hands-on Rust Effective Learning through 2D Game De

Praneeth Chinthaka Ranasinghe 1 Feb 7, 2022
A rust chess implementation using a neural network scoring function built on huggingface/candle + rust + wasm

Rusty Chess What is it? Rusty Chess aims to be a high quality embeddable chess engine that runs entirely locally in the browser (no backend required).

Gareth 3 Nov 3, 2023
A Rust wrapper and bindings of Allegro 5 game programming library

RustAllegro A thin Rust wrapper of Allegro 5. Game loop example extern crate allegro; extern crate allegro_font; use allegro::*; use allegro_font::*;

null 80 Dec 31, 2022