use texture index
This commit is contained in:
@@ -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),
|
||||||
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(
|
pub fn generate_chunk_mesh(
|
||||||
chunk: &Chunk,
|
chunk: &Chunk,
|
||||||
@@ -35,6 +43,7 @@ pub fn generate_chunk_mesh(
|
|||||||
let mut verts = Vec::with_capacity(vertex_count);
|
let mut verts = Vec::with_capacity(vertex_count);
|
||||||
let mut uvs = Vec::with_capacity(vertex_count);
|
let mut uvs = Vec::with_capacity(vertex_count);
|
||||||
let mut indices = 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 z in 0..Chunk::SIZE {
|
||||||
for x in 0..Chunk::SIZE {
|
for x in 0..Chunk::SIZE {
|
||||||
@@ -57,6 +66,7 @@ pub fn generate_chunk_mesh(
|
|||||||
&mut verts,
|
&mut verts,
|
||||||
&mut uvs,
|
&mut uvs,
|
||||||
&mut indices,
|
&mut indices,
|
||||||
|
&mut texture_indicies,
|
||||||
// &mut tex,
|
// &mut tex,
|
||||||
tile.texture_id,
|
tile.texture_id,
|
||||||
tile.side_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_POSITION, verts)
|
||||||
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
|
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
|
||||||
|
.with_inserted_attribute(ATTRIBUTE_TEXTURE_INDEX, texture_indicies)
|
||||||
.with_inserted_indices(Indices::U32(indices))
|
.with_inserted_indices(Indices::U32(indices))
|
||||||
.with_duplicated_vertices()
|
.with_duplicated_vertices()
|
||||||
.with_computed_flat_normals();
|
.with_computed_flat_normals();
|
||||||
@@ -82,24 +93,25 @@ fn create_tile(
|
|||||||
verts: &mut Vec<Vec3>,
|
verts: &mut Vec<Vec3>,
|
||||||
uvs: &mut Vec<Vec2>,
|
uvs: &mut Vec<Vec2>,
|
||||||
indices: &mut Vec<u32>,
|
indices: &mut Vec<u32>,
|
||||||
|
texture_indices: &mut Vec<u32>,
|
||||||
texture_index: u32,
|
texture_index: u32,
|
||||||
side_texture_index: u32,
|
side_texture_index: u32,
|
||||||
) {
|
) {
|
||||||
let uv_offset = Vec2::splat(0.5);
|
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;
|
let idx = verts.len() as u32;
|
||||||
uvs.push(uv_offset + tex_off);
|
uvs.push(uv_offset);
|
||||||
|
texture_indices.push(texture_index);
|
||||||
verts.push(pos);
|
verts.push(pos);
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
let p = pos + HEX_CORNERS[i];
|
let p = pos + HEX_CORNERS[i];
|
||||||
verts.push(p);
|
verts.push(p);
|
||||||
let uv = (HEX_CORNERS[i].xz() / 2.) + uv_offset;
|
let uv = (HEX_CORNERS[i].xz() / 2.) + uv_offset;
|
||||||
uvs.push(uv + tex_off);
|
uvs.push(uv);
|
||||||
indices.push(idx);
|
indices.push(idx);
|
||||||
indices.push(idx + 1 + i as u32);
|
indices.push(idx + 1 + i as u32);
|
||||||
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
indices.push(idx + 1 + ((i as u32 + 1) % 6));
|
||||||
|
texture_indices.push(texture_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..neighbors.len() {
|
for i in 0..neighbors.len() {
|
||||||
@@ -107,7 +119,16 @@ fn create_tile(
|
|||||||
match cur_n {
|
match cur_n {
|
||||||
Some(n_height) => {
|
Some(n_height) => {
|
||||||
if n_height < pos.y {
|
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<Vec3>,
|
verts: &mut Vec<Vec3>,
|
||||||
uvs: &mut Vec<Vec2>,
|
uvs: &mut Vec<Vec2>,
|
||||||
indices: &mut Vec<u32>,
|
indices: &mut Vec<u32>,
|
||||||
tex_off: Vec2,
|
texture_indices: &mut Vec<u32>,
|
||||||
|
texture_index: u32,
|
||||||
) {
|
) {
|
||||||
let p1 = HEX_CORNERS[(dir) % 6] + pos;
|
let p1 = HEX_CORNERS[(dir) % 6] + pos;
|
||||||
let p2 = HEX_CORNERS[(dir + 1) % 6] + pos;
|
let p2 = HEX_CORNERS[(dir + 1) % 6] + pos;
|
||||||
@@ -136,6 +158,11 @@ fn create_tile_wall(
|
|||||||
verts.push(p3);
|
verts.push(p3);
|
||||||
verts.push(p4);
|
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);
|
||||||
indices.push(idx + 2);
|
indices.push(idx + 2);
|
||||||
indices.push(idx + 1);
|
indices.push(idx + 1);
|
||||||
@@ -144,8 +171,8 @@ fn create_tile_wall(
|
|||||||
indices.push(idx + 2);
|
indices.push(idx + 2);
|
||||||
indices.push(idx + 3);
|
indices.push(idx + 3);
|
||||||
|
|
||||||
uvs.push(Vec2::ZERO + tex_off);
|
uvs.push(Vec2::ZERO);
|
||||||
uvs.push(Vec2::new(1., 0.) + tex_off);
|
uvs.push(Vec2::new(1., 0.));
|
||||||
uvs.push(Vec2::new(0., pos.y - height) + tex_off);
|
uvs.push(Vec2::new(0., pos.y - height));
|
||||||
uvs.push(Vec2::new(1., pos.y - height) + tex_off);
|
uvs.push(Vec2::new(1., pos.y - height));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,30 +5,33 @@ use bevy_inspector_egui::quick::WorldInspectorPlugin;
|
|||||||
|
|
||||||
mod phos;
|
mod phos;
|
||||||
mod prelude;
|
mod prelude;
|
||||||
|
mod shaders;
|
||||||
|
|
||||||
use phos::PhosGamePlugin;
|
use phos::PhosGamePlugin;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins((
|
.add_plugins((
|
||||||
DefaultPlugins.set(WindowPlugin {
|
DefaultPlugins
|
||||||
primary_window: Some(Window {
|
.set(WindowPlugin {
|
||||||
title: "Phos".into(),
|
primary_window: Some(Window {
|
||||||
name: Some("phos".into()),
|
title: "Phos".into(),
|
||||||
resolution: (1920.0, 1080.0).into(),
|
name: Some("phos".into()),
|
||||||
resizable: true,
|
resolution: (1920.0, 1080.0).into(),
|
||||||
present_mode: PresentMode::AutoNoVsync,
|
resizable: true,
|
||||||
|
present_mode: PresentMode::AutoNoVsync,
|
||||||
|
..default()
|
||||||
|
}),
|
||||||
..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(),
|
WorldInspectorPlugin::new(),
|
||||||
PhosGamePlugin,
|
PhosGamePlugin,
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::shaders::chunk::ChunkMaterial;
|
||||||
use bevy::asset::LoadState;
|
use bevy::asset::LoadState;
|
||||||
use bevy::core_pipeline::experimental::taa::TemporalAntiAliasPlugin;
|
use bevy::core_pipeline::experimental::taa::TemporalAntiAliasPlugin;
|
||||||
use bevy::pbr::ExtendedMaterial;
|
use bevy::pbr::ExtendedMaterial;
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
use bevy::asset::{Asset, Handle};
|
use bevy::asset::Handle;
|
||||||
use bevy::pbr::{MaterialExtension, MaterialExtensionKey, MaterialExtensionPipeline, MaterialPipeline, MaterialPipelineKey};
|
use bevy::prelude::{Component, Image, Resource};
|
||||||
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;
|
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct ChunkAtlas {
|
pub struct ChunkAtlas {
|
||||||
@@ -19,33 +15,3 @@ pub struct PhosMap {
|
|||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct PhosChunk;
|
pub struct PhosChunk;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
|
|
||||||
pub struct ChunkMaterial {
|
|
||||||
#[texture(100, dimension = "2d_array")]
|
|
||||||
#[sampler(101)]
|
|
||||||
pub array_texture: Handle<Image>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MaterialExtension for ChunkMaterial {
|
|
||||||
fn fragment_shader() -> ShaderRef {
|
|
||||||
"shaders/world/chunk.wgsl".into()
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn specialize(
|
|
||||||
// _pipeline: &MaterialExtensionPipeline,
|
|
||||||
// descriptor: &mut RenderPipelineDescriptor,
|
|
||||||
// layout: &MeshVertexBufferLayout,
|
|
||||||
// _key: MaterialExtensionKey<Self>,
|
|
||||||
// ) -> 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(())
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|||||||
43
game/main/src/shaders/chunk.rs
Normal file
43
game/main/src/shaders/chunk.rs
Normal file
@@ -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<Image>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialExtension for ChunkMaterial {
|
||||||
|
fn fragment_shader() -> ShaderRef {
|
||||||
|
"shaders/world/chunk.wgsl".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn specialize(
|
||||||
|
_pipeline: &MaterialExtensionPipeline,
|
||||||
|
descriptor: &mut RenderPipelineDescriptor,
|
||||||
|
layout: &MeshVertexBufferLayout,
|
||||||
|
_key: MaterialExtensionKey<Self>,
|
||||||
|
) -> 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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
1
game/main/src/shaders/mod.rs
Normal file
1
game/main/src/shaders/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod chunk;
|
||||||
Reference in New Issue
Block a user