mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
add glsl support
This commit is contained in:
parent
326b20643f
commit
3542ddcd0c
5 changed files with 67 additions and 9 deletions
|
@ -30,7 +30,7 @@ image = { version = "0.23.12", default-features = false }
|
|||
|
||||
# misc
|
||||
wgpu = "0.9"
|
||||
naga = { git = "https://github.com/gfx-rs/naga", rev = "0cf5484bba530f1134badbd2a1c1a8e9daf2e9c3", features = ["glsl-in", "spv-out", "spv-in", "wgsl-in"] }
|
||||
naga = { git = "https://github.com/gfx-rs/naga", rev = "0cf5484bba530f1134badbd2a1c1a8e9daf2e9c3", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
bitflags = "1.2.1"
|
||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
|
||||
use bevy_reflect::{TypeUuid, Uuid};
|
||||
use bevy_utils::{tracing::error, BoxedFuture};
|
||||
use naga::{valid::ModuleInfo, Module};
|
||||
use std::{borrow::Cow, marker::Copy};
|
||||
use naga::{valid::ModuleInfo, Module, ShaderStage};
|
||||
use std::{borrow::Cow, collections::HashMap, marker::Copy};
|
||||
use thiserror::Error;
|
||||
use wgpu::{ShaderFlags, ShaderModuleDescriptor, ShaderSource};
|
||||
|
||||
|
@ -21,6 +21,8 @@ pub enum ShaderReflectError {
|
|||
#[error(transparent)]
|
||||
WgslParse(#[from] naga::front::wgsl::ParseError),
|
||||
#[error(transparent)]
|
||||
GlslParse(#[from] naga::front::glsl::ParseError),
|
||||
#[error(transparent)]
|
||||
SpirVParse(#[from] naga::front::spv::Error),
|
||||
#[error(transparent)]
|
||||
Validation(#[from] naga::valid::ValidationError),
|
||||
|
@ -31,6 +33,7 @@ pub enum ShaderReflectError {
|
|||
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
|
||||
pub enum Shader {
|
||||
Wgsl(Cow<'static, str>),
|
||||
Glsl(Cow<'static, str>),
|
||||
SpirV(Vec<u8>),
|
||||
// TODO: consider the following
|
||||
// PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
|
||||
|
@ -53,6 +56,10 @@ impl ShaderReflection {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_wgsl(&self) -> Result<String, naga::back::wgsl::Error> {
|
||||
naga::back::wgsl::write_string(&self.module, &self.module_info)
|
||||
}
|
||||
}
|
||||
|
||||
impl Shader {
|
||||
|
@ -60,6 +67,18 @@ impl Shader {
|
|||
let module = match &self {
|
||||
// TODO: process macros here
|
||||
Shader::Wgsl(source) => naga::front::wgsl::parse_str(&source)?,
|
||||
Shader::Glsl(source) => {
|
||||
let mut entry_points = HashMap::default();
|
||||
entry_points.insert("vertex".to_string(), ShaderStage::Vertex);
|
||||
entry_points.insert("fragment".to_string(), ShaderStage::Fragment);
|
||||
naga::front::glsl::parse_str(
|
||||
&source,
|
||||
&naga::front::glsl::Options {
|
||||
entry_points,
|
||||
..Default::default()
|
||||
},
|
||||
)?
|
||||
}
|
||||
Shader::SpirV(source) => naga::front::spv::parse_u8_slice(
|
||||
&source,
|
||||
&naga::front::spv::Options {
|
||||
|
@ -84,6 +103,10 @@ impl Shader {
|
|||
Shader::Wgsl(source.into())
|
||||
}
|
||||
|
||||
pub fn from_glsl(source: impl Into<Cow<'static, str>>) -> Shader {
|
||||
Shader::Glsl(source.into())
|
||||
}
|
||||
|
||||
pub fn from_spirv(source: Vec<u8>) -> Shader {
|
||||
Shader::SpirV(source)
|
||||
}
|
||||
|
@ -124,10 +147,15 @@ impl<'a> From<&'a Shader> for ShaderModuleDescriptor<'a> {
|
|||
label: None,
|
||||
source: match shader {
|
||||
Shader::Wgsl(source) => ShaderSource::Wgsl(source.clone()),
|
||||
Shader::Glsl(source) => {
|
||||
let reflection = shader.reflect().unwrap();
|
||||
let wgsl = reflection.get_wgsl().unwrap();
|
||||
ShaderSource::Wgsl(wgsl.into())
|
||||
}
|
||||
Shader::SpirV(_) => {
|
||||
// TODO: we can probably just transmute the u8 array to u32?
|
||||
let x = shader.reflect().unwrap();
|
||||
let spirv = x.get_spirv().unwrap();
|
||||
let reflection = shader.reflect().unwrap();
|
||||
let spirv = reflection.get_spirv().unwrap();
|
||||
ShaderSource::SpirV(Cow::Owned(spirv))
|
||||
}
|
||||
},
|
||||
|
|
|
@ -28,8 +28,10 @@ pub struct SpriteShaders {
|
|||
impl FromWorld for SpriteShaders {
|
||||
fn from_world(world: &mut World) -> Self {
|
||||
let render_device = world.get_resource::<RenderDevice>().unwrap();
|
||||
let shader = Shader::from_wgsl(include_str!("sprite.wgsl"));
|
||||
let shader_module = render_device.create_shader_module(&shader);
|
||||
let shader_vert = Shader::from_glsl(include_str!("sprite.vert"));
|
||||
let shader_frag = Shader::from_glsl(include_str!("sprite.frag"));
|
||||
let shader_module_vert = render_device.create_shader_module(&shader_vert);
|
||||
let shader_module_frag = render_device.create_shader_module(&shader_frag);
|
||||
|
||||
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &[BindGroupLayoutEntry {
|
||||
|
@ -96,11 +98,11 @@ impl FromWorld for SpriteShaders {
|
|||
},
|
||||
],
|
||||
}],
|
||||
module: &shader_module,
|
||||
module: &shader_module_vert,
|
||||
entry_point: "vertex",
|
||||
},
|
||||
fragment: Some(FragmentState {
|
||||
module: &shader_module,
|
||||
module: &shader_module_frag,
|
||||
entry_point: "fragment",
|
||||
targets: &[ColorTargetState {
|
||||
format: TextureFormat::bevy_default(),
|
||||
|
|
11
pipelined/bevy_sprite2/src/render/sprite.frag
Normal file
11
pipelined/bevy_sprite2/src/render/sprite.frag
Normal file
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 v_Uv;
|
||||
layout(location = 0) out vec4 o_Target;
|
||||
|
||||
layout(set = 1, binding = 0) uniform texture2D sprite_texture;
|
||||
layout(set = 1, binding = 1) uniform sampler sprite_sampler;
|
||||
|
||||
void fragment() {
|
||||
o_Target = texture(sampler2D(sprite_texture, sprite_sampler), v_Uv);
|
||||
}
|
17
pipelined/bevy_sprite2/src/render/sprite.vert
Normal file
17
pipelined/bevy_sprite2/src/render/sprite.vert
Normal file
|
@ -0,0 +1,17 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 Vertex_Position;
|
||||
layout(location = 1) in vec2 Vertex_Uv;
|
||||
|
||||
layout(location = 0) out vec2 v_Uv;
|
||||
|
||||
layout(set = 0, binding = 0) uniform View {
|
||||
mat4 ViewProj;
|
||||
vec4 ViewWorldPosition;
|
||||
// vec3 ViewWorldPosition;
|
||||
};
|
||||
|
||||
void vertex() {
|
||||
v_Uv = Vertex_Uv;
|
||||
gl_Position = ViewProj * vec4(Vertex_Position, 1.0);
|
||||
}
|
Loading…
Reference in a new issue