2025-08-30 23:53:21 +00:00
|
|
|
//! A shader that uses the GLSL shading language.
|
|
|
|
|
|
|
|
|
|
use bevy::{
|
2025-08-31 00:05:01 +00:00
|
|
|
prelude::*,
|
|
|
|
|
reflect::TypePath,
|
|
|
|
|
render::render_resource::{AsBindGroup, ShaderRef},
|
2025-08-30 23:53:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// 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";
|
2025-08-30 20:48:38 +00:00
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
App::new()
|
2025-08-31 00:05:01 +00:00
|
|
|
.add_plugins(DefaultPlugins)
|
|
|
|
|
.add_plugins(MaterialPlugin::<CustomMaterial>::default())
|
2025-08-30 23:53:21 +00:00
|
|
|
.add_systems(Startup, setup)
|
2025-08-30 20:48:38 +00:00
|
|
|
.run();
|
|
|
|
|
}
|
2025-08-30 23:53:21 +00:00
|
|
|
|
2025-08-31 00:05:01 +00:00
|
|
|
/// set up a simple 2D-screen-like surface
|
2025-08-30 23:53:21 +00:00
|
|
|
fn setup(
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
|
|
|
mut materials: ResMut<Assets<CustomMaterial>>,
|
|
|
|
|
) {
|
2025-08-31 00:05:01 +00:00
|
|
|
// Fullscreen flat surface: use a very large, thin cuboid so it behaves like a plane
|
2025-08-30 23:53:21 +00:00
|
|
|
commands.spawn((
|
|
|
|
|
Mesh3d(meshes.add(Cuboid::default())),
|
|
|
|
|
MeshMaterial3d(materials.add(CustomMaterial {
|
2025-08-31 00:05:01 +00:00
|
|
|
color: LinearRgba::new(0.2, 0.6, 0.9, 1.0),
|
2025-08-30 23:53:21 +00:00
|
|
|
color_texture: None,
|
2025-08-31 00:05:01 +00:00
|
|
|
alpha_mode: AlphaMode::Opaque,
|
2025-08-30 23:53:21 +00:00
|
|
|
})),
|
2025-08-31 00:05:01 +00:00
|
|
|
// 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)),
|
2025-08-30 23:53:21 +00:00
|
|
|
));
|
|
|
|
|
|
2025-08-31 00:05:01 +00:00
|
|
|
// 2D camera so the scene renders as a flat screen
|
|
|
|
|
commands.spawn((Camera2d::default(), Transform::default()));
|
2025-08-30 23:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn fragment_shader() -> ShaderRef {
|
|
|
|
|
FRAGMENT_SHADER_ASSET_PATH.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn alpha_mode(&self) -> AlphaMode {
|
|
|
|
|
self.alpha_mode
|
|
|
|
|
}
|
|
|
|
|
}
|