Draw water

This commit is contained in:
Imbris 2020-12-07 01:18:19 -05:00
parent 97bed5752b
commit fe6cf0396f
7 changed files with 91 additions and 62 deletions

View File

@ -24,7 +24,7 @@ pub use self::{
BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel,
Locals as FigureLocals,
},
fluid::Vertex as FluidVertex,
fluid::{BindGroup as FluidWaves, Vertex as FluidVertex},
lod_terrain::{LodData, Vertex as LodTerrainVertex},
particle::{Instance as ParticleInstance, Vertex as ParticleVertex},
postprocess::Locals as PostProcessLocals,

View File

@ -1,4 +1,4 @@
use super::super::{AaMode, GlobalsLayouts, TerrainLayout};
use super::super::{AaMode, GlobalsLayouts, TerrainLayout, Texture};
use bytemuck::{Pod, Zeroable};
use vek::*;
@ -43,6 +43,11 @@ impl Vertex {
}
}
pub struct BindGroup {
pub(in super::super) bind_group: wgpu::BindGroup,
waves: Texture,
}
pub struct FluidLayout {
pub waves: wgpu::BindGroupLayout,
}
@ -76,6 +81,25 @@ impl FluidLayout {
}),
}
}
pub fn bind(&self, device: &wgpu::Device, waves: Texture) -> BindGroup {
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: None,
layout: &self.waves,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(&waves.view),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&waves.sampler),
},
],
});
BindGroup { bind_group, waves }
}
}
pub struct FluidPipeline {

View File

@ -15,7 +15,6 @@ use crate::scene::camera::CameraMode;
use bytemuck::{Pod, Zeroable};
use common::terrain::BlockKind;
use vek::*;
use wgpu::BindGroup;
pub const MAX_POINT_LIGHT_COUNT: usize = 31;
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
@ -243,7 +242,7 @@ pub struct GlobalsLayouts {
}
pub struct ColLights<Locals> {
pub bind_group: BindGroup,
pub bind_group: wgpu::BindGroup,
pub texture: Texture,
phantom: std::marker::PhantomData<Locals>,
}

View File

@ -1,7 +1,9 @@
use super::{
super::{
consts::Consts,
pipelines::{figure, lod_terrain, terrain, ui, ColLights, GlobalModel, GlobalsBindGroup},
pipelines::{
figure, fluid, lod_terrain, terrain, ui, ColLights, GlobalModel, GlobalsBindGroup,
},
texture::Texture,
},
Renderer,
@ -64,4 +66,8 @@ impl Renderer {
pub fn terrain_bind_col_light(&self, col_light: Texture) -> ColLights<terrain::Locals> {
self.layouts.global.bind_col_light(&self.device, col_light)
}
pub fn fluid_bind_waves(&self, texture: Texture) -> fluid::BindGroup {
self.layouts.fluid.bind(&self.device, texture)
}
}

View File

@ -181,28 +181,16 @@ impl<'a> FirstPassDrawer<'a> {
self.render_pass.draw(0..model.len() as u32, 0..1)
}
/*pub fn draw_fluid<'b: 'a>(
&mut self,
model: &'b Model,
locals: &'b Consts<terrain::Locals>,
waves: &'b Consts<fluid::Locals>,
globals: &'b Consts<Globals>,
lights: &'b Consts<Light>,
shadows: &'b Consts<Shadow>,
verts: Range<u32>,
) {
pub fn draw_particles(&mut self) -> ParticleDrawer<'_, 'a> {
self.render_pass
.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
self.render_pass.set_bind_group(1, &lights.bind_group, &[]);
self.render_pass.set_bind_group(2, &shadows.bind_group, &[]);
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
self.render_pass.set_bind_group(4, &waves.bind_group, &[]);
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
self.render_pass.draw(verts, 0..1);
.set_pipeline(&self.renderer.particle_pipeline.pipeline);
ParticleDrawer {
render_pass: &mut self.render_pass,
}
}
pub fn draw_sprite<'b: 'a>(
/*pub fn draw_sprite<'b: 'a>(
&mut self,
model: &'b Model,
instances: &'a Instances<sprite::Instance>,
@ -221,11 +209,12 @@ impl<'a> FirstPassDrawer<'a> {
self.render_pass.draw(verts, 0..instances.count() as u32);
}*/
pub fn draw_particles<'c>(&'c mut self) -> ParticleDrawer<'c, 'a> {
pub fn draw_fluid<'b: 'a>(&mut self, waves: &'b fluid::BindGroup) -> FluidDrawer<'_, 'a> {
self.render_pass
.set_pipeline(&self.renderer.particle_pipeline.pipeline);
.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
self.render_pass.set_bind_group(1, &waves.bind_group, &[]);
ParticleDrawer {
FluidDrawer {
render_pass: &mut self.render_pass,
}
}
@ -236,7 +225,7 @@ pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> {
}
impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
// Note: if we ever need to draw less than the whole model, this api can be
// Note: if we ever need to draw less than the whole model, these APIs can be
// changed
pub fn draw<'data: 'pass>(
&mut self,
@ -252,6 +241,22 @@ impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
}
}
pub struct FluidDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
}
impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> {
pub fn draw<'data: 'pass>(
&mut self,
model: &'data Model<fluid::Vertex>,
locals: &'data terrain::BoundLocals,
) {
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
self.render_pass.set_bind_group(2, &locals.bind_group, &[]);
self.render_pass.draw(0..model.len() as u32, 0..1);
}
}
pub struct SecondPassDrawer<'a> {
pub(super) render_pass: wgpu::RenderPass<'a>,
pub renderer: &'a Renderer,

View File

@ -1020,7 +1020,7 @@ impl Scene {
self.figure_mgr
.render_player(drawer, state, player_entity, tick, global, lod, camera_data);
self.terrain.render(drawer, global, lod, focus_pos);
self.terrain.render(drawer, focus_pos);
/* self.figure_mgr.render(
renderer,
@ -1037,14 +1037,12 @@ impl Scene {
// Render the skybox.
drawer.draw_skybox(&self.skybox.model);
/*self.terrain.render_translucent(
renderer,
global,
lod,
self.terrain.render_translucent(
drawer,
focus_pos,
cam_pos,
scene_data.sprite_render_distance,
);*/
);
// Render particle effects.
self.particle_mgr

View File

@ -9,9 +9,9 @@ use crate::{
},
render::{
pipelines::{self, ColLights},
ColLightInfo, Consts, FirstPassDrawer, FluidVertex, GlobalModel, Instances, LodData, Mesh,
Model, RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex, TerrainLocals,
TerrainVertex, Texture,
ColLightInfo, Consts, FirstPassDrawer, FluidVertex, FluidWaves, GlobalModel, Instances,
LodData, Mesh, Model, RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex,
TerrainLocals, TerrainVertex, Texture,
},
};
@ -332,7 +332,7 @@ pub struct Terrain<V: RectRasterableVol = TerrainChunk> {
/// for any particular chunk; look at the `texture` field in
/// `TerrainChunkData` for that.
col_lights: ColLights<pipelines::terrain::Locals>,
waves: Texture,
waves: FluidWaves,
phantom: PhantomData<V>,
}
@ -564,13 +564,17 @@ impl<V: RectRasterableVol> Terrain<V> {
mesh_recv_overflow: 0.0,
sprite_data: sprite_render_context.sprite_data,
sprite_col_lights: sprite_render_context.sprite_col_lights,
waves: renderer
.create_texture(
&assets::Image::load_expect("voxygen.texture.waves").read().0,
Some(wgpu::FilterMode::Linear),
Some(wgpu::AddressMode::Repeat),
)
.expect("Failed to create wave texture"),
waves: {
let waves_tex = renderer
.create_texture(
&assets::Image::load_expect("voxygen.texture.waves").read().0,
Some(wgpu::FilterMode::Linear),
Some(wgpu::AddressMode::Repeat),
)
.expect("Failed to create wave texture");
renderer.fluid_bind_waves(waves_tex)
},
col_lights,
phantom: PhantomData,
}
@ -1454,13 +1458,7 @@ impl<V: RectRasterableVol> Terrain<V> {
});
}
pub fn render<'a>(
&'a self,
drawer: &mut FirstPassDrawer<'a>,
global: &GlobalModel,
lod: &LodData,
focus_pos: Vec3<f32>,
) {
pub fn render<'a>(&'a self, drawer: &mut FirstPassDrawer<'a>, focus_pos: Vec3<f32>) {
span!(_guard, "render", "Terrain::render");
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
(e as i32).div_euclid(sz as i32)
@ -1480,11 +1478,9 @@ impl<V: RectRasterableVol> Terrain<V> {
}
}
pub fn render_translucent(
&self,
renderer: &mut Renderer,
global: &GlobalModel,
lod: &LodData,
pub fn render_translucent<'a>(
&'a self,
drawer: &mut FirstPassDrawer<'a>,
focus_pos: Vec3<f32>,
cam_pos: Vec3<f32>,
sprite_render_distance: f32,
@ -1566,6 +1562,8 @@ impl<V: RectRasterableVol> Terrain<V> {
drop(guard);
// Translucent
span!(guard, "Fluid chunks");
let mut fluid_drawer = drawer.draw_fluid(&self.waves);
chunk_iter
.clone()
.filter(|(_, chunk)| chunk.visible.is_visible())
@ -1579,13 +1577,12 @@ impl<V: RectRasterableVol> Terrain<V> {
.into_iter()
.rev() // Render back-to-front
.for_each(|(model, locals)| {
/*renderer.render_fluid_chunk(
fluid_drawer.draw(
model,
global,
locals,
lod,
&self.waves,
)*/
)
});
drop(fluid_drawer);
drop(guard);
}
}