pack vertex data
This commit is contained in:
@@ -94,6 +94,8 @@ pub mod prelude {
|
|||||||
return chunk.temperature[pos.to_chunk_local_index()];
|
return chunk.temperature[pos.to_chunk_local_index()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub const ATTRIBUTE_PACKED_VERTEX_DATA: MeshVertexAttribute =
|
||||||
|
MeshVertexAttribute::new("PackedVertexData", 988540817, VertexFormat::Uint32);
|
||||||
|
|
||||||
pub const ATTRIBUTE_TEXTURE_INDEX: MeshVertexAttribute =
|
pub const ATTRIBUTE_TEXTURE_INDEX: MeshVertexAttribute =
|
||||||
MeshVertexAttribute::new("TextureIndex", 988540917, VertexFormat::Uint32);
|
MeshVertexAttribute::new("TextureIndex", 988540917, VertexFormat::Uint32);
|
||||||
|
|||||||
@@ -102,7 +102,131 @@ pub fn generate_chunk_mesh(
|
|||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_packed_chunk_mesh(
|
||||||
|
chunk: &Chunk,
|
||||||
|
map: &Map,
|
||||||
|
painter: &BiomePainterAsset,
|
||||||
|
tiles: &Res<Assets<TileAsset>>,
|
||||||
|
mappers: &Res<Assets<TileMapperAsset>>,
|
||||||
|
) -> Mesh {
|
||||||
|
let vertex_count: usize = Chunk::SIZE * Chunk::SIZE * 6;
|
||||||
|
let mut packed_data = Vec::with_capacity(vertex_count);
|
||||||
|
let mut indices = Vec::with_capacity(vertex_count);
|
||||||
|
let mut heights = Vec::with_capacity(vertex_count);
|
||||||
|
|
||||||
|
for z in 0..Chunk::SIZE {
|
||||||
|
for x in 0..Chunk::SIZE {
|
||||||
|
let height = chunk.heights[x + z * Chunk::SIZE];
|
||||||
|
let moisture = chunk.moisture[x + z * Chunk::SIZE];
|
||||||
|
let temperature = chunk.temperature[x + z * Chunk::SIZE];
|
||||||
|
let coord = HexCoord::from_offset(
|
||||||
|
IVec2::new(x as i32, z as i32) + (chunk.chunk_offset * Chunk::SIZE as i32),
|
||||||
|
);
|
||||||
|
let n = map.get_neighbors(&coord);
|
||||||
|
let biome = mappers.get(painter.sample_biome(moisture, temperature));
|
||||||
|
let tile_handle = biome.unwrap().sample_tile(height);
|
||||||
|
let tile = tiles.get(tile_handle).unwrap();
|
||||||
|
|
||||||
|
create_packed_tile(
|
||||||
|
UVec2::new(x as u32, z as u32),
|
||||||
|
height,
|
||||||
|
&n,
|
||||||
|
&mut packed_data,
|
||||||
|
&mut indices,
|
||||||
|
&mut heights,
|
||||||
|
tile.texture_id,
|
||||||
|
tile.side_texture_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mesh = Mesh::new(
|
||||||
|
PrimitiveTopology::TriangleList,
|
||||||
|
RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD,
|
||||||
|
)
|
||||||
|
.with_inserted_attribute(ATTRIBUTE_PACKED_VERTEX_DATA, packed_data)
|
||||||
|
.with_inserted_indices(Indices::U32(indices));
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
const TEX_MULTI: Vec2 = Vec2::new(1000., 1.);
|
const TEX_MULTI: Vec2 = Vec2::new(1000., 1.);
|
||||||
|
|
||||||
|
fn create_packed_tile(
|
||||||
|
offset: UVec2,
|
||||||
|
height: f32,
|
||||||
|
neighbors: &[Option<f32>; 6],
|
||||||
|
packed_data: &mut Vec<u32>,
|
||||||
|
indices: &mut Vec<u32>,
|
||||||
|
heights: &mut Vec<f32>,
|
||||||
|
texture_index: u32,
|
||||||
|
side_texture_index: u32,
|
||||||
|
) {
|
||||||
|
let idx = packed_data.len() as u32;
|
||||||
|
|
||||||
|
packed_data.push(pack_vertex_data(offset, 0, texture_index));
|
||||||
|
heights.push(height);
|
||||||
|
for i in 0..6 {
|
||||||
|
packed_data.push(pack_vertex_data(offset, i + 1, texture_index));
|
||||||
|
indices.push(idx);
|
||||||
|
indices.push(idx + 1 + i as u32);
|
||||||
|
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
||||||
|
heights.push(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..neighbors.len() {
|
||||||
|
let cur_n = neighbors[i];
|
||||||
|
match cur_n {
|
||||||
|
Some(n_height) => {
|
||||||
|
if n_height < height {
|
||||||
|
create_packed_tile_wall(
|
||||||
|
offset,
|
||||||
|
height,
|
||||||
|
n_height,
|
||||||
|
i,
|
||||||
|
packed_data,
|
||||||
|
indices,
|
||||||
|
heights,
|
||||||
|
side_texture_index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_packed_tile_wall(
|
||||||
|
offset: UVec2,
|
||||||
|
height_top: f32,
|
||||||
|
height_bottom: f32,
|
||||||
|
side: usize,
|
||||||
|
packed_data: &mut Vec<u32>,
|
||||||
|
indices: &mut Vec<u32>,
|
||||||
|
heights: &mut Vec<f32>,
|
||||||
|
side_texture_index: u32,
|
||||||
|
) {
|
||||||
|
let idx = packed_data.len() as u32;
|
||||||
|
|
||||||
|
let side_2 = ((side + 1) % 6) + 1;
|
||||||
|
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side + 1, side_texture_index));
|
||||||
|
packed_data.push(pack_vertex_data(offset, side_2, side_texture_index));
|
||||||
|
|
||||||
|
heights.push(height_top);
|
||||||
|
heights.push(height_top);
|
||||||
|
heights.push(height_bottom);
|
||||||
|
heights.push(height_bottom);
|
||||||
|
|
||||||
|
indices.push(idx);
|
||||||
|
indices.push(idx + 2);
|
||||||
|
indices.push(idx + 1);
|
||||||
|
|
||||||
|
indices.push(idx + 1);
|
||||||
|
indices.push(idx + 2);
|
||||||
|
indices.push(idx + 3);
|
||||||
|
}
|
||||||
|
|
||||||
fn create_tile(
|
fn create_tile(
|
||||||
pos: Vec3,
|
pos: Vec3,
|
||||||
neighbors: &[Option<f32>; 6],
|
neighbors: &[Option<f32>; 6],
|
||||||
@@ -187,12 +311,12 @@ fn create_tile_wall(
|
|||||||
uvs.push((Vec2::new(1., pos.y - height) / TEX_MULTI) + tex_off);
|
uvs.push((Vec2::new(1., pos.y - height) / TEX_MULTI) + tex_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pack_vertex_data(offset: IVec2, vert: usize, tex: u32) -> u32 {
|
fn pack_vertex_data(offset: UVec2, vert: usize, tex: u32) -> u32 {
|
||||||
//4 bits vert
|
//4 bits vert
|
||||||
//6 + 6 bits offset
|
//6 + 6 bits offset
|
||||||
//12 bits texture
|
//12 bits texture
|
||||||
let mut data = offset.x as u32;
|
let mut data = offset.x;
|
||||||
data += (offset.y as u32) << 6;
|
data += (offset.y) << 6;
|
||||||
data += (vert as u32) << (6 + 6);
|
data += (vert as u32) << (6 + 6);
|
||||||
data += tex << (6 + 6 + 4);
|
data += tex << (6 + 6 + 4);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
use bevy::asset::{Asset, Handle};
|
use bevy::asset::{Asset, Handle};
|
||||||
use bevy::pbr::MaterialExtension;
|
use bevy::pbr::MaterialExtension;
|
||||||
use bevy::reflect::TypePath;
|
use bevy::reflect::TypePath;
|
||||||
|
use bevy::render::mesh::Mesh;
|
||||||
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
||||||
use bevy::render::texture::Image;
|
use bevy::render::texture::Image;
|
||||||
|
use world_generation::prelude::ATTRIBUTE_PACKED_VERTEX_DATA;
|
||||||
|
|
||||||
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
|
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
|
||||||
pub struct ChunkMaterial {
|
pub struct ChunkMaterial {
|
||||||
@@ -15,4 +17,24 @@ impl MaterialExtension for ChunkMaterial {
|
|||||||
fn fragment_shader() -> ShaderRef {
|
fn fragment_shader() -> ShaderRef {
|
||||||
"shaders/world/chunk.wgsl".into()
|
"shaders/world/chunk.wgsl".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vertex_shader() -> ShaderRef {
|
||||||
|
"shaders/world/chunk_packed.wgsl".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn specialize(
|
||||||
|
_pipeline: &bevy::pbr::MaterialExtensionPipeline,
|
||||||
|
descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor,
|
||||||
|
layout: &bevy::render::mesh::MeshVertexBufferLayout,
|
||||||
|
_key: bevy::pbr::MaterialExtensionKey<Self>,
|
||||||
|
) -> Result<(), bevy::render::render_resource::SpecializedMeshPipelineError> {
|
||||||
|
let vertex_layout = layout.get_layout(&[
|
||||||
|
Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
|
||||||
|
Mesh::ATTRIBUTE_UV_0.at_shader_location(1),
|
||||||
|
Mesh::ATTRIBUTE_NORMAL.at_shader_location(2),
|
||||||
|
ATTRIBUTE_PACKED_VERTEX_DATA.at_shader_location(7),
|
||||||
|
])?;
|
||||||
|
descriptor.vertex.buffers = vec![vertex_layout];
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user