Rust中128×256×128体素块迭代与渲染优化问询
体素块生成与可见面渲染优化方案求助
我正在制作规格为128×256×128的体素块,需迭代体素位置完成两个核心操作:先生成体素,再检查相邻体素以仅渲染可见面网格。但当前单块处理耗时约5秒,特此寻求优化该流程的技术方案。
体素创建代码
for x in 0..=width { for z in 0..=depth { let noise_value1 = noise.get([ (chunk_position.x + x as f32 * 0.01) as f64, (chunk_position.z + z as f32 * 0.01) as f64, ]) as f32; let mut y = ((noise_value1 * 20.0) + (CHUNK_DEPTH / 3) as f32).round() as usize; y = y.min(height); chunk_voxels.voxel_array.extend((0..y).map(|n| { ( Position { x: x as u8, y: n as u8, z: z as u8, }, Voxel { voxel_id: 1 }, ) })); } }
可见面渲染检查代码
for voxel in voxel_array.iter() { if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32, y: voxel.0.y as f32 + 1 as f32, z: voxel.0.z as f32, }) { //check for up if !voxel_array.contains_key(&Position { x: voxel.0.x, y: voxel.0.y + 1, z: voxel.0.z, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: 0.0, y: 1.0, z: 0.0, }, ) } } if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32, y: voxel.0.y as f32 - 1 as f32, z: voxel.0.z as f32, }) { //check for down if !voxel_array.contains_key(&Position { x: voxel.0.x, y: voxel.0.y - 1, z: voxel.0.z, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: 0.0, y: -1.0, z: 0.0, }, ) } } if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32, y: voxel.0.y as f32, z: voxel.0.z as f32 - 1 as f32, }) { //check for left if !voxel_array.contains_key(&Position { x: voxel.0.x, y: voxel.0.y, z: voxel.0.z - 1, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: 0.0, y: 0.0, z: -1.0, }, ) } } if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32, y: voxel.0.y as f32, z: voxel.0.z as f32 + 1 as f32, }) { //check for right if !voxel_array.contains_key(&Position { x: voxel.0.x, y: voxel.0.y, z: voxel.0.z + 1, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: 0.0, y: 0.0, z: 1.0, }, ) } } if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32 - 1 as f32, y: voxel.0.y as f32, z: voxel.0.z as f32, }) { //check for forward if !voxel_array.contains_key(&Position { x: voxel.0.x - 1, y: voxel.0.y, z: voxel.0.z, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: -1.0, y: 0.0, z: 0.0, }, ) } } if check_for_out_of_bounds(Vec3 { x: voxel.0.x as f32 + 1 as f32, y: voxel.0.y as f32, z: voxel.0.z as f32, }) { //check for back if !voxel_array.contains_key(&Position { x: voxel.0.x + 1, y: voxel.0.y, z: voxel.0.z, }) { generate_voxel_mesh( Vec3 { x: voxel.0.x as f32 + chunk_pos.x, y: voxel.0.y as f32 + chunk_pos.y, z: voxel.0.z as f32 + chunk_pos.z, }, 1.0, voxel.1.voxel_id, mesh_builder, Vec3 { x: 1.0, y: 0.0, z: 0.0, }, ) } } }
优化方案
1. 体素存储结构重构
哈希表的contains_key存在哈希计算与查找开销,直接改用三维数组存储体素,访问速度接近O(0):
// 定义固定尺寸的三维数组,None代表空体素 let mut voxel_grid = [[[Option<Voxel>; 128]; 256]; 128];
生成体素时直接填充数组,避免键值对的内存分配与拷贝:
let chunk_x_offset = chunk_position.x as f64 * 0.01; let chunk_z_offset = chunk_position.z as f64 * 0.01; for x in 0..=width { for z in 0..=depth { let noise_value1 = noise.get([ chunk_x_offset + (x as f32 * 0.01) as f64, chunk_z_offset + (z as f32 * 0.01) as f64, ]) as f32; let mut y = ((noise_value1 * 20.0) + (CHUNK_DEPTH / 3) as f32).round() as usize; y = y.min(height); for n in 0..y { voxel_grid[x][n][z] = Some(Voxel { voxel_id: 1 }); } } }
2. 可见面检查逻辑精简
- 预定义6个方向的偏移量数组,消除代码冗余:
const DIRECTIONS: [(i8, i8, i8, Vec3); 6] = [ (0, 1, 0, Vec3 {x:0.0,y:1.0,z:0.0}), // 上 (0, -1, 0, Vec3 {x:0.0,y:-1.0,z:0.0}), // 下 (0, 0, -1, Vec3 {x:0.0,y:0.0,z:-1.0}), // 左 (0, 0, 1, Vec3 {x:0.0,y:0.0,z:1.0}), // 右 (-1, 0, 0, Vec3 {x:-1.0,y:0.0,z:0.0}), // 前 (1, 0, 0, Vec3 {x:1.0,y:0.0,z:0.0}), // 后 ]; - 合并边界检查与体素存在性判断,避免重复调用
check_for_out_of_bounds:for x in 0..128 { for y in 0..256 { for z in 0..128 { if let Some(voxel) = &voxel_grid[x][y][z] { for &(dx, dy, dz, dir) in &DIRECTIONS { let nx = x as i8 + dx; let ny = y as i8 + dy; let nz = z as i8 + dz; // 相邻位置越界 或 无体素时渲染面 let should_render = if nx < 0 || nx >= 128 || ny < 0 || ny >= 256 || nz < 0 || nz >= 128 { true } else { voxel_grid[nx as usize][ny as usize][nz as usize].is_none() }; if should_render { generate_voxel_mesh( Vec3 { x: x as f32 + chunk_pos.x, y: y as f32 + chunk_pos.y, z: z as f32 + chunk_pos.z, }, 1.0, voxel.voxel_id, mesh_builder, dir, ); } } } } } }
3. 噪声采样与计算优化
- 提前计算chunk级别的噪声偏移值,避免循环内重复计算
chunk_position.x/z * 0.01; - 若使用的噪声库支持批量采样,一次性生成所有x/z坐标的噪声值,减少函数调用开销;
- 尝试用
floor()替代round()(若业务允许),降低浮点运算成本。
4. 网格生成批量优化
- 预定义各方向面的顶点模板,仅需添加体素偏移量即可生成顶点坐标,避免重复计算;
- 收集所有需要渲染的面数据,一次性提交给
mesh_builder,减少单步调用的 overhead。
内容的提问来源于stack exchange,提问作者NewUser69420
相关产品推荐
相关产品推荐

