要在Rust中使用naga
将GLSL代码直接转换为wgpu
可以使用的格式,您需要执行以下步骤:
- 使用
naga
解析GLSL代码 :naga
是一个用于解析、验证和转换不同着色语言的库。我们将使用它来解析GLSL代码并转换为wgpu
可以使用的wgsl
格式。 - 将
wgsl
代码传递给wgpu
:一旦我们有了wgsl
代码,就可以将其传递给wgpu
以创建着色器模块。
以下是一个完整的示例,展示了如何将GLSL代码转换为wgsl并在wgpu
中使用:
依赖
toml
[dependencies]
winit = "0.29.15"
wgpu = "0.20"
naga = { version = "0.20.0", features = ["glsl-in", "wgsl-out"] }
示例代码
rust
fn main() {
use naga::ShaderStage;
use naga::front::glsl::{Frontend, Options};
use naga::valid::{Capabilities, Validator};
use naga::valid::ValidationFlags;
use naga::back::wgsl;
let glsl = r#"
#version 450
layout(location = 0) in ivec4 a_Pos;
layout(location = 1) in ivec4 a_Normal;
layout(location = 0) out vec3 v_Normal;
layout(location = 1) out vec4 v_Position;
layout(set = 0, binding = 0) uniform Globals {
mat4 u_ViewProj;
uvec4 u_NumLights;
};
layout(set = 1, binding = 0) uniform Entity {
mat4 u_World;
vec4 u_Color;
};
void main() {
v_Normal = mat3(u_World) * vec3(a_Normal.xyz);
v_Position = u_World * vec4(a_Pos);
gl_Position = u_ViewProj * v_Position;
}
"#;
// 使用 naga 解析 GLSL 代码
let mut frontend = Frontend::default();
let options = Options::from(ShaderStage::Vertex);
let Ok(res) = frontend.parse(&options, glsl) else { panic!("Failed to parse shader") };
// println!("{:?}", res);
// 验证模块
let mut validator = Validator::new(ValidationFlags::all(), Capabilities::empty());
let Ok(module_info) = validator.validate(&res) else { panic!("Failed to validate shader") };
// println!("{:?}", module_info);
// 将模块转换为 WGSL
let code = wgsl::write_string(&res, &module_info, wgsl::WriterFlags::all() ).unwrap();
println!("{}", code);
}