Shadertoy移植到Rust GPU
Shadertoys Ported to Rust GPU

原始链接: https://rust-gpu.github.io/blog/2025/04/10/shadertoys/

Rust GPU 允许使用 Rust 编写 GPU 着色器,并将其编译成 SPIR-V,用于 Vulkan 工作流程。一个最近的项目成功地将 Shadertoy 着色器移植到 Rust,突出了其关键优势:使用 `bytemuck` crate 实现 CPU 和 GPU 之间无缝的数据共享;支持 trait、泛型和宏,从而实现可重用且符合人体工程学的抽象;以及能够使用熟悉的 Rust 工具,例如 `cargo`、`clippy` 和其他特性。该团队利用 trait 进行着色器特定操作,并使用泛型来实现通道类型灵活性。宏被用来减少代码重复。他们还通过修复 `wgpu` 和 `naga` 中的问题回馈了生态系统。尽管存在一些不足之处,但移植过程非常简单,证明 Rust GPU 适用于着色器实验,并欢迎更多用户和贡献者来改进入门和文档。代码可在 GitHub 上的 rust-gpu 仓库中找到。

一个 Hacker News 讨论串正在热议一个将 Shadertoy 移植到 Rust GPU 的项目。一位名为“hackyhacky”的评论者对项目介绍中的一句话提出了异议,该句话声称 CUDA 和 OpenCL 是 HLSL 和 GLSL 的“更好替代方案”,但由于厂商锁定或缺乏传统的图形管道支持而不适用。“hackyhacky”认为这种比较具有误导性,因为 CUDA 和 OpenCL 是计算语言,而 HLSL 和 GLSL 是着色器语言,两者服务于根本不同的目的。虽然两者都可以用于超出其最初目的的用途,“hackyhacky”认为将 CUDA 作为 GLSL 的直接替代方案是不诚实的。
Hacker News 最新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Shadertoys移植到Rust GPU (rust-gpu.github.io) 23 分,由 todsacerdoti 3 小时前发布 | 隐藏 | 过去 | 收藏 | 2 条评论 sitkack 17 分钟前 | 下一条 [–] https://github.com/Rust-GPU/rust-gpu-shadertoys 回复 airstrike 1 小时前 | 上一条 [–] 昨天:https://news.ycombinator.com/item?id=43667693 (84 分,33 条评论) 回复 加入我们,参加6月16-17日在旧金山举办的AI创业学校! 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系我们 搜索:

原文

We ported a few popular Shadertoy shaders over to Rust using Rust GPU. The process was straightforward and we want to share some highlights.

The code is available on GitHub.

Shadertoy screenshot

What is Rust GPU?

Rust GPU is a project that allows you to write code for GPUs using the Rust programming language. GPUs are typically programmed using specialized languages like WGSL, GLSL, MSL, or HLSL. Rust GPU changes this by letting you use Rust to write GPU programs (often called "shaders" or "kernels").

These Rust GPU programs are then compiled into SPIR-V, a low-level format that most GPUs understand. Since SPIR-V is the format Vulkan uses, Rust GPU makes it possible to integrate Rust-based GPU programs into any Vulkan-compatible workflow.

For more details, check out the Rust GPU website or the GitHub repository.

Shared code between CPU and GPU

Sharing data between the CPU and GPU is common in shader programming. This often requires special tooling or manual effort. Using Rust on both sides made this seamless:

#[repr(C)]
#[derive(Copy, Clone, Pod, Zeroable)]
pub struct ShaderConstants {
pub width: u32,
pub height: u32,
pub time: f32,
pub cursor_x: f32,
pub cursor_y: f32,
pub drag_start_x: f32,
pub drag_start_y: f32,
pub drag_end_x: f32,
pub drag_end_y: f32,
pub mouse_left_pressed: u32,
pub mouse_left_clicked: u32,
}

Note that on both the CPU and the GPU we are using the bytemuck crate for the Pod and Zeroable derives. This crate is unmodified and integrated directly from crates.io. Many no_std + no alloc Rust crates work on the GPU!

Traits, generics, and macros

Rust GPU supports traits. We used traits to encapsulate shader-specific operations in reusable ergonomic abstractions:

pub trait FloatExt {
fn gl_fract(self) -> Self;
fn rem_euclid(self, rhs: Self) -> Self;
fn gl_sign(self) -> Self;
fn deg_to_radians(self) -> Self;
fn step(self, x: Self) -> Self;
}

While there are still some rough edges, generics mostly work as expected. We used them to support multiple channel types without duplicating logic:

pub struct State<C0, C1> {
inputs: Inputs<C0, C1>,
cam_point_at: Vec3,
cam_origin: Vec3,
time: f32,
ldir: Vec3,
}

Rust macros also function normally. Using macros allowed us to reduce repetitive code further.

macro_rules! deriv_impl {
($ty:ty) => {
impl Derivative for $ty {
deriv_fn!(ddx, OpDPdx, false);
deriv_fn!(ddx_fine, OpDPdxFine, true);
deriv_fn!(ddx_coarse, OpDPdxCoarse, true);
deriv_fn!(ddy, OpDPdy, false);
deriv_fn!(ddy_fine, OpDPdyFine, true);
deriv_fn!(ddy_coarse, OpDPdyCoarse, true);
deriv_fn!(fwidth, OpFwidth, false);
deriv_fn!(fwidth_fine, OpFwidthFine, true);
deriv_fn!(fwidth_coarse, OpFwidthCoarse, true);
}
};
}


deriv_impl!(f32);
deriv_impl!(Vec2);
deriv_impl!(Vec3A);
deriv_impl!(Vec4);

Want to typecheck the shaders? cargo check. Build them? cargo build. Run in release mode? cargo run --release. Gate code at compile time? Use features.

If you run clippy on the shaders, you'll see it complains about many things as we intentionally kept the Rust versions of shaders similar to their original GLSL versions.

This is one of Rust GPU's big advantages: you can use all the Rust tools you're already familiar with.

Improving the Rust ecosystem

While porting shaders, we also contributed back to the ecosystem by identifying and fixing several issues in wgpu and naga:

These fixes help everyone using wgpu and naga, not just users of Rust GPU.

Come join us!

While we hit some sharp edges, porting Shadertoy shaders to Rust with Rust GPU was reasonably straightforward. Rust GPU is definitely ready for shader experimentation.

We're eager to add more users and contributors! We will be working on revamping the onboarding and documentation soon. To follow along or get involved, check out the rust-gpu repo on GitHub.

联系我们 contact @ memedata.com