diff --git a/assets/shaders/README.md b/assets/shaders/README.md new file mode 100644 index 0000000..7f9a18f --- /dev/null +++ b/assets/shaders/README.md @@ -0,0 +1,7 @@ +# Shaders Directory + +Contains WGSL shader source files compiled at runtime by wgpu. Each file defines vertex and fragment stages for a specific rendering pipeline. + +## Files + +- **basic_shader.wgsl** — Simple triangle shader used as a minimal example. Renders a solid red triangle using hardcoded positions computed entirely on the GPU side. diff --git a/assets/shaders/basic_shader.wgsl b/assets/shaders/basic_shader.wgsl index ff3f116..c6b3dd4 100644 --- a/assets/shaders/basic_shader.wgsl +++ b/assets/shaders/basic_shader.wgsl @@ -1,14 +1,20 @@ +//! # Basic Shader Module +struct VertexInput { + @location(0) position: vec3, +}; + +struct VertexOutput { + @builtin(position) clip_position: vec4, +}; + @vertex -pub fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4f { - var positions = array( - vec2f(0.0, 0.5), - vec2f(-0.5, -0.5), - vec2f(0.5, -0.5), - ); - return vec4f(positions[vertex_index], 0.0, 1.0); +fn vs_main(model: VertexInput) -> VertexOutput { + var out: VertexOutput; + out.clip_position = vec4(model.position, 1.0); + return out; } @fragment -pub fn fs_main() -> @location(0) vec4f { - return vec4f(1.0, 0.0, 0.0, 1.0); +fn fs_main() -> @location(0) vec4 { + return vec4(1.0, 0.5, 0.2, 1.0); // Couleur orange } diff --git a/lib/assets/shaders/basic_shader.wsgl b/lib/assets/shaders/basic_shader.wsgl deleted file mode 100644 index e69de29..0000000 diff --git a/lib/renderer.rs b/lib/renderer.rs index a8850aa..c5133b2 100644 --- a/lib/renderer.rs +++ b/lib/renderer.rs @@ -5,6 +5,9 @@ use crate::conf::BASIC_SHADER; +// On demande à Cargo de surveiller ce fichier (si le wsgl est modifié, mais pas la lib) +const _: &[u8] = include_bytes!("../assets/shaders/basic_shader.wgsl"); + /// Renders geometry using a fixed RenderPipeline. This struct owns heavy objects /// (RenderPipeline) compiled once at creation time, avoiding per-frame allocation. pub struct Renderer { @@ -19,10 +22,15 @@ impl Renderer { /// by the orchestrator (main.rs). The pipeline is compiled only here; subsequent calls are cheap. pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self { // In wgpu 30, ShaderModuleDescriptor fields changed: label is Option<&str> (not Some(label)), - // and source uses Cow<'_, str> instead of [u8]. include_str! + .into() converts &str → Cow. + // and source uses Cow<'_, str> instead of [u8]. + // BASIC_SHADER serves as both the debug label and the file path loaded at runtime + // (include_str!() requires a string literal, not a variable). + // See assets/shaders/basic_shader.wgsl for the WGSL source — defines vs_main + fs_main stages. + let shader_source = + std::fs::read_to_string(BASIC_SHADER).expect("Failed to read shader file"); let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some(BASIC_SHADER), - source: wgpu::ShaderSource::Wgsl(include_str!("../assets/shaders/basic_shader.wgsl").into()), + source: wgpu::ShaderSource::Wgsl(shader_source.into()), }); // push_constant_ranges → removed in wgpu 30; replaced by immediate_size for var support. @@ -98,4 +106,8 @@ impl Renderer { drop(render_pass); queue.submit(std::iter::once(encoder.finish())); } + // méthode utilitaire pour cacher le "bruit" + pub fn submit_commands(&self, queue: &wgpu::Queue, encoder: wgpu::CommandEncoder) { + queue.submit(std::iter::once(encoder.finish())); + } }