#wgsl #shader #wgpu #graphics #gamedev #constant

wgsl_preprocessor

用Rust编写的WGPU的WGSL非官方预处理器

8个版本 (稳定)

1.1.4 2024年8月19日
1.1.3 2022年8月29日
1.0.0 2022年7月30日
0.1.0 2022年7月30日

游戏开发中排名249

Download history 4/week @ 2024-06-21 1/week @ 2024-06-28 1/week @ 2024-07-26 121/week @ 2024-08-16

每月下载122

GPL-2.0-or-later

24KB
437

此Crate提供了一组库,用于执行与WGSL中预处理器期望执行的操作类似的功能。由于WGSL至少在1.0版本中不会有一个预处理器,因此此Crate提供了解决一些常见问题的方案,如包含着色器文件和从Rust代码中定义常量。

示例:包含多个着色器文件

以下是本示例中三个着色器文件的内容(每个包含文件末尾都有空行):test_shaders/main.wgsl

//!include test_shaders/included.wgsl test_shaders/included2.wgsl

test_shaders/included.wgsl:

struct TestStruct {
	test_data: vec4<f32>;
};

test_shaders/included2.wgsl:

struct AnotherTestStruct {
	another_test_data: vec3<u32>;
};

使用这些 include 语句,main.wgsl 变为

struct TestStruct {
	test_data: vec4<f32>;
};
struct AnotherTestStruct {
	another_test_data: vec3<u32>;
};

需要注意的是,test_shaders/main.wgsl 也可以包含

//!include test_shaders/included.wgsl
//!include test_shaders/included2.wgsl

结果将会相同。

示例:定义宏

支持非函数式宏定义,例如

//!define u3 vec3<u32>
@compute
@workgroup_size(64)
fn main(@builtin(global_invocation_id) id: u3) {
	// ...
}

使用这个 define 语句,源代码变为

@compute
@workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
	// ...
}

多行宏尚不支持。

示例:定义常量结构体数组

假设一些颜色常量是在着色器编译前计算的,并且出于性能原因应该注入到代码中。 main.wgsl 将包含

struct Struct {
	data: vec4<f32>,
}
//!define STRUCT_ARRAY

在Rust代码中,Struct 被定义,并且给定一个实现 WGSLType 它可以转换为一个具有单个名为 data 的成员 vec4<f32> 的WGSL结构体。构建和编译着色器的Rust代码将包含

use wgsl_preprocessor::WGSLType;

struct Struct {
	pub data: [f32; 4],
}

impl WGSLType for Struct {
	fn type_name() -> String {
		"Struct".to_string()
	}

	fn string_definition(&self) -> String {
		format!("{}(vec4<f32>({:?}))", Self::type_name(), self.data)
			.replace(&['[', ']'], "")
	}
}

使用以下数组定义构建和编译 main.wgsl

use wgsl_preprocessor::ShaderBuilder;

ShaderBuilder::new("main.wgsl")
	.unwrap()
	.put_array_definition(
		"STRUCT_ARRAY",
		&vec![
			&Struct {
				data: [1.0, 2.0, 3.0, 4.0]
			},
			&Struct {
				data: [1.5, 2.1, 3.7, 4.9]
			}
		]
	)
	.build();

编译后的内容将与

var<private> STRUCT_ARRAY: array<Struct, 2> = array<Struct, 2>(Struct(vec4<f32>(1.0, 2.0, 3.0, 4.0)),Struct(vec4<f32>(1.5, 2.1, 3.7, 4.9)),);

Crate功能

将适当长度的数组作为向量插入

默认情况下,以下功能均未启用。

  • array_vectors - 当启用时,适合长度的所有数组和标量类型的 WGSLType 实现会被编译。此功能强制将(例如)[f32; 4] 转换为 ShaderBuilder::put_array_definition 等方法中的 WGSL 类型 vec4<f32>
  • cgmath_vectors - 此功能与 array_vectors 类似,但与 cgmath 向量对象(如 cgmath::Vector3<u32>)相关,这些对象将被转换为 vec3<u32>

依赖关系

~5–37MB
~565K SLoC