From b644da1f5693710038009ef9ab287f0843b22214 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Wed, 24 Apr 2024 19:37:39 -0400 Subject: [PATCH] use texture index --- engine/world_generation/src/mesh_generator.rs | 47 +++++++++++++++---- game/main/src/main.rs | 35 +++++++------- game/main/src/phos.rs | 1 + game/main/src/prelude.rs | 38 +-------------- game/main/src/shaders/chunk.rs | 43 +++++++++++++++++ game/main/src/shaders/mod.rs | 1 + 6 files changed, 103 insertions(+), 62 deletions(-) create mode 100644 game/main/src/shaders/chunk.rs create mode 100644 game/main/src/shaders/mod.rs diff --git a/engine/world_generation/src/mesh_generator.rs b/engine/world_generation/src/mesh_generator.rs index 8b7a2e1..23e4e01 100644 --- a/engine/world_generation/src/mesh_generator.rs +++ b/engine/world_generation/src/mesh_generator.rs @@ -23,6 +23,14 @@ const HEX_CORNERS: [Vec3; 6] = [ Vec3::new(-INNER_RADIUS, 0., -0.5 * OUTER_RADIUS), Vec3::new(-INNER_RADIUS, 0., 0.5 * OUTER_RADIUS), ]; +const HEX_NORMALS: [Vec3; 6] = [ + Vec3::new(0., 0., OUTER_RADIUS), + Vec3::new(INNER_RADIUS, 0., 0.5 * OUTER_RADIUS), + Vec3::new(INNER_RADIUS, 0., -0.5 * OUTER_RADIUS), + Vec3::new(0., 0., -OUTER_RADIUS), + Vec3::new(-INNER_RADIUS, 0., -0.5 * OUTER_RADIUS), + Vec3::new(-INNER_RADIUS, 0., 0.5 * OUTER_RADIUS), +]; pub fn generate_chunk_mesh( chunk: &Chunk, @@ -35,6 +43,7 @@ pub fn generate_chunk_mesh( let mut verts = Vec::with_capacity(vertex_count); let mut uvs = Vec::with_capacity(vertex_count); let mut indices = Vec::with_capacity(vertex_count); + let mut texture_indicies = Vec::with_capacity(vertex_count); for z in 0..Chunk::SIZE { for x in 0..Chunk::SIZE { @@ -57,6 +66,7 @@ pub fn generate_chunk_mesh( &mut verts, &mut uvs, &mut indices, + &mut texture_indicies, // &mut tex, tile.texture_id, tile.side_texture_id, @@ -70,6 +80,7 @@ pub fn generate_chunk_mesh( ) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, verts) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) + .with_inserted_attribute(ATTRIBUTE_TEXTURE_INDEX, texture_indicies) .with_inserted_indices(Indices::U32(indices)) .with_duplicated_vertices() .with_computed_flat_normals(); @@ -82,24 +93,25 @@ fn create_tile( verts: &mut Vec, uvs: &mut Vec, indices: &mut Vec, + texture_indices: &mut Vec, texture_index: u32, side_texture_index: u32, ) { let uv_offset = Vec2::splat(0.5); - let tex_off = Vec2::new(texture_index as f32, 0.); - let side_tex_off = Vec2::new(side_texture_index as f32, 0.); let idx = verts.len() as u32; - uvs.push(uv_offset + tex_off); + uvs.push(uv_offset); + texture_indices.push(texture_index); verts.push(pos); for i in 0..6 { let p = pos + HEX_CORNERS[i]; verts.push(p); let uv = (HEX_CORNERS[i].xz() / 2.) + uv_offset; - uvs.push(uv + tex_off); + uvs.push(uv); indices.push(idx); indices.push(idx + 1 + i as u32); indices.push(idx + 1 + ((i as u32 + 1) % 6)); + texture_indices.push(texture_index); } for i in 0..neighbors.len() { @@ -107,7 +119,16 @@ fn create_tile( match cur_n { Some(n_height) => { if n_height < pos.y { - create_tile_wall(pos, i, n_height, verts, uvs, indices, side_tex_off); + create_tile_wall( + pos, + i, + n_height, + verts, + uvs, + indices, + texture_indices, + side_texture_index, + ); } } _ => {} @@ -122,7 +143,8 @@ fn create_tile_wall( verts: &mut Vec, uvs: &mut Vec, indices: &mut Vec, - tex_off: Vec2, + texture_indices: &mut Vec, + texture_index: u32, ) { let p1 = HEX_CORNERS[(dir) % 6] + pos; let p2 = HEX_CORNERS[(dir + 1) % 6] + pos; @@ -136,6 +158,11 @@ fn create_tile_wall( verts.push(p3); verts.push(p4); + texture_indices.push(texture_index); + texture_indices.push(texture_index); + texture_indices.push(texture_index); + texture_indices.push(texture_index); + indices.push(idx); indices.push(idx + 2); indices.push(idx + 1); @@ -144,8 +171,8 @@ fn create_tile_wall( indices.push(idx + 2); indices.push(idx + 3); - uvs.push(Vec2::ZERO + tex_off); - uvs.push(Vec2::new(1., 0.) + tex_off); - uvs.push(Vec2::new(0., pos.y - height) + tex_off); - uvs.push(Vec2::new(1., pos.y - height) + tex_off); + uvs.push(Vec2::ZERO); + uvs.push(Vec2::new(1., 0.)); + uvs.push(Vec2::new(0., pos.y - height)); + uvs.push(Vec2::new(1., pos.y - height)); } diff --git a/game/main/src/main.rs b/game/main/src/main.rs index bdeec35..bfb9741 100644 --- a/game/main/src/main.rs +++ b/game/main/src/main.rs @@ -5,30 +5,33 @@ use bevy_inspector_egui::quick::WorldInspectorPlugin; mod phos; mod prelude; +mod shaders; use phos::PhosGamePlugin; fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Phos".into(), - name: Some("phos".into()), - resolution: (1920.0, 1080.0).into(), - resizable: true, - present_mode: PresentMode::AutoNoVsync, + DefaultPlugins + .set(WindowPlugin { + primary_window: Some(Window { + title: "Phos".into(), + name: Some("phos".into()), + resolution: (1920.0, 1080.0).into(), + resizable: true, + present_mode: PresentMode::AutoNoVsync, + ..default() + }), ..default() + }) + .set(ImagePlugin { + default_sampler: ImageSamplerDescriptor { + address_mode_u: ImageAddressMode::Repeat, + address_mode_v: ImageAddressMode::Repeat, + mag_filter: ImageFilterMode::Nearest, + ..default() + }, }), - ..default() - }).set(ImagePlugin { - default_sampler: ImageSamplerDescriptor { - address_mode_u: ImageAddressMode::Repeat, - address_mode_v: ImageAddressMode::Repeat, - mag_filter: ImageFilterMode::Nearest, - ..default() - } - }), WorldInspectorPlugin::new(), PhosGamePlugin, )) diff --git a/game/main/src/phos.rs b/game/main/src/phos.rs index 7b6f476..bfc0e25 100644 --- a/game/main/src/phos.rs +++ b/game/main/src/phos.rs @@ -1,4 +1,5 @@ use crate::prelude::*; +use crate::shaders::chunk::ChunkMaterial; use bevy::asset::LoadState; use bevy::core_pipeline::experimental::taa::TemporalAntiAliasPlugin; use bevy::pbr::ExtendedMaterial; diff --git a/game/main/src/prelude.rs b/game/main/src/prelude.rs index 2f60177..cfac76c 100644 --- a/game/main/src/prelude.rs +++ b/game/main/src/prelude.rs @@ -1,9 +1,5 @@ -use bevy::asset::{Asset, Handle}; -use bevy::pbr::{MaterialExtension, MaterialExtensionKey, MaterialExtensionPipeline, MaterialPipeline, MaterialPipelineKey}; -use bevy::prelude::{Component, Image, Mesh, Resource, TypePath}; -use bevy::render::mesh::{Indices, MeshVertexBufferLayout}; -use bevy::render::render_resource::{AsBindGroup, RenderPipelineDescriptor, ShaderRef, SpecializedMeshPipelineError}; -use world_generation::prelude::ATTRIBUTE_TEXTURE_INDEX; +use bevy::asset::Handle; +use bevy::prelude::{Component, Image, Resource}; #[derive(Resource)] pub struct ChunkAtlas { @@ -19,33 +15,3 @@ pub struct PhosMap { #[derive(Component)] pub struct PhosChunk; - - -#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] -pub struct ChunkMaterial { - #[texture(100, dimension = "2d_array")] - #[sampler(101)] - pub array_texture: Handle, -} - -impl MaterialExtension for ChunkMaterial { - fn fragment_shader() -> ShaderRef { - "shaders/world/chunk.wgsl".into() - } - - // fn specialize( - // _pipeline: &MaterialExtensionPipeline, - // descriptor: &mut RenderPipelineDescriptor, - // layout: &MeshVertexBufferLayout, - // _key: MaterialExtensionKey, - // ) -> Result<(), 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_TEXTURE_INDEX.at_shader_location(3), - // ])?; - // descriptor.vertex.buffers = vec![vertex_layout]; - // Ok(()) - // } -} diff --git a/game/main/src/shaders/chunk.rs b/game/main/src/shaders/chunk.rs new file mode 100644 index 0000000..e295c90 --- /dev/null +++ b/game/main/src/shaders/chunk.rs @@ -0,0 +1,43 @@ +use bevy::{ + asset::{Asset, Handle}, + pbr::{MaterialExtension, MaterialExtensionKey, MaterialExtensionPipeline}, + prelude::*, + reflect::TypePath, + render::{ + mesh::MeshVertexBufferLayout, + render_resource::{ + AsBindGroup, RenderPipelineDescriptor, ShaderRef, SpecializedMeshPipelineError, + }, + texture::Image, + }, +}; +use world_generation::prelude::ATTRIBUTE_TEXTURE_INDEX; + +#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] +pub struct ChunkMaterial { + #[texture(100, dimension = "2d_array")] + #[sampler(101)] + pub array_texture: Handle, +} + +impl MaterialExtension for ChunkMaterial { + fn fragment_shader() -> ShaderRef { + "shaders/world/chunk.wgsl".into() + } + + fn specialize( + _pipeline: &MaterialExtensionPipeline, + descriptor: &mut RenderPipelineDescriptor, + layout: &MeshVertexBufferLayout, + _key: MaterialExtensionKey, + ) -> Result<(), 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_TEXTURE_INDEX.at_shader_location(7), + ])?; + descriptor.vertex.buffers = vec![vertex_layout]; + Ok(()) + } +} diff --git a/game/main/src/shaders/mod.rs b/game/main/src/shaders/mod.rs new file mode 100644 index 0000000..15cf3d8 --- /dev/null +++ b/game/main/src/shaders/mod.rs @@ -0,0 +1 @@ +pub mod chunk;