@@ -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,40 +158,59 @@ 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 ) > ,
162- cameras : Query < & ExtractedView > ,
163179 render_device : Res < RenderDevice > ,
180+ camera_query : Query < & CameraPosition > ,
164181) {
165- let Some ( camera) = cameras. iter ( ) . next ( ) else {
166- return ;
167- } ;
168- let cam_pos = camera. world_from_view . transform_point ( Vec3 :: ZERO ) ;
182+ let camera_pos = camera_query
183+ . iter ( )
184+ . next ( )
185+ . map ( |pos| pos. 0 )
186+ . unwrap_or ( Vec3 :: ZERO ) ;
169187
170- for ( entity , instance_data ) in & query {
171- let mut sorted_instances = instance_data . instances . clone ( ) ;
188+ // // Debug: Print camera position
189+ // println!("Camera position: {:?}", camera_pos );
172190
173- if sorted_instances. is_empty ( ) {
191+ for ( entity, instance_data) in & query {
192+ if instance_data. instances . is_empty ( ) {
174193 commands. entity ( entity) . remove :: < InstanceBuffer > ( ) ;
175194 continue ;
176195 }
177196
178- // Sort back-to-front for proper alpha blending
197+ let mut sorted_instances = instance_data . instances . clone ( ) ;
179198 sorted_instances. sort_by ( |a, b| {
180- let a_pos = Vec3 :: new ( a. pos_scale [ 0 ] , a. pos_scale [ 1 ] , a. pos_scale [ 2 ] ) ;
181- let b_pos = Vec3 :: new ( b. pos_scale [ 0 ] , b. pos_scale [ 1 ] , b. pos_scale [ 2 ] ) ;
182- let a_dist = cam_pos. distance_squared ( a_pos) ;
183- let b_dist = cam_pos. distance_squared ( b_pos) ;
184-
185- b_dist
186- . partial_cmp ( & a_dist)
187- . unwrap_or ( std:: cmp:: Ordering :: Equal )
199+ let dist_a = camera_pos. distance_squared ( Vec3 :: from_slice ( & a. pos_scale [ 0 ..3 ] ) ) ;
200+ let dist_b = camera_pos. distance_squared ( Vec3 :: from_slice ( & b. pos_scale [ 0 ..3 ] ) ) ;
201+ dist_b. partial_cmp ( & dist_a) . unwrap_or ( std:: cmp:: Ordering :: Equal )
188202 } ) ;
189203
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+
190212 let buffer = render_device. create_buffer_with_data ( & BufferInitDescriptor {
191- label : Some ( "sorted instance data buffer" ) ,
213+ label : Some ( "instance data buffer" ) ,
192214 contents : bytemuck:: cast_slice ( sorted_instances. as_slice ( ) ) ,
193215 usage : BufferUsages :: VERTEX | BufferUsages :: COPY_DST ,
194216 } ) ;
@@ -200,6 +222,7 @@ fn prepare_instance_buffers(
200222 }
201223}
202224
225+
203226/// Custom pipeline for instanced mesh rendering.
204227#[ derive( Resource ) ]
205228struct CustomPipeline {
@@ -242,7 +265,18 @@ impl SpecializedMeshPipeline for CustomPipeline {
242265
243266 descriptor. fragment . as_mut ( ) . unwrap ( ) . targets [ 0 ] = Some ( ColorTargetState {
244267 format : color_format,
245- 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+ } ) ,
246280 write_mask : ColorWrites :: ALL ,
247281 } ) ;
248282
0 commit comments