mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +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
|
# misc
|
||||||
wgpu = "0.9"
|
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"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
|
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
|
||||||
use bevy_reflect::{TypeUuid, Uuid};
|
use bevy_reflect::{TypeUuid, Uuid};
|
||||||
use bevy_utils::{tracing::error, BoxedFuture};
|
use bevy_utils::{tracing::error, BoxedFuture};
|
||||||
use naga::{valid::ModuleInfo, Module};
|
use naga::{valid::ModuleInfo, Module, ShaderStage};
|
||||||
use std::{borrow::Cow, marker::Copy};
|
use std::{borrow::Cow, collections::HashMap, marker::Copy};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wgpu::{ShaderFlags, ShaderModuleDescriptor, ShaderSource};
|
use wgpu::{ShaderFlags, ShaderModuleDescriptor, ShaderSource};
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ pub enum ShaderReflectError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
WgslParse(#[from] naga::front::wgsl::ParseError),
|
WgslParse(#[from] naga::front::wgsl::ParseError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
GlslParse(#[from] naga::front::glsl::ParseError),
|
||||||
|
#[error(transparent)]
|
||||||
SpirVParse(#[from] naga::front::spv::Error),
|
SpirVParse(#[from] naga::front::spv::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Validation(#[from] naga::valid::ValidationError),
|
Validation(#[from] naga::valid::ValidationError),
|
||||||
|
@ -31,6 +33,7 @@ pub enum ShaderReflectError {
|
||||||
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
|
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
|
||||||
pub enum Shader {
|
pub enum Shader {
|
||||||
Wgsl(Cow<'static, str>),
|
Wgsl(Cow<'static, str>),
|
||||||
|
Glsl(Cow<'static, str>),
|
||||||
SpirV(Vec<u8>),
|
SpirV(Vec<u8>),
|
||||||
// TODO: consider the following
|
// TODO: consider the following
|
||||||
// PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
|
// 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 {
|
impl Shader {
|
||||||
|
@ -60,6 +67,18 @@ impl Shader {
|
||||||
let module = match &self {
|
let module = match &self {
|
||||||
// TODO: process macros here
|
// TODO: process macros here
|
||||||
Shader::Wgsl(source) => naga::front::wgsl::parse_str(&source)?,
|
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(
|
Shader::SpirV(source) => naga::front::spv::parse_u8_slice(
|
||||||
&source,
|
&source,
|
||||||
&naga::front::spv::Options {
|
&naga::front::spv::Options {
|
||||||
|
@ -84,6 +103,10 @@ impl Shader {
|
||||||
Shader::Wgsl(source.into())
|
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 {
|
pub fn from_spirv(source: Vec<u8>) -> Shader {
|
||||||
Shader::SpirV(source)
|
Shader::SpirV(source)
|
||||||
}
|
}
|
||||||
|
@ -124,10 +147,15 @@ impl<'a> From<&'a Shader> for ShaderModuleDescriptor<'a> {
|
||||||
label: None,
|
label: None,
|
||||||
source: match shader {
|
source: match shader {
|
||||||
Shader::Wgsl(source) => ShaderSource::Wgsl(source.clone()),
|
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(_) => {
|
Shader::SpirV(_) => {
|
||||||
// TODO: we can probably just transmute the u8 array to u32?
|
// TODO: we can probably just transmute the u8 array to u32?
|
||||||
let x = shader.reflect().unwrap();
|
let reflection = shader.reflect().unwrap();
|
||||||
let spirv = x.get_spirv().unwrap();
|
let spirv = reflection.get_spirv().unwrap();
|
||||||
ShaderSource::SpirV(Cow::Owned(spirv))
|
ShaderSource::SpirV(Cow::Owned(spirv))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,8 +28,10 @@ pub struct SpriteShaders {
|
||||||
impl FromWorld for SpriteShaders {
|
impl FromWorld for SpriteShaders {
|
||||||
fn from_world(world: &mut World) -> Self {
|
fn from_world(world: &mut World) -> Self {
|
||||||
let render_device = world.get_resource::<RenderDevice>().unwrap();
|
let render_device = world.get_resource::<RenderDevice>().unwrap();
|
||||||
let shader = Shader::from_wgsl(include_str!("sprite.wgsl"));
|
let shader_vert = Shader::from_glsl(include_str!("sprite.vert"));
|
||||||
let shader_module = render_device.create_shader_module(&shader);
|
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 {
|
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
entries: &[BindGroupLayoutEntry {
|
entries: &[BindGroupLayoutEntry {
|
||||||
|
@ -96,11 +98,11 @@ impl FromWorld for SpriteShaders {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
module: &shader_module,
|
module: &shader_module_vert,
|
||||||
entry_point: "vertex",
|
entry_point: "vertex",
|
||||||
},
|
},
|
||||||
fragment: Some(FragmentState {
|
fragment: Some(FragmentState {
|
||||||
module: &shader_module,
|
module: &shader_module_frag,
|
||||||
entry_point: "fragment",
|
entry_point: "fragment",
|
||||||
targets: &[ColorTargetState {
|
targets: &[ColorTargetState {
|
||||||
format: TextureFormat::bevy_default(),
|
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