mirror of
https://github.com/bevyengine/bevy
synced 2025-01-27 20:35:21 +00:00
9cc7e7c080
* Save 16 bytes per vertex by calculating tangents in the shader at runtime, rather than storing them in the vertex data. * Based on https://jcgt.org/published/0009/03/04, https://www.jeremyong.com/graphics/2023/12/16/surface-gradient-bump-mapping. * Fixed visbuffer resolve to use the updated algorithm that flips ddy correctly * Added some more docs about meshlet material limitations, and some TODOs about transforming UV coordinates for the future. ![image](https://github.com/user-attachments/assets/222d8192-8c82-4d77-945d-53670a503761) For testing add a normal map to the bunnies with StandardMaterial like below, and then test that on both main and this PR (make sure to download the correct bunny for each). Results should be mostly identical. ```rust normal_map_texture: Some(asset_server.load_with_settings( "textures/BlueNoise-Normal.png", |settings: &mut ImageLoaderSettings| settings.is_srgb = false, )), ```
79 lines
2.3 KiB
Rust
79 lines
2.3 KiB
Rust
use super::{
|
|
asset::{Meshlet, MeshletBoundingSpheres},
|
|
persistent_buffer::PersistentGpuBufferable,
|
|
};
|
|
use alloc::sync::Arc;
|
|
|
|
const MESHLET_VERTEX_SIZE_IN_BYTES: u32 = 32;
|
|
|
|
impl PersistentGpuBufferable for Arc<[u8]> {
|
|
type Metadata = ();
|
|
|
|
fn size_in_bytes(&self) -> usize {
|
|
self.len()
|
|
}
|
|
|
|
fn write_bytes_le(&self, _: Self::Metadata, buffer_slice: &mut [u8]) {
|
|
buffer_slice.clone_from_slice(self);
|
|
}
|
|
}
|
|
|
|
impl PersistentGpuBufferable for Arc<[u32]> {
|
|
type Metadata = u64;
|
|
|
|
fn size_in_bytes(&self) -> usize {
|
|
self.len() * size_of::<u32>()
|
|
}
|
|
|
|
fn write_bytes_le(&self, offset: Self::Metadata, buffer_slice: &mut [u8]) {
|
|
let offset = offset as u32 / MESHLET_VERTEX_SIZE_IN_BYTES;
|
|
|
|
for (i, index) in self.iter().enumerate() {
|
|
let size = size_of::<u32>();
|
|
let i = i * size;
|
|
let bytes = (*index + offset).to_le_bytes();
|
|
buffer_slice[i..(i + size)].clone_from_slice(&bytes);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PersistentGpuBufferable for Arc<[Meshlet]> {
|
|
type Metadata = (u64, u64);
|
|
|
|
fn size_in_bytes(&self) -> usize {
|
|
self.len() * size_of::<Meshlet>()
|
|
}
|
|
|
|
fn write_bytes_le(
|
|
&self,
|
|
(vertex_offset, index_offset): Self::Metadata,
|
|
buffer_slice: &mut [u8],
|
|
) {
|
|
let vertex_offset = (vertex_offset as usize / size_of::<u32>()) as u32;
|
|
let index_offset = index_offset as u32;
|
|
|
|
for (i, meshlet) in self.iter().enumerate() {
|
|
let size = size_of::<Meshlet>();
|
|
let i = i * size;
|
|
let bytes = bytemuck::cast::<_, [u8; size_of::<Meshlet>()]>(Meshlet {
|
|
start_vertex_id: meshlet.start_vertex_id + vertex_offset,
|
|
start_index_id: meshlet.start_index_id + index_offset,
|
|
vertex_count: meshlet.vertex_count,
|
|
triangle_count: meshlet.triangle_count,
|
|
});
|
|
buffer_slice[i..(i + size)].clone_from_slice(&bytes);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PersistentGpuBufferable for Arc<[MeshletBoundingSpheres]> {
|
|
type Metadata = ();
|
|
|
|
fn size_in_bytes(&self) -> usize {
|
|
self.len() * size_of::<MeshletBoundingSpheres>()
|
|
}
|
|
|
|
fn write_bytes_le(&self, _: Self::Metadata, buffer_slice: &mut [u8]) {
|
|
buffer_slice.clone_from_slice(bytemuck::cast_slice(self));
|
|
}
|
|
}
|