https://github.com/pannapudi/compaster
Rasterization using compute shaders
https://github.com/pannapudi/compaster
compute gpu rasterization shaders wgpu
Last synced: 10 months ago
JSON representation
Rasterization using compute shaders
- Host: GitHub
- URL: https://github.com/pannapudi/compaster
- Owner: pannapudi
- Created: 2021-12-14T15:46:38.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-07-12T07:57:39.000Z (almost 2 years ago)
- Last Synced: 2025-02-28T18:41:47.525Z (over 1 year ago)
- Topics: compute, gpu, rasterization, shaders, wgpu
- Language: Rust
- Homepage:
- Size: 186 KB
- Stars: 21
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# gpu_compute_rasterizer

This is a basic implementation of a rasterizer using compute shaders and [wgpu](https://github.com/gfx-rs/wgpu).
## Differences
1. Typed GPU buffers.
From the CPU side I was able to utilize Rust type system and awesome crate [bytemuck](https://github.com/Lokathor/bytemuck) to have typed GPU buffers.
WebGPU (and any other graphics API) has strict rules for memory alignment.
`Vec3` vector types having size of 12 (3 * size_of(f32)) bytes has an alignment of 16, same as `Vec4`. And for Rust, all structs have to be marked as `#[repr(C)]` it prevents from shuffling fields for the sake of size optimization and the alighment checked by `Pod` and `Zeroable` traits provided by `bytemuck`.
2. Render one fullscreen triangle instead of quad.
Having to render a fullscreen quad (or something that fills the whole screen required in `present.wgsl` shader to copy buffer content on screen.
Advantages of using fullscreen triangle is it only requires 3 vertex shader invocations (instead of 6 for a quad made up of two triangles) and less code(but not simpler).
```rust
[[stage(vertex)]]
fn vs_main_trig([[builtin(vertex_index)]] vertex_idx: u32) -> VertexOutput {
let uv = vec2((vertex_idx << 1u) & 2u, vertex_idx & 2u);
let out = VertexOutput(vec4(1.0 - 2.0 * vec2(uv), 0.0, 1.0));
return out;
}
```
3. More types in shaders
I also tried to simplify buffer access by creating `Pixel` struct, but that didn't work well, because we can't currently have atomic operations and types on non `scalar types` by wgsl spec.
```rust
let p = color_buffer.value[index];
let pixel = pixel_to_vec(p);
let col = vec4(pixel, 1.0);
```
original
```rust
let index = u32(X + Y * uniforms.screenWidth) * 3u;
let R = f32(finalColorBuffer.data[index + 0u]) / 255.0;
let G = f32(finalColorBuffer.data[index + 1u]) / 255.0;
let B = f32(finalColorBuffer.data[index + 2u]) / 255.0;
let finalColor = vec4(R, G, B, 1.0);
```
Also I tried to add look_at camera, but currently didn't get any success in it.