@@ -63,6 +63,8 @@ pub const SHADER_HANDLE: Handle<Shader> = weak_handle!("123e4567-e89b-12d3-a456-
6363impl Plugin for VoxelMaterialPlugin {
6464 fn build ( & self , app : & mut App ) {
6565 app. add_plugins ( ExtractComponentPlugin :: < InstanceMaterialData > :: default ( ) ) ;
66+ app. add_plugins ( ExtractComponentPlugin :: < CameraPosition > :: default ( ) ) ; // Add this line
67+
6668 app. sub_app_mut ( RenderApp )
6769 . add_render_command :: < Transparent3d , DrawCustom > ( )
6870 . init_resource :: < SpecializedMeshPipelines < CustomPipeline > > ( )
@@ -86,6 +88,7 @@ impl Plugin for VoxelMaterialPlugin {
8688 }
8789}
8890
91+
8992/// Single instance data containing position, scale and color.
9093#[ derive( Clone , Copy , Pod , Zeroable ) ]
9194#[ repr( C ) ]
@@ -155,34 +158,57 @@ struct InstanceBuffer {
155158 length : usize ,
156159}
157160
161+ #[ derive( Component , Clone ) ]
162+ struct CameraPosition ( Vec3 ) ;
163+
164+ impl ExtractComponent for CameraPosition {
165+ type QueryData = & ' static GlobalTransform ;
166+ type QueryFilter = With < Camera3d > ;
167+ type Out = Self ;
168+
169+ fn extract_component ( transform : QueryItem < ' _ , Self :: QueryData > ) -> Option < Self > {
170+ Some ( CameraPosition ( transform. translation ( ) ) )
171+ }
172+ }
173+
174+
158175/// Prepares instance buffers each frame, sorting instances by distance to camera.
159176fn prepare_instance_buffers (
160177 mut commands : Commands ,
161178 query : Query < ( Entity , & InstanceMaterialData ) > ,
162179 render_device : Res < RenderDevice > ,
163- views : Query < & GlobalTransform , With < Camera > > ,
180+ camera_query : Query < & CameraPosition > ,
164181) {
165- // Get the first camera's position, or use a default if none exist
166- let camera_pos = views
182+ let camera_pos = camera_query
167183 . iter ( )
168184 . next ( )
169- . map ( |transform| transform . translation ( ) )
185+ . map ( |pos| pos . 0 )
170186 . unwrap_or ( Vec3 :: ZERO ) ;
171187
188+ // // Debug: Print camera position
189+ // println!("Camera position: {:?}", camera_pos);
190+
172191 for ( entity, instance_data) in & query {
173192 if instance_data. instances . is_empty ( ) {
174193 commands. entity ( entity) . remove :: < InstanceBuffer > ( ) ;
175194 continue ;
176195 }
177196
178- // Sort back-to-front by distance from camera
179197 let mut sorted_instances = instance_data. instances . clone ( ) ;
180198 sorted_instances. sort_by ( |a, b| {
181199 let dist_a = camera_pos. distance_squared ( Vec3 :: from_slice ( & a. pos_scale [ 0 ..3 ] ) ) ;
182200 let dist_b = camera_pos. distance_squared ( Vec3 :: from_slice ( & b. pos_scale [ 0 ..3 ] ) ) ;
183201 dist_b. partial_cmp ( & dist_a) . unwrap_or ( std:: cmp:: Ordering :: Equal )
184202 } ) ;
185203
204+ // Debug: Print instance order and distances
205+ // println!("Sorted instances (far to near):");
206+ // for inst in &sorted_instances {
207+ // let pos = Vec3::from_slice(&inst.pos_scale[0..3]);
208+ // let dist = camera_pos.distance(pos);
209+ // println!(" pos: {:?}, distance: {:.3}, color: {:?}", pos, dist, inst.color);
210+ // }
211+
186212 let buffer = render_device. create_buffer_with_data ( & BufferInitDescriptor {
187213 label : Some ( "instance data buffer" ) ,
188214 contents : bytemuck:: cast_slice ( sorted_instances. as_slice ( ) ) ,
@@ -239,7 +265,18 @@ impl SpecializedMeshPipeline for CustomPipeline {
239265
240266 descriptor. fragment . as_mut ( ) . unwrap ( ) . targets [ 0 ] = Some ( ColorTargetState {
241267 format : color_format,
242- blend : Some ( BlendState :: ALPHA_BLENDING ) ,
268+ blend : Some ( BlendState {
269+ color : BlendComponent {
270+ src_factor : BlendFactor :: SrcAlpha ,
271+ dst_factor : BlendFactor :: OneMinusSrcAlpha ,
272+ operation : BlendOperation :: Add ,
273+ } ,
274+ alpha : BlendComponent {
275+ src_factor : BlendFactor :: SrcAlpha ,
276+ dst_factor : BlendFactor :: OneMinusSrcAlpha ,
277+ operation : BlendOperation :: Add ,
278+ } ,
279+ } ) ,
243280 write_mask : ColorWrites :: ALL ,
244281 } ) ;
245282
0 commit comments