@@ -238,6 +238,16 @@ pub struct VulkanEngine<'a> {
238238 ferrofluidsim_compute_pipeline : wgpu:: ComputePipeline ,
239239 ferrofluidsim_clear_pipeline : wgpu:: ComputePipeline ,
240240 ferrofluidsim_bind_group : wgpu:: BindGroup ,
241+
242+ // GPU compute bioluminescent waves simulation
243+ #[ allow( dead_code) ]
244+ biolum_particles_buffer : wgpu:: Buffer ,
245+ biolum_compute_pipeline : wgpu:: ComputePipeline ,
246+ biolum_compute_bind_group : wgpu:: BindGroup ,
247+ biolum_render_bind_group : wgpu:: BindGroup ,
248+ #[ allow( dead_code) ]
249+ biolum_render_pipeline_layout : wgpu:: PipelineLayout ,
250+
241251 #[ allow( dead_code) ]
242252 pub start_time : std:: time:: Instant ,
243253
@@ -642,6 +652,33 @@ impl<'a> VulkanEngine<'a> {
642652 immediate_size : 0 ,
643653 } ) ;
644654
655+ let biolum_render_bind_group_layout = device. create_bind_group_layout ( & wgpu:: BindGroupLayoutDescriptor {
656+ label : Some ( "Biolum Render Layout" ) ,
657+ entries : & [
658+ wgpu:: BindGroupLayoutEntry {
659+ binding : 0 ,
660+ visibility : wgpu:: ShaderStages :: VERTEX | wgpu:: ShaderStages :: FRAGMENT ,
661+ ty : wgpu:: BindingType :: Buffer {
662+ ty : wgpu:: BufferBindingType :: Storage { read_only : true } ,
663+ has_dynamic_offset : false ,
664+ min_binding_size : None ,
665+ } ,
666+ count : None ,
667+ } ,
668+ ] ,
669+ } ) ;
670+
671+ let biolum_render_pipeline_layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
672+ label : Some ( "Biolum Render Pipeline Layout" ) ,
673+ bind_group_layouts : & [
674+ Some ( & bind_group_layout) ,
675+ Some ( & smoke_render_layout) ,
676+ Some ( & camera_bind_group_layout) ,
677+ Some ( & biolum_render_bind_group_layout) ,
678+ ] ,
679+ immediate_size : 0 ,
680+ } ) ;
681+
645682 // Shared shader headers — included at compile time, resolved via simple string replacement.
646683 // This is the single source of truth for AudioUniforms layout and glyph font.
647684 const SHADER_COMMON : & str = include_str ! ( "shaders/_common.wgsl" ) ;
@@ -674,6 +711,7 @@ impl<'a> VulkanEngine<'a> {
674711 16 => include_str ! ( "shaders/vis_synthwaveracer.wgsl" ) ,
675712 17 => include_str ! ( "shaders/vis_cuboids.wgsl" ) ,
676713 18 => include_str ! ( "shaders/vis_vumeters.wgsl" ) ,
714+ 19 => include_str ! ( "shaders/vis_bioluminescence.wgsl" ) ,
677715 _ => include_str ! ( "shaders/vis_spectrum.wgsl" ) ,
678716 }
679717 } ;
@@ -744,23 +782,9 @@ impl<'a> VulkanEngine<'a> {
744782 source : wgpu:: ShaderSource :: Wgsl ( std:: borrow:: Cow :: Borrowed ( source. as_str ( ) ) ) ,
745783 } ) ;
746784
747- let ( layout, vertex_buffers, primitive, vs_entry) = match vis_def. pipeline_type {
748- crate :: state:: PipelineType :: FullscreenQuad => (
749- & render_pipeline_layout,
750- Vec :: new ( ) ,
751- wgpu:: PrimitiveState {
752- topology : wgpu:: PrimitiveTopology :: TriangleList ,
753- strip_index_format : None ,
754- front_face : wgpu:: FrontFace :: Ccw ,
755- cull_mode : None ,
756- polygon_mode : wgpu:: PolygonMode :: Fill ,
757- unclipped_depth : false ,
758- conservative : false ,
759- } ,
760- "vs_main"
761- ) ,
762- crate :: state:: PipelineType :: Mesh3D { .. } => (
763- & render_pipeline_layout_3d,
785+ let ( layout, vertex_buffers, primitive, vs_entry) = if vis_def. id == 19 {
786+ (
787+ & biolum_render_pipeline_layout,
764788 vec ! [ Vertex :: desc( ) ] ,
765789 wgpu:: PrimitiveState {
766790 topology : wgpu:: PrimitiveTopology :: TriangleList ,
@@ -772,7 +796,38 @@ impl<'a> VulkanEngine<'a> {
772796 conservative : false ,
773797 } ,
774798 "vs_main_3d"
775- ) ,
799+ )
800+ } else {
801+ match vis_def. pipeline_type {
802+ crate :: state:: PipelineType :: FullscreenQuad => (
803+ & render_pipeline_layout,
804+ Vec :: new ( ) ,
805+ wgpu:: PrimitiveState {
806+ topology : wgpu:: PrimitiveTopology :: TriangleList ,
807+ strip_index_format : None ,
808+ front_face : wgpu:: FrontFace :: Ccw ,
809+ cull_mode : None ,
810+ polygon_mode : wgpu:: PolygonMode :: Fill ,
811+ unclipped_depth : false ,
812+ conservative : false ,
813+ } ,
814+ "vs_main"
815+ ) ,
816+ crate :: state:: PipelineType :: Mesh3D { .. } => (
817+ & render_pipeline_layout_3d,
818+ vec ! [ Vertex :: desc( ) ] ,
819+ wgpu:: PrimitiveState {
820+ topology : wgpu:: PrimitiveTopology :: TriangleList ,
821+ strip_index_format : None ,
822+ front_face : wgpu:: FrontFace :: Ccw ,
823+ cull_mode : None ,
824+ polygon_mode : wgpu:: PolygonMode :: Fill ,
825+ unclipped_depth : false ,
826+ conservative : false ,
827+ } ,
828+ "vs_main_3d"
829+ ) ,
830+ }
776831 } ;
777832
778833 let pipeline = device. create_render_pipeline ( & wgpu:: RenderPipelineDescriptor {
@@ -1495,6 +1550,89 @@ impl<'a> VulkanEngine<'a> {
14951550 label : Some ( "Ferrofluid Clear" ) , layout : Some ( & ferrofluidsim_pipeline_layout) , module : & ferrofluidsim_compute_shader, entry_point : Some ( "clear" ) , compilation_options : Default :: default ( ) , cache : None ,
14961551 } ) ;
14971552
1553+ // --- Bioluminescent Waves Compute & Render Setup ---
1554+ let biolum_particles_buffer = device. create_buffer ( & wgpu:: BufferDescriptor {
1555+ label : Some ( "Bioluminescent Particles" ) ,
1556+ size : ( 65536 * 32 ) as u64 , // 65,536 particles * 32 bytes/particle
1557+ usage : wgpu:: BufferUsages :: STORAGE | wgpu:: BufferUsages :: COPY_DST ,
1558+ mapped_at_creation : false ,
1559+ } ) ;
1560+ queue. write_buffer ( & biolum_particles_buffer, 0 , & vec ! [ 0u8 ; 65536 * 32 ] ) ;
1561+
1562+ let biolum_compute_layout = device. create_bind_group_layout ( & wgpu:: BindGroupLayoutDescriptor {
1563+ label : Some ( "Biolum Compute Layout" ) ,
1564+ entries : & [
1565+ wgpu:: BindGroupLayoutEntry {
1566+ binding : 0 ,
1567+ visibility : wgpu:: ShaderStages :: COMPUTE ,
1568+ ty : wgpu:: BindingType :: Buffer {
1569+ ty : wgpu:: BufferBindingType :: Uniform ,
1570+ has_dynamic_offset : false ,
1571+ min_binding_size : None ,
1572+ } ,
1573+ count : None ,
1574+ } ,
1575+ wgpu:: BindGroupLayoutEntry {
1576+ binding : 1 ,
1577+ visibility : wgpu:: ShaderStages :: COMPUTE ,
1578+ ty : wgpu:: BindingType :: Buffer {
1579+ ty : wgpu:: BufferBindingType :: Storage { read_only : false } ,
1580+ has_dynamic_offset : false ,
1581+ min_binding_size : None ,
1582+ } ,
1583+ count : None ,
1584+ } ,
1585+ ] ,
1586+ } ) ;
1587+
1588+ let biolum_compute_bind_group = device. create_bind_group ( & wgpu:: BindGroupDescriptor {
1589+ label : Some ( "Biolum Compute Bind Group" ) ,
1590+ layout : & biolum_compute_layout,
1591+ entries : & [
1592+ wgpu:: BindGroupEntry {
1593+ binding : 0 ,
1594+ resource : uniform_buffer. as_entire_binding ( ) ,
1595+ } ,
1596+ wgpu:: BindGroupEntry {
1597+ binding : 1 ,
1598+ resource : biolum_particles_buffer. as_entire_binding ( ) ,
1599+ } ,
1600+ ] ,
1601+ } ) ;
1602+
1603+ let biolum_compute_source = resolve_shader_includes ( include_str ! ( "shaders/biolum_compute.wgsl" ) ) ;
1604+ let biolum_compute_shader = device. create_shader_module ( wgpu:: ShaderModuleDescriptor {
1605+ label : Some ( "Biolum Compute Shader" ) ,
1606+ source : wgpu:: ShaderSource :: Wgsl ( std:: borrow:: Cow :: Borrowed ( & biolum_compute_source) ) ,
1607+ } ) ;
1608+
1609+ let biolum_compute_pipeline_layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
1610+ label : Some ( "Biolum Compute Pipeline Layout" ) ,
1611+ bind_group_layouts : & [ Some ( & biolum_compute_layout) ] ,
1612+ immediate_size : 0 ,
1613+ } ) ;
1614+
1615+ let biolum_compute_pipeline = device. create_compute_pipeline ( & wgpu:: ComputePipelineDescriptor {
1616+ label : Some ( "Biolum Compute Pipeline" ) ,
1617+ layout : Some ( & biolum_compute_pipeline_layout) ,
1618+ module : & biolum_compute_shader,
1619+ entry_point : Some ( "main" ) ,
1620+ compilation_options : Default :: default ( ) ,
1621+ cache : None ,
1622+ } ) ;
1623+
1624+ let biolum_render_bind_group = device. create_bind_group ( & wgpu:: BindGroupDescriptor {
1625+ label : Some ( "Biolum Render Bind Group" ) ,
1626+ layout : & biolum_render_bind_group_layout,
1627+ entries : & [
1628+ wgpu:: BindGroupEntry {
1629+ binding : 0 ,
1630+ resource : biolum_particles_buffer. as_entire_binding ( ) ,
1631+ } ,
1632+ ] ,
1633+ } ) ;
1634+ // --- End Bioluminescent Waves Setup ---
1635+
14981636 let mut query_set = None ;
14991637 let mut query_resolve_buffer = None ;
15001638 let mut query_read_buffer = None ;
@@ -1830,6 +1968,13 @@ impl<'a> VulkanEngine<'a> {
18301968 ferrofluidsim_compute_pipeline,
18311969 ferrofluidsim_clear_pipeline,
18321970 ferrofluidsim_bind_group,
1971+
1972+ biolum_particles_buffer,
1973+ biolum_compute_pipeline,
1974+ biolum_compute_bind_group,
1975+ biolum_render_bind_group,
1976+ biolum_render_pipeline_layout,
1977+
18331978 start_time : std:: time:: Instant :: now ( ) ,
18341979 fft_compute_pipeline,
18351980 fft_bind_group,
@@ -3937,6 +4082,17 @@ impl<'a> VulkanEngine<'a> {
39374082 compute_pass. dispatch_workgroups ( 391 , 1 , 1 ) ;
39384083 }
39394084
4085+ if vis_def. id == 19 {
4086+ println ! ( "DEBUG: Bioluminescence Waves Sim Compute Dispatching!" ) ;
4087+ let mut compute_pass = encoder. begin_compute_pass ( & wgpu:: ComputePassDescriptor {
4088+ label : Some ( "Bioluminescence Waves Sim Compute" ) ,
4089+ timestamp_writes : None ,
4090+ } ) ;
4091+ compute_pass. set_pipeline ( & self . biolum_compute_pipeline ) ;
4092+ compute_pass. set_bind_group ( 0 , Some ( & self . biolum_compute_bind_group ) , & [ ] ) ;
4093+ compute_pass. dispatch_workgroups ( 256 , 1 , 1 ) ;
4094+ }
4095+
39404096 {
39414097 let mut render_pass = encoder. begin_render_pass ( & wgpu:: RenderPassDescriptor {
39424098 label : Some ( "Main Render Pass" ) ,
@@ -3945,7 +4101,11 @@ impl<'a> VulkanEngine<'a> {
39454101 resolve_target : None ,
39464102 depth_slice : None ,
39474103 ops : wgpu:: Operations {
3948- load : wgpu:: LoadOp :: Clear ( wgpu:: Color { r : 0.1 , g : 0.1 , b : 0.1 , a : 1.0 } ) ,
4104+ load : wgpu:: LoadOp :: Clear ( if vis_def. id == 19 {
4105+ wgpu:: Color { r : 0.001 , g : 0.003 , b : 0.008 , a : 1.0 }
4106+ } else {
4107+ wgpu:: Color { r : 0.1 , g : 0.1 , b : 0.1 , a : 1.0 }
4108+ } ) ,
39494109 store : wgpu:: StoreOp :: Store ,
39504110 } ,
39514111 } ) ] ,
@@ -4014,6 +4174,9 @@ impl<'a> VulkanEngine<'a> {
40144174 } ,
40154175 crate :: state:: PipelineType :: Mesh3D { geometry, instances } => {
40164176 render_pass. set_bind_group ( 2 , & self . camera_bind_group , & [ ] ) ;
4177+ if vis_def. id == 19 {
4178+ render_pass. set_bind_group ( 3 , & self . biolum_render_bind_group , & [ ] ) ;
4179+ }
40174180 if let Some ( mesh) = self . mesh_registry . get ( geometry) {
40184181 render_pass. set_vertex_buffer ( 0 , mesh. vertex_buffer . slice ( ..) ) ;
40194182 render_pass. set_index_buffer ( mesh. index_buffer . slice ( ..) , wgpu:: IndexFormat :: Uint32 ) ;
0 commit comments