wip
This commit is contained in:
parent
bc21beeb36
commit
abff3f5434
4 changed files with 58 additions and 63 deletions
|
|
@ -1,14 +0,0 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 v_uv;
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
layout(set = 0, binding = 0) uniform MaterialUniform {
|
||||
vec4 color;
|
||||
} material;
|
||||
|
||||
void main() {
|
||||
// simple uv-based gradient multiplied by uniform color
|
||||
vec3 grad = vec3(v_uv, 0.5);
|
||||
o_color = material.color * vec4(grad, 1.0);
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#version 450
|
||||
|
||||
// Minimal passthrough vertex shader for a fullscreen plane.
|
||||
layout(location = 0) in vec3 Vertex_Position;
|
||||
layout(location = 1) in vec2 Vertex_Uv;
|
||||
|
||||
layout(location = 0) out vec2 v_uv;
|
||||
|
||||
void main() {
|
||||
v_uv = Vertex_Uv;
|
||||
gl_Position = vec4(Vertex_Position, 1.0);
|
||||
}
|
||||
30
assets/shaders/default.wgsl
Normal file
30
assets/shaders/default.wgsl
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Simple UV gradient shader (vertex + fragment)
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) position: vec3<f32>,
|
||||
@location(1) uv: vec2<f32>,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) uv: vec2<f32>,
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
// assume incoming positions are in clip-space (vec3 with z, or model-transformed)
|
||||
out.clip_position = vec4<f32>(in.position, 1.0);
|
||||
out.uv = in.uv;
|
||||
return out;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
// very simple vertical gradient between two colors
|
||||
let bottom = vec3<f32>(1.0, 0.8, 0.2); // warm
|
||||
let top = vec3<f32>(0.2, 0.6, 1.0); // cool
|
||||
|
||||
let color = mix(bottom, top, in.uv.y);
|
||||
return vec4<f32>(color, 1.0);
|
||||
}
|
||||
65
src/main.rs
65
src/main.rs
|
|
@ -4,16 +4,18 @@ use bevy::{
|
|||
prelude::*,
|
||||
reflect::TypePath,
|
||||
render::render_resource::{AsBindGroup, ShaderRef},
|
||||
sprite::{AlphaMode2d, Material2d, Material2dPlugin},
|
||||
window::PrimaryWindow,
|
||||
};
|
||||
|
||||
/// This example uses shader source files from the assets subdirectory
|
||||
const VERTEX_SHADER_ASSET_PATH: &str = "shaders/custom_material.vert";
|
||||
const FRAGMENT_SHADER_ASSET_PATH: &str = "shaders/custom_material.frag";
|
||||
const SHADER_ASSET_PATH: &str = "shaders/default.wgsl";
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugins(MaterialPlugin::<CustomMaterial>::default())
|
||||
.add_plugins((
|
||||
DefaultPlugins,
|
||||
Material2dPlugin::<CustomMaterial>::default(),
|
||||
))
|
||||
.add_systems(Startup, setup)
|
||||
.run();
|
||||
}
|
||||
|
|
@ -23,47 +25,36 @@ fn setup(
|
|||
mut commands: Commands,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<CustomMaterial>>,
|
||||
primary_window: Single<&Window, With<PrimaryWindow>>,
|
||||
) {
|
||||
// Fullscreen flat surface: use a very large, thin cuboid so it behaves like a plane
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(CustomMaterial {
|
||||
color: LinearRgba::new(0.2, 0.6, 0.9, 1.0),
|
||||
color_texture: None,
|
||||
alpha_mode: AlphaMode::Opaque,
|
||||
})),
|
||||
// Scale X/Y large to cover the camera view, keep Z very small to make it effectively a plane
|
||||
Transform::from_scale(Vec3::new(2000.0, 2000.0, 0.01)),
|
||||
));
|
||||
// camera
|
||||
commands.spawn(Camera2d);
|
||||
|
||||
// 2D camera so the scene renders as a flat screen
|
||||
commands.spawn((Camera2d::default(), Transform::default()));
|
||||
// quad that fills the whole window
|
||||
let size = Vec2::new(
|
||||
primary_window.resolution.width(),
|
||||
primary_window.resolution.height(),
|
||||
);
|
||||
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(Rectangle::default())),
|
||||
MeshMaterial2d(materials.add(CustomMaterial {})),
|
||||
Transform::from_scale(Vec3::new(size.x, size.y, 1.0)),
|
||||
));
|
||||
}
|
||||
|
||||
// This is the struct that will be passed to your shader
|
||||
#[derive(Asset, TypePath, AsBindGroup, Clone)]
|
||||
struct CustomMaterial {
|
||||
#[uniform(0)]
|
||||
color: LinearRgba,
|
||||
#[texture(1)]
|
||||
#[sampler(2)]
|
||||
color_texture: Option<Handle<Image>>,
|
||||
alpha_mode: AlphaMode,
|
||||
}
|
||||
|
||||
/// The Material trait is very configurable, but comes with sensible defaults for all methods.
|
||||
/// You only need to implement functions for features that need non-default behavior. See the Material api docs for details!
|
||||
/// When using the GLSL shading language for your shader, the specialize method must be overridden.
|
||||
impl Material for CustomMaterial {
|
||||
fn vertex_shader() -> ShaderRef {
|
||||
VERTEX_SHADER_ASSET_PATH.into()
|
||||
}
|
||||
struct CustomMaterial {}
|
||||
|
||||
/// The Material2d trait is very configurable, but comes with sensible defaults for all methods.
|
||||
/// You only need to implement functions for features that need non-default behavior. See the Material2d api docs for details!
|
||||
impl Material2d for CustomMaterial {
|
||||
fn fragment_shader() -> ShaderRef {
|
||||
FRAGMENT_SHADER_ASSET_PATH.into()
|
||||
SHADER_ASSET_PATH.into()
|
||||
}
|
||||
|
||||
fn alpha_mode(&self) -> AlphaMode {
|
||||
self.alpha_mode
|
||||
fn alpha_mode(&self) -> AlphaMode2d {
|
||||
AlphaMode2d::Opaque
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue