Skip to content

Commit 7f3ab45

Browse files
committed
Add subpasses rust shaders
1 parent f433298 commit 7f3ab45

File tree

14 files changed

+261
-0
lines changed

14 files changed

+261
-0
lines changed

shaders/rust/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shaders/rust/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ members = [
110110
"ssao/ssao",
111111
"stencilbuffer/outline",
112112
"stencilbuffer/toon",
113+
"subpasses/composition",
114+
"subpasses/gbuffer",
115+
"subpasses/transparent",
113116
"tessellation/base",
114117
"tessellation/passthrough",
115118
"tessellation/pntriangles",
3.7 KB
Binary file not shown.
688 Bytes
Binary file not shown.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "subpasses-composition"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
6+
[lib]
7+
crate-type = ["dylib"]
8+
9+
[dependencies]
10+
spirv-std = { workspace = true }
11+
12+
[package.metadata.rust-gpu.build]
13+
capabilities = ["InputAttachment"]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#![cfg_attr(target_arch = "spirv", no_std)]
2+
#![allow(clippy::missing_safety_doc)]
3+
4+
use spirv_std::{spirv, glam::{Vec2, Vec3, Vec4}};
5+
use spirv_std::num_traits::Float;
6+
7+
#[repr(C)]
8+
#[derive(Copy, Clone)]
9+
pub struct Light {
10+
pub position: Vec4,
11+
pub color: [f32; 3],
12+
pub radius: f32,
13+
}
14+
15+
const AMBIENT: f32 = 0.05;
16+
17+
#[spirv(vertex)]
18+
pub fn main_vs(
19+
#[spirv(vertex_index)] vertex_index: i32,
20+
#[spirv(position)] out_position: &mut Vec4,
21+
out_uv: &mut Vec2,
22+
) {
23+
let uv = Vec2::new(
24+
((vertex_index << 1) & 2) as f32,
25+
(vertex_index & 2) as f32
26+
);
27+
*out_uv = uv;
28+
*out_position = Vec4::new(uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0);
29+
}
30+
31+
#[spirv(fragment)]
32+
pub fn main_fs(
33+
#[spirv(input_attachment_index = 0, descriptor_set = 0, binding = 0)] input_position: &spirv_std::Image!(subpass, type=f32, sampled=false),
34+
#[spirv(input_attachment_index = 1, descriptor_set = 0, binding = 1)] input_normal: &spirv_std::Image!(subpass, type=f32, sampled=false),
35+
#[spirv(input_attachment_index = 2, descriptor_set = 0, binding = 2)] input_albedo: &spirv_std::Image!(subpass, type=f32, sampled=false),
36+
#[spirv(storage_buffer, descriptor_set = 0, binding = 3)] lights: &[Light],
37+
_in_uv: Vec2,
38+
out_color: &mut Vec4,
39+
) {
40+
// Read G-Buffer values from previous sub pass
41+
let coord = spirv_std::glam::IVec2::new(0, 0); // Subpass reads at current fragment location
42+
let frag_pos = input_position.read_subpass(coord).truncate();
43+
let normal = input_normal.read_subpass(coord).truncate();
44+
let albedo = input_albedo.read_subpass(coord);
45+
46+
// Ambient part
47+
let mut frag_color = albedo.truncate() * AMBIENT;
48+
49+
for i in 0..64 {
50+
let light = &lights[i];
51+
let l = light.position.truncate() - frag_pos;
52+
let dist = l.length();
53+
54+
let l = l.normalize();
55+
let atten = light.radius / (dist.powf(3.0) + 1.0);
56+
57+
let n = normal.normalize();
58+
let n_dot_l = n.dot(l).max(0.0);
59+
let color = Vec3::new(light.color[0], light.color[1], light.color[2]);
60+
let diff = color * albedo.truncate() * n_dot_l * atten;
61+
62+
frag_color += diff;
63+
}
64+
65+
*out_color = Vec4::new(frag_color.x, frag_color.y, frag_color.z, 1.0);
66+
}
1.65 KB
Binary file not shown.
9.17 KB
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "subpasses-gbuffer"
3+
version = "0.1.0"
4+
edition.workspace = true
5+
6+
[lib]
7+
crate-type = ["dylib"]
8+
9+
[dependencies]
10+
spirv-std = { workspace = true }
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#![cfg_attr(target_arch = "spirv", no_std)]
2+
#![allow(clippy::missing_safety_doc)]
3+
4+
use spirv_std::{spirv, glam::{Mat3, Mat4, Vec3, Vec4}};
5+
6+
#[repr(C)]
7+
#[derive(Copy, Clone)]
8+
pub struct Ubo {
9+
pub projection: Mat4,
10+
pub model: Mat4,
11+
pub view: Mat4,
12+
}
13+
14+
#[spirv(vertex)]
15+
pub fn main_vs(
16+
in_pos: Vec4,
17+
in_color: Vec3,
18+
in_normal: Vec3,
19+
#[spirv(uniform, descriptor_set = 0, binding = 0)] ubo: &Ubo,
20+
#[spirv(position)] out_position: &mut Vec4,
21+
out_normal: &mut Vec3,
22+
out_color: &mut Vec3,
23+
out_world_pos: &mut Vec3,
24+
_out_tangent: &mut Vec3,
25+
) {
26+
*out_position = ubo.projection * ubo.view * ubo.model * in_pos;
27+
28+
// Vertex position in world space
29+
let world_pos = (ubo.model * in_pos).truncate();
30+
// GL to Vulkan coord space
31+
*out_world_pos = Vec3::new(world_pos.x, -world_pos.y, world_pos.z);
32+
33+
// Normal in world space
34+
let m_normal = Mat3::from_mat4(ubo.model).transpose().inverse();
35+
*out_normal = m_normal * in_normal.normalize();
36+
37+
// Currently just vertex color
38+
*out_color = in_color;
39+
}
40+
41+
#[spirv(fragment)]
42+
pub fn main_fs(
43+
#[spirv(frag_coord)] frag_coord: Vec4,
44+
in_normal: Vec3,
45+
in_color: Vec3,
46+
in_world_pos: Vec3,
47+
#[spirv(spec_constant(id = 0))] near_plane_bits: u32,
48+
#[spirv(spec_constant(id = 1))] far_plane_bits: u32,
49+
out_color: &mut Vec4,
50+
out_position: &mut Vec4,
51+
out_normal: &mut Vec4,
52+
out_albedo: &mut Vec4,
53+
) {
54+
*out_position = Vec4::new(in_world_pos.x, in_world_pos.y, in_world_pos.z, 1.0);
55+
56+
let mut n = in_normal.normalize();
57+
n.y = -n.y;
58+
*out_normal = Vec4::new(n.x, n.y, n.z, 1.0);
59+
60+
out_albedo.x = in_color.x;
61+
out_albedo.y = in_color.y;
62+
out_albedo.z = in_color.z;
63+
64+
// Store linearized depth in alpha component
65+
let near_plane = f32::from_bits(near_plane_bits);
66+
let far_plane = f32::from_bits(far_plane_bits);
67+
let z = frag_coord.z * 2.0 - 1.0;
68+
out_position.w = (2.0 * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
69+
70+
// Write color attachments to avoid undefined behaviour (validation error)
71+
*out_color = Vec4::ZERO;
72+
}

0 commit comments

Comments
 (0)