### compute_shader usage example Source: https://docs.rs/cuneus/0.6.2/cuneus/macro.compute_shader.html Example showing how to build a compute shader configuration and instantiate it using the macro. ```rust let config = ComputeShader::builder() .with_entry_point("main") .with_custom_uniforms::() .build(); let compute_shader = cuneus::compute_shader!(core, "shaders/my_shader.wgsl", config); ``` -------------------------------- ### Initialize and Start GPU Synthesis Source: https://docs.rs/cuneus/0.6.2/cuneus/gst/audio/struct.SynthesisManager.html Demonstrates initializing the SynthesisManager and starting GPU synthesis within a struct's init method. ```rust 13 fn init(core: &Core) -> Self { 14 // Create texture display layout - needed to show compute shader output on screen 15 // This layout defines how to bind the texture (binding 0) and sampler (binding 1) for rendering 16 let base = RenderKit::new(core); 17 18 // Multi-pass configuration: 19 // Pass 1 "effect": self-feedback for temporal trail 20 // Pass 2 "main_image": reads effect output, overlays text 21 let passes = vec![ 22 PassDescription::new("effect", &["effect"]), 23 PassDescription::new("main_image", &["effect"]), 24 ]; 25 26 let config = ComputeShader::builder() 27 .with_entry_point("effect") 28 .with_multi_pass(&passes) 29 .with_mouse() 30 .with_fonts() 31 .with_audio(1024) 32 .with_workgroup_size([16, 16, 1]) 33 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 34 .with_label("Debug Screen") 35 .build(); 36 37 let compute_shader = cuneus::compute_shader!(core, "shaders/debugscreen.wgsl", config); 38 39 // init audio synthesis system 40 let audio_synthesis = match SynthesisManager::new() { 41 Ok(mut synth) => { 42 if let Err(_e) = synth.start_gpu_synthesis() { 43 None 44 } else { 45 Some(synth) 46 } 47 } 48 Err(_e) => None}; 49 50 Self { 51 base, 52 compute_shader, 53 audio_synthesis, 54 generate_note: false} 55 } ``` -------------------------------- ### Initialize ExportManager Request in Lich Example Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.ExportManager.html Demonstrates the initial setup of export and control request objects within the render loop. ```rust 99 fn render(&mut self, core: &Core) -> Result<(), cuneus::SurfaceError> { 100 let mut frame = self.base.begin_frame(core)?; 101 102 let mut params = self.current_params; 103 let mut changed = false; 104 let mut should_start_export = false; 105 let mut export_request = self.base.export_manager.get_ui_request(); 106 let mut controls_request = self 107 .base 108 .controls 109 .get_ui_request(&self.base.start_time, &core.size, self.base.fps_tracker.fps()); 110 111 let full_output = if self.base.key_handler.show_ui { 112 self.base.render_ui(core, |ctx| { 113 RenderKit::apply_default_style(ctx); 114 115 egui::Window::new("Lich") 116 .collapsible(true) 117 .resizable(true) 118 .default_width(320.0) 119 .show(ctx, |ui| { 120 egui::CollapsingHeader::new("Parameters") 121 .default_open(true) 122 .show(ui, |ui| { ``` -------------------------------- ### Initialize and start PCM stream in Bugberman Source: https://docs.rs/cuneus/0.6.2/cuneus/gst/audio/struct.PcmStreamManager.html Demonstrates creating and starting a PCM stream within a game initialization context. ```rust let pcm_stream = match PcmStreamManager::new(Some(SAMPLE_RATE)) { Ok(mut stream) => match stream.start() { Ok(()) => Some(stream), Err(e) => { error!("Failed to start PCM stream: {e}"); None } }, Err(e) => { error!("Failed to create PCM stream: {e}"); None } }; ``` -------------------------------- ### Initialize and start PCM stream in Veridis Quo Source: https://docs.rs/cuneus/0.6.2/cuneus/gst/audio/struct.PcmStreamManager.html Shows an alternative pattern for starting the PCM stream with additional logging on success. ```rust let pcm_stream = match PcmStreamManager::new(Some(SAMPLE_RATE)) { Ok(mut stream) => { if let Err(e) = stream.start() { error!("Failed to start PCM stream: {e}"); None } else { info!("PCM audio stream started at {SAMPLE_RATE} Hz"); Some(stream) } } Err(e) => { error!("Failed to create PCM stream: {e}"); None } }; ``` -------------------------------- ### ShaderApp::run Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.ShaderApp.html Starts the application event loop and initializes the shader manager. ```APIDOC ## pub fn run(self, event_loop: EventLoop<()>, shader_creator: impl FnOnce(&Core) -> S + 'static) -> Result<(), Box> ### Description Runs the application event loop. It takes an event loop and a closure that initializes the shader manager using the application's core. ### Parameters - **event_loop** (EventLoop<()>) - Required - The event loop to run. - **shader_creator** (impl FnOnce(&Core) -> S) - Required - A closure that creates the shader manager. ``` -------------------------------- ### Initialize Media Panel UI Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.ShaderControls.html Setup for the media control panel within the egui window context. ```rust fn render(&mut self, core: &Core) -> Result<(), cuneus::SurfaceError> { let mut frame = self.base.begin_frame(core)?; // Handle UI and controls let mut params = self.current_params; let mut changed = false; let mut should_start_export = false; let mut export_request = self.base.export_manager.get_ui_request(); let mut controls_request = self .base .controls .get_ui_request(&self.base.start_time, &core.size, self.base.fps_tracker.fps()); let using_video_texture = self.base.using_video_texture; let using_hdri_texture = self.base.using_hdri_texture; let using_webcam_texture = self.base.using_webcam_texture; let video_info = self.base.get_video_info(); let hdri_info = self.base.get_hdri_info(); let webcam_info = self.base.get_webcam_info(); let full_output = if self.base.key_handler.show_ui { self.base.render_ui(core, |ctx| { RenderKit::apply_default_style(ctx); egui::Window::new("Particle Splatting") .collapsible(true) .resizable(true) .default_width(250.0) .show(ctx, |ui| { ShaderControls::render_media_panel( ui, &mut controls_request, using_video_texture, video_info, ``` -------------------------------- ### Configure and Initialize Compute Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Examples demonstrating the builder pattern for setting up various compute shader types. ```rust let initial_params = AudioVisParams::default(); let base = RenderKit::new(core); let config = ComputeShader::builder() .with_entry_point("main") .with_custom_uniforms::() .with_audio_spectrum(69) // 64 spectrum + BPM + 4 energy values .with_workgroup_size([16, 16, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("Audio Visualizer Compute") .build(); let compute_shader = cuneus::compute_shader!(core, "shaders/audiovis.wgsl", config); // Initialize custom uniform with initial parameters compute_shader.set_custom_params(initial_params, &core.queue); Self { base, compute_shader, current_params: initial_params, } } ``` ```rust fn init(core: &Core) -> Self { let initial_params = VolumeParams { speed: 1.0, intensity: 0.001, color1_r: 0.1, color1_g: 0.3, color1_b: 0.7, color2_r: 0.8, color2_g: 0.4, color2_b: 0.2, color3_r: 1.0, color3_g: 1.0, color3_b: 1.0, gamma: 0.8, zoom: 1.0, _padding1: 0.0, _padding2: 0.0, _padding3: 0.0}; let base = RenderKit::new(core); let config = ComputeShader::builder() .with_entry_point("main") .with_custom_uniforms::() .with_workgroup_size([8, 8, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("Volume Passage Unified") .build(); let compute_shader = cuneus::compute_shader!(core, "shaders/volumepassage.wgsl", config); compute_shader.set_custom_params(initial_params, &core.queue); Self { base, compute_shader, current_params: initial_params} } ``` ```rust fn init(core: &Core) -> Self { let base = RenderKit::new(core); let initial_params = CliffordParams { a: -2.0, b: -2.0, c: -1.2, d: 2.0, motion_speed: 1.0, rotation_x: 0.0, rotation_y: 0.0, brightness: 2.5, scale: 0.6, dof_amount: 0.2, dof_focal_dist: 0.5, dispersion: 0.25, warp: 3.0, _pad3: 0.0, wl_center: 550.0, wl_spread: 300.0, symmetry: 0.15, _pad0: 0.0, _pad1: 0.0, _pad2: 0.0, }; let mut config = ComputeShader::builder() .with_entry_point("Splat") .with_custom_uniforms::() .with_atomic_buffer(3) .with_workgroup_size([16, 16, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("Clifford Attractor Unified") .build(); config.entry_points.push("main_image".to_string()); let compute_shader = cuneus::compute_shader!(core, "shaders/cliffordcompute.wgsl", config); compute_shader.set_custom_params(initial_params, &core.queue); Self { base, compute_shader, current_params: initial_params} } ``` ```rust fn init(core: &Core) -> Self { let initial_params = LegoParams { brick_scale: 0.01, lightdir_x: 0.8, lightdir_y: 0.6, grain: 0.04, gamma: 0.4, shadow_str: 0.5, shadow_dist: 1.25, ao_str: 0.85, spec_pow: 12.0, spec_str: 0.3, edge_enh: 0.15, stud_h: 0.045, base_h: 0.2, rim_str: 0.5, res_scale_mult: 0.2, stud_h_mult: 1.0, light_r: 0.8, light_g: 0.75, light_b: 0.7, depth_scale: 0.85, edge_blend: 0.3, _pad: 0.0, _pad2: 0.0, _pad3: 0.0}; let base = RenderKit::new(core); let config = ComputeShader::builder() .with_entry_point("main_image") .with_channels(1) .with_custom_uniforms::() .with_workgroup_size([16, 16, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("LEGO Effect") .build(); let compute_shader = cuneus::compute_shader!(core, "shaders/lego.wgsl", config); compute_shader.set_custom_params(initial_params, &core.queue); ``` -------------------------------- ### Initialize and Run ShaderApp Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.ShaderApp.html Demonstrates creating a new ShaderApp instance and starting the application loop with a shader manager. ```rust 212fn main() -> Result<(), Box> { 213 let (app, event_loop) = ShaderApp::new("EMNIST", 800, 600); 214 215 app.run(event_loop, CNNDigitRecognizer::init) 216} ``` ```rust 46fn main() -> Result<(), Box> { 47 env_logger::init(); 48 let (app, event_loop) = ShaderApp::new("cuneus", 800, 600); 49 app.run(event_loop, Shader::init) 50} ``` ```rust 287fn main() -> Result<(), Box> { 288 env_logger::init(); 289 let (app, event_loop) = ShaderApp::new("JFA", 800, 600); 290 291 app.run(event_loop, JfaShader::init) 292} ``` ```rust 63fn main() -> Result<(), Box> { 64 env_logger::init(); 65 let (app, event_loop) = ShaderApp::new("GGXbrot", 800, 600); 66 app.run(event_loop, Shader::init) 67} ``` ```rust 327fn main() -> Result<(), Box> { 328 env_logger::init(); 329 let (app, event_loop) = ShaderApp::new("universe", 800, 600); 330 app.run(event_loop, NebulaShader::init) 331} ``` ```rust 198fn main() -> Result<(), Box> { 199 env_logger::init(); 200 let (app, event_loop) = ShaderApp::new("Lich Lightning", 800, 600); 201 app.run(event_loop, LichShader::init) 202} ``` -------------------------------- ### Initialize Lego Shader Configuration Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Partial configuration example for a Lego-style shader using custom parameters and texture channels. ```rust 38 fn init(core: &Core) -> Self { 39 let initial_params = LegoParams { 40 brick_scale: 0.01, 41 lightdir_x: 0.8, 42 lightdir_y: 0.6, 43 grain: 0.04, 44 gamma: 0.4, 45 shadow_str: 0.5, 46 shadow_dist: 1.25, 47 ao_str: 0.85, 48 spec_pow: 12.0, 49 spec_str: 0.3, 50 edge_enh: 0.15, 51 stud_h: 0.045, 52 base_h: 0.2, 53 rim_str: 0.5, 54 res_scale_mult: 0.2, 55 stud_h_mult: 1.0, 56 light_r: 0.8, 57 light_g: 0.75, 58 light_b: 0.7, 59 depth_scale: 0.85, 60 edge_blend: 0.3, 61 _pad: 0.0, 62 _pad2: 0.0, 63 _pad3: 0.0}; 64 let base = RenderKit::new(core); 65 66 let config = ComputeShader::builder() 67 .with_entry_point("main_image") 68 .with_channels(1) ``` -------------------------------- ### Configure Multi-Pass Pipeline Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of setting up a multi-pass compute pipeline using PassDescription. ```rust 111 fn init(core: &Core) -> Self { 112 let base = RenderKit::new(core); 113 let initial_params = ExperimentParams::default(); 114 115 let passes = vec![ 116 PassDescription::new("accumulate", &["accumulate"]), ``` -------------------------------- ### Partial Struct Initialization Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of initializing a struct containing a compute shader. ```rust 132 Self { 133 base, 134 compute_shader, 135 current_params: initial_params, 136 should_reset_accumulation: true, 137 } 138 } ``` -------------------------------- ### Pod derive examples Source: https://docs.rs/cuneus/0.6.2/cuneus/derive.Pod.html Examples of structs deriving Pod with repr(C) and repr(transparent) attributes. ```rust #[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] struct Test { a: u16, b: u16, } #[derive(Copy, Clone, Pod, Zeroable)] #[repr(transparent)] struct Generic { a: A, b: PhantomData, } ``` -------------------------------- ### Configure a Compute Shader Pipeline Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html A basic example showing how to initialize a ComputeShaderBuilder with multi-pass configuration, custom uniforms, and input resources. ```rust let config = ComputeShader::builder() .with_multi_pass(&passes) .with_custom_uniforms::() .with_mouse() .with_channels(1) .build(); ``` -------------------------------- ### Configure a Multi-Pass Compute Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of setting up a multi-pass pipeline using PassDescription and ComputeShaderBuilder. ```rust 35 fn init(core: &Core) -> Self { 36 let initial_params = KuwaharaParams { 37 radius: 5.0, 38 q: 1.5, 39 alpha: 4.0, 40 filter_strength: 0.8, 41 sigma_d: 0.8, 42 sigma_r: 1.2, 43 edge_threshold: 0.2, 44 color_enhance: 1.0, 45 blur_samples: 15.0, 46 blur_lod: 2.0, 47 blur_slod: 4.0, 48 filter_mode: 1, 49 show_tensors: 0, 50 lic_length: 15.0, 51 lic_strength: 0.5, 52 lic_width: 1.5}; 53 let base = RenderKit::new(core); 54 55 let passes = vec![ 56 PassDescription::new("structure_tensor", &[]), 57 PassDescription::new("tensor_field", &["structure_tensor"]), 58 PassDescription::new("kuwahara_filter", &["tensor_field"]), 59 PassDescription::new("lic_edges", &["tensor_field", "kuwahara_filter"]) 60 .with_resolution_scale(0.5), 61 PassDescription::new("main_image", &["lic_edges"]), 62 ]; 63 64 let config = ComputeShader::builder() 65 .with_entry_point("structure_tensor") 66 .with_multi_pass(&passes) 67 .with_custom_uniforms::() 68 .with_workgroup_size([16, 16, 1]) 69 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 70 .with_channels(2) 71 .with_label("Kuwahara Multi-Pass") 72 .build(); 73 74 let compute_shader = cuneus::compute_shader!(core, "shaders/kuwahara.wgsl", config); 75 76 compute_shader.set_custom_params(initial_params, &core.queue); 77 78 Self { 79 base, 80 compute_shader, 81 current_params: initial_params} ``` -------------------------------- ### Zeroable Custom Bounds Examples Source: https://docs.rs/cuneus/0.6.2/cuneus/derive.Zeroable.html Examples demonstrating the use of custom bounds and perfect derive semantics for generic types. ```rust #[derive(Clone, Zeroable)] #[zeroable(bound = "")] struct AlwaysZeroable { a: PhantomData, } AlwaysZeroable::::zeroed(); ``` ```rust #[derive(Copy, Clone, Zeroable)] #[repr(u8)] #[zeroable(bound = "")] enum MyOption { None, Some(T), } assert!(matches!(MyOption::::zeroed(), MyOption::None)); ``` ```rust #[derive(Clone, Zeroable)] #[zeroable(bound = "T: Copy")] struct ZeroableWhenTIsCopy { a: PhantomData, } ZeroableWhenTIsCopy::::zeroed(); ``` ```rust #[derive(Clone, Zeroable)] #[zeroable(bound = "")] struct ZeroableWhenTIsZeroable { a: T, } ZeroableWhenTIsZeroable::::zeroed(); ``` ```rust ZeroableWhenTIsZeroable::::zeroed(); ``` -------------------------------- ### Configure and Initialize Compute Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Examples of using the ComputeShaderBuilder to define shader parameters and initialize the compute shader instance. ```rust 68 .with_channels(1) 69 .with_custom_uniforms::() 70 .with_workgroup_size([16, 16, 1]) 71 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 72 .with_label("LEGO Effect") 73 .build(); 74 75 let compute_shader = cuneus::compute_shader!(core, "shaders/lego.wgsl", config); 76 77 compute_shader.set_custom_params(initial_params, &core.queue); 78 79 Self { 80 base, 81 compute_shader, 82 current_params: initial_params} 83 } ``` ```rust 37 fn init(core: &Core) -> Self { 38 let base = RenderKit::new(core); 39 40 let passes = vec![ 41 PassDescription::new("lightning", &[]), 42 PassDescription::new("feedback", &["lightning", "feedback"]), 43 PassDescription::new("main_image", &["feedback"]), 44 ]; 45 46 let config = ComputeShader::builder() 47 .with_multi_pass(&passes) 48 .with_custom_uniforms::() 49 .with_workgroup_size([16, 16, 1]) 50 .with_texture_format(cuneus::compute::COMPUTE_TEXTURE_FORMAT_RGBA16) 51 .with_label("Lich Lightning") 52 .build(); 53 54 let compute_shader = cuneus::compute_shader!(core, "shaders/lich.wgsl", config); 55 56 let initial_params = LichParams { 57 cloud_density: 3.0, 58 lightning_intensity: 1.2, 59 branch_count: 1.0, 60 feedback_decay: 0.94, 61 base_color: [0.25, 0.55, 1.0], 62 glow_intensity: 1.5, 63 specular_strength: 1.2, 64 contrast: 1.8, 65 gamma: 1.0, 66 saturation: 1.4, 67 color_shift: 12.0, 68 spectrum_mix: 0.4, 69 light_intensity: 1.6, 70 _pad: 0.0, 71 }; 72 73 // Initialize custom uniform with initial parameters 74 compute_shader.set_custom_params(initial_params, &core.queue); 75 76 Self { 77 base, 78 compute_shader, 79 current_params: initial_params, 80 } 81 } ``` ```rust 42 fn init(core: &Core) -> Self { 43 let initial_params = AudioVisParams::default(); 44 let base = RenderKit::new(core); 45 46 let config = ComputeShader::builder() 47 .with_entry_point("main") 48 .with_custom_uniforms::() 49 .with_audio_spectrum(69) // 64 spectrum + BPM + 4 energy values 50 .with_workgroup_size([16, 16, 1]) 51 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 52 .with_label("Audio Visualizer Compute") 53 .build(); 54 55 let compute_shader = cuneus::compute_shader!(core, "shaders/audiovis.wgsl", config); 56 57 58 // Initialize custom uniform with initial parameters 59 compute_shader.set_custom_params(initial_params, &core.queue); 60 61 Self { 62 base, 63 compute_shader, 64 current_params: initial_params, 65 } 66 } ``` ```rust 111 fn init(core: &Core) -> Self { 112 let base = RenderKit::new(core); 113 let initial_params = ExperimentParams::default(); 114 115 let passes = vec![ 116 PassDescription::new("accumulate", &["accumulate"]), 117 PassDescription::new("main_image", &["accumulate"]), 118 ]; 119 120 let config = ComputeShader::builder() 121 .with_multi_pass(&passes) 122 .with_custom_uniforms::() 123 .with_channels(1) 124 .with_workgroup_size([16, 16, 1]) 125 .with_texture_format(cuneus::compute::COMPUTE_TEXTURE_FORMAT_RGBA16) 126 .with_label("Currents Path Tracer") 127 .build(); 128 129 let compute_shader = cuneus::compute_shader!(core, "shaders/tameimp.wgsl", config); 130 compute_shader.set_custom_params(initial_params, &core.queue); ``` -------------------------------- ### Initialize Compute Shader with Uniforms Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of configuring a compute shader with custom uniform parameters and specific workgroup settings. ```rust 79 Self { 80 base, 81 compute_shader, 82 current_params: initial_params} 83 } ``` ```rust 44 fn init(core: &Core) -> Self { 45 // Create texture bind group layout for displaying compute shader output 46 let base = RenderKit::new(core); 47 48 let initial_params = SinhParams { 49 aa: 2, 50 camera_x: 0.1, 51 camera_y: 10.0, 52 camera_z: 10.0, 53 orbit_speed: 0.3, 54 magic_number: 36.0, 55 cv_min: 2.197, 56 cv_max: 2.99225, 57 os_base: 0.00004, 58 os_scale: 0.02040101, 59 base_color_r: 0.5, 60 base_color_g: 0.25, 61 base_color_b: 0.05, 62 light_color_r: 0.8, 63 light_color_g: 1.0, 64 light_color_b: 0.3, 65 ambient_r: 1.2, 66 ambient_g: 1.0, 67 ambient_b: 0.8, 68 gamma: 0.4, 69 iterations: 65, 70 bound: 12.25, 71 fractal_scale: 0.05, 72 vignette_offset: 0.0}; 73 74 let config = ComputeShader::builder() 75 .with_entry_point("main") 76 .with_custom_uniforms::() 77 .with_workgroup_size([16, 16, 1]) 78 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 79 .with_label("Sinh Unified") 80 .build(); 81 82 let compute_shader = cuneus::compute_shader!(core, "shaders/sinh.wgsl", config); 83 84 85 compute_shader.set_custom_params(initial_params, &core.queue); 86 87 Self { 88 base, 89 compute_shader, 90 current_params: initial_params} 91 } ``` ```rust 47 fn init(core: &Core) -> Self { 48 let base = RenderKit::new(core); 49 50 let initial_params = BuddhabrotParams { 51 max_iterations: 500, 52 escape_radius: 4.0, 53 zoom: 0.5, 54 offset_x: -0.5, 55 offset_y: 0.0, 56 rotation: 1.55, 57 exposure: 6.5, 58 sample_density: 0.5, 59 motion_speed: 0.0, 60 dithering: 0.2, 61 wavelength_min: 485.0, 62 wavelength_max: 660.0, 63 gamma: 0.6, 64 saturation: 1.2, 65 color_shift: 1.1, 66 intensity_scale: 5.0, 67 white_balance_r: 1.2, 68 white_balance_g: 1.0, 69 white_balance_b: 1.08, 70 min_trajectory_len: 20, 71 }; 72 73 let mut config = ComputeShader::builder() 74 .with_entry_point("Splat") 75 .with_custom_uniforms::() 76 .with_atomic_buffer(3) 77 .with_workgroup_size([16, 16, 1]) 78 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 79 .with_label("Spectral Buddhabrot") 80 .build(); 81 82 config.entry_points.push("main_image".to_string()); 83 84 let compute_shader = cuneus::compute_shader!(core, "shaders/buddhabrot.wgsl", config); 85 compute_shader.set_custom_params(initial_params, &core.queue); 86 87 Self { 88 base, 89 compute_shader, 90 frame_count: 0, 91 accumulated_rendering: false, 92 current_params: initial_params, 93 } 94 } ``` -------------------------------- ### Configure a Gaussian Preprocess Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of building a compute shader with a specific entry point and multiple storage buffers for Gaussian preprocessing. ```rust let config = ComputeShaderBuilder::new() .with_label("Gaussian Preprocess") .with_entry_point("preprocess") .with_custom_uniforms::() .with_workgroup_size([256, 1, 1]) .with_storage_buffer(StorageBufferSpec::new("gaussians", gaussian_size)) .with_storage_buffer(StorageBufferSpec::new("gaussian_2d", gaussian_2d_size)) .with_storage_buffer(StorageBufferSpec::new("depth_keys", keys_size)) .with_storage_buffer(StorageBufferSpec::new("sorted_indices", indices_size)) .with_storage_buffer(StorageBufferSpec::new("camera", camera_size)) .build(); let preprocess = cuneus::compute_shader!(core, "shaders/gaussian3d.wgsl", config); ``` -------------------------------- ### Handle Input with Core Window Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.Core.html Examples of using the core.window() method within input handling logic for various applications. ```rust 199 fn handle_input(&mut self, core: &Core, event: &WindowEvent) -> bool { 200 if self.base.forward_to_egui(core, event) { 201 return true; 202 } 203 204 if let WindowEvent::KeyboardInput { event, .. } = event { 205 if event.state == winit::event::ElementState::Pressed { 206 if let winit::keyboard::Key::Character(ref s) = event.logical_key { 207 if s.as_str() == "r" || s.as_str() == "R" { 208 self.base.start_time = std::time::Instant::now(); 209 // Reset audio stream 210 if let Some(ref mut stream) = self.pcm_stream { 211 let _ = stream.stop(); 212 let _ = stream.start(); 213 } 214 return true; 215 } 216 } 217 } 218 return self 219 .base 220 .key_handler 221 .handle_keyboard_input(core.window(), event); 222 } 223 224 false 225 } ``` ```rust 187 fn handle_input(&mut self, core: &Core, event: &WindowEvent) -> bool { 188 let _ui_handled = self.base.forward_to_egui(core, event); 189 190 if let WindowEvent::KeyboardInput { event, .. } = event { 191 if let winit::keyboard::PhysicalKey::Code(key_code) = event.physical_key { 192 match key_code { 193 KeyCode::ArrowUp | KeyCode::ArrowDown | KeyCode::ArrowLeft | KeyCode::ArrowRight 194 | KeyCode::KeyW | KeyCode::KeyA | KeyCode::KeyS | KeyCode::KeyD 195 | KeyCode::Space => { 196 match event.state { 197 ElementState::Pressed => { self.held_keys.insert(key_code); } 198 ElementState::Released => { self.held_keys.remove(&key_code); } 199 } 200 return true; 201 } 202 _ => {} 203 } 204 } 205 return self 206 .base 207 .key_handler 208 .handle_keyboard_input(core.window(), event); 209 } 210 211 false 212 } ``` ```rust 214 fn handle_input(&mut self, core: &Core, event: &WindowEvent) -> bool { 215 let ui_handled = self.base.forward_to_egui(core, event); 216 217 if let WindowEvent::MouseWheel { delta, .. } = event { 218 if !ui_handled { 219 let dy = match delta { 220 winit::event::MouseScrollDelta::LineDelta(_, y) => *y, 221 winit::event::MouseScrollDelta::PixelDelta(p) => p.y as f32 / 40.0, 222 }; 223 self.game.camera_scale = (self.game.camera_scale + dy * 5.0).clamp(20.0, 200.0); 224 } 225 return true; 226 } 227 228 if self.base.handle_mouse_input(core, event, ui_handled) { 229 return true; 230 } 231 232 if let WindowEvent::KeyboardInput { event, .. } = event { 233 if let winit::keyboard::PhysicalKey::Code(key_code) = event.physical_key { 234 // Track held state for camera keys; movement is applied per-frame in update(). 235 match key_code { 236 KeyCode::KeyQ | KeyCode::KeyE | KeyCode::KeyW | KeyCode::KeyS => { 237 match event.state { 238 ElementState::Pressed => { self.held_keys.insert(key_code); } 239 ElementState::Released => { self.held_keys.remove(&key_code); } 240 } 241 return true; 242 } 243 _ => {} 244 } 245 } 246 return self 247 .base 248 .key_handler 249 .handle_keyboard_input(core.window(), event); 250 } 251 252 false 253 } ``` -------------------------------- ### Partial Compute Shader Builder Configuration Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Shows the start of a builder configuration chain. ```rust 66 let config = ComputeShader::builder() 67 .with_entry_point("main_image") ``` -------------------------------- ### Initialize ComputeShaderBuilder for Multi-Pass Setup Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Configures a compute shader using multiple pass descriptions. ```rust 37 fn init(core: &Core) -> Self { 38 let base = RenderKit::new(core); 39 40 let passes = vec![ 41 PassDescription::new("lightning", &[]), 42 PassDescription::new("feedback", &["lightning", "feedback"]), 43 PassDescription::new("main_image", &["feedback"]), 44 ]; 45 46 let config = ComputeShader::builder() 47 .with_multi_pass(&passes) 48 .with_custom_uniforms::() 49 .with_workgroup_size([16, 16, 1]) 50 .with_texture_format(cuneus::compute::COMPUTE_TEXTURE_FORMAT_RGBA16) ``` -------------------------------- ### Initialize Color Palette Section Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.MouseTracker.html Starts a new collapsible header for the Color Palette section. ```rust egui::CollapsingHeader::new("Color Palette") .default_open(false) .show(ui, |ui| { ui.horizontal(|ui| { ``` -------------------------------- ### Initialize StorageBufferSpec in ComputeShader Builder Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.StorageBufferSpec.html Examples of using StorageBufferSpec::new within a ComputeShader builder configuration. ```rust .with_storage_buffer(StorageBufferSpec::new( "atomic_buffer", (core.size.width * core.size.height * 3 * 4) as u64, )) // 3 channels * u32 per pixel ``` ```rust .with_storage_buffer(StorageBufferSpec::new( "atomic_buffer", (core.size.width * core.size.height * 4 * 4) as u64, )) ``` -------------------------------- ### Start Export Process Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.ExportManager.html Initiates the export process based on the state returned by the UI widget. ```rust if should_start_export { self.base.export_manager.start_export(); } ``` -------------------------------- ### Initialize Render Frame Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.UniformBinding.html Starts the rendering frame process using the provided core context. ```rust 110 fn render(&mut self, core: &Core) -> Result<(), cuneus::SurfaceError> { 111 let mut frame = self.base.begin_frame(core)?; ``` -------------------------------- ### Configure a Compute Shader with Unified Parameters Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of configuring a compute shader with custom uniforms, atomic buffers, and multiple entry points. ```rust let mut config = ComputeShader::builder() .with_entry_point("Splat") .with_custom_uniforms::() .with_atomic_buffer(3) .with_workgroup_size([16, 16, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("Clifford Attractor Unified") .build(); config.entry_points.push("main_image".to_string()); let compute_shader = cuneus::compute_shader!(core, "shaders/cliffordcompute.wgsl", config); compute_shader.set_custom_params(initial_params, &core.queue); ``` -------------------------------- ### Render Loop with UI Parameters Source: https://docs.rs/cuneus/0.6.2/cuneus/struct.UniformBinding.html Example of a render loop using egui to modify parameters that would typically be bound to uniforms. ```rust fn render(&mut self, core: &Core) -> Result<(), cuneus::SurfaceError> { let mut frame = self.base.begin_frame(core)?; let mut params = self.current_params; let mut changed = false; let mut should_start_export = false; let mut export_request = self.base.export_manager.get_ui_request(); let mut controls_request = self.base.controls.get_ui_request( &self.base.start_time, &core.size, self.base.fps_tracker.fps(), ); let full_output = if self.base.key_handler.show_ui { self.base.render_ui(core, |ctx| { RenderKit::apply_default_style(ctx); egui::Window::new("Schwarzschild") .collapsible(true) .resizable(true) .default_width(330.0) .show(ctx, |ui| { egui::CollapsingHeader::new("Camera").default_open(true).show(ui, |ui| { ui.label("Position:"); changed |= ui.add(egui::Slider::new(&mut params.cam_x, -50.0..=50.0).text("X")).changed(); changed |= ui.add(egui::Slider::new(&mut params.cam_y, -50.0..=50.0).text("Y")).changed(); changed |= ui.add(egui::Slider::new(&mut params.cam_z, -50.0..=50.0).text("Z")).changed(); ui.separator(); ui.label("Orientation:"); changed |= ui.add(egui::Slider::new(&mut params.cam_pitch, -3.14..=3.14).text("Pitch")).changed(); changed |= ui.add(egui::Slider::new(&mut params.cam_yaw, -3.14..=3.14).text("Yaw")).changed(); changed |= ui.add(egui::Slider::new(&mut params.cam_roll, -3.14..=3.14).text("Roll")).changed(); changed |= ui.add(egui::Slider::new(&mut params.fov, 15.0..=90.0).text("FOV")).changed(); changed |= ui.add(egui::Slider::new(&mut params.taa_weight, 0.0..=0.95).text("TAA")).changed(); }); egui::CollapsingHeader::new("Disk").default_open(true).show(ui, |ui| { changed |= ui.add(egui::Slider::new(&mut params.disk_inner, 1.5..=8.0).text("Inner")).changed(); changed |= ui.add(egui::Slider::new(&mut params.disk_outer, 5.0..=40.0).text("Outer")).changed(); changed |= ui.add(egui::Slider::new(&mut params.disk_thickness, 0.05..=2.0).text("Thickness")).changed(); ``` -------------------------------- ### Configure a Single-Pass Compute Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of building a simple compute shader configuration with custom uniforms and workgroup size. ```rust 69 .with_custom_uniforms::() 70 .with_workgroup_size([16, 16, 1]) 71 .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) 72 .with_label("LEGO Effect") 73 .build(); 74 75 let compute_shader = cuneus::compute_shader!(core, "shaders/lego.wgsl", config); 76 77 compute_shader.set_custom_params(initial_params, &core.queue); 78 79 Self { 80 base, 81 compute_shader, 82 current_params: initial_params} ``` -------------------------------- ### Configure FFT Compute Shader Source: https://docs.rs/cuneus/0.6.2/cuneus/compute/builder/struct.ComputeShaderBuilder.html Example of building a multi-pass compute shader for FFT processing with custom uniforms and storage buffers. ```rust let config = ComputeShader::builder() .with_entry_point("initialize_data") // Start with data initialization .with_multi_pass(&passes) .with_input_texture() // Re-enable input texture support .with_custom_uniforms::() .with_storage_buffer(StorageBufferSpec::new("image_data", 2048 * 2048 * 3 * 8)) // FFT working memory: max res to avoid crash .with_workgroup_size([16, 16, 1]) .with_texture_format(COMPUTE_TEXTURE_FORMAT_RGBA16) .with_label("FFT Multi-Pass") .build(); let compute_shader = cuneus::compute_shader!(core, "shaders/fft.wgsl", config); // Initialize custom uniform with initial parameters compute_shader.set_custom_params(initial_params, &core.queue); ``` -------------------------------- ### Loading and Processing GaussianCloud Source: https://docs.rs/cuneus/0.6.2/cuneus/ply/struct.GaussianCloud.html Example demonstrating how to load a PLY file into a GaussianCloud and upload its byte data to GPU buffers. ```rust fn load_ply(&mut self, core: &Core, path: &std::path::Path) { info!("Loading: {:?}", path); match GaussianCloud::from_ply(path) { Ok(cloud) => { let count = cloud.metadata.num_gaussians.min(MAX_GAUSSIANS); info!("Loaded {} Gaussians", count); let bytes = cloud.as_bytes(); let size = (count as usize * 64).min(bytes.len()); core.queue.write_buffer(&self.preprocess.storage_buffers[0], 0, &bytes[..size]); self.params.num_gaussians = count; self.sync_params(core); self.sorter.prepare_with_buffers( &core.device, &self.preprocess.storage_buffers[2], &self.preprocess.storage_buffers[3], count, ); self.render_bind_group = Some(self.renderer.create_bind_group( &core.device, &self.params_buffer, &self.camera_buffer, &self.preprocess.storage_buffers[1], &self.preprocess.storage_buffers[3], )); self.sorter.force_sort(); self.camera.reset(); } Err(e) => error!("Load error: {:?}", e)} } ```