Skip to content

Commit 051f8ee

Browse files
committed
feat: water init
1 parent 7816ae5 commit 051f8ee

File tree

8 files changed

+470
-12
lines changed

8 files changed

+470
-12
lines changed

src/chunk.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub struct Chunk {
2828
pub y: i32,
2929
pub blocks: BlockVec,
3030
pub indices: u32,
31+
pub water_indices: u32,
3132
pub device: Arc<wgpu::Device>,
3233
pub queue: Arc<wgpu::Queue>,
3334
pub noise_data: Arc<NoiseData>,
@@ -122,7 +123,22 @@ impl Chunk {
122123
false
123124
}
124125
}
125-
pub fn build_mesh(&self, other_chunks: Vec<WorldChunk>) -> (u32, wgpu::Buffer, wgpu::Buffer) {
126+
/*
127+
Return tuple:
128+
0: vertex indices , 1: water vertex indices
129+
2: vertex buffer , 3: index buffer
130+
4: water vertex buffer, 5: water index buffer */
131+
pub fn build_mesh(
132+
&self,
133+
other_chunks: Vec<WorldChunk>,
134+
) -> (
135+
u32,
136+
u32,
137+
wgpu::Buffer,
138+
wgpu::Buffer,
139+
wgpu::Buffer,
140+
wgpu::Buffer,
141+
) {
126142
let mut water_vertex: Vec<BlockVertexData> = vec![];
127143
let mut water_indices: Vec<u32> = vec![];
128144
let mut vertex: Vec<BlockVertexData> = vec![];
@@ -176,6 +192,13 @@ impl Chunk {
176192
let chunk = chunk.read().unwrap();
177193
if chunk.exists_block_at(&target_block) {
178194
is_visible = false;
195+
196+
if chunk.block_type_at(&target_block)
197+
== Some(BlockType::Water)
198+
&& block.block_type != BlockType::Water
199+
{
200+
is_visible = true;
201+
}
179202
}
180203
}
181204
None => {
@@ -187,15 +210,21 @@ impl Chunk {
187210
target_block.z as u32,
188211
self.noise_data.clone(),
189212
)
213+
&& face_position.y >= WATER_HEIGHT_LEVEL as f32
190214
{
191215
is_visible = false
192216
};
193217
}
194218
}
195-
} else if self.exists_block_at(&face_position)
196-
&& self.block_type_at(&face_position) != Some(BlockType::Water)
197-
{
219+
} else if self.exists_block_at(&face_position) {
198220
is_visible = false;
221+
222+
// This can be a oneline if, but it gets very hard to read
223+
if self.block_type_at(&face_position) == Some(BlockType::Water)
224+
&& block.block_type != BlockType::Water
225+
{
226+
is_visible = true;
227+
}
199228
}
200229

201230
if is_visible {
@@ -244,10 +273,28 @@ impl Chunk {
244273
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
245274
});
246275

276+
let chunk_water_vertex_buffer =
277+
self.device
278+
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
279+
contents: bytemuck::cast_slice(&water_vertex),
280+
label: Some(&format!("water-chunk-vertex-{}-{}", self.x, self.y)),
281+
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
282+
});
283+
let chunk_water_index_buffer =
284+
self.device
285+
.create_buffer_init(&wgpu::util::BufferInitDescriptor {
286+
contents: bytemuck::cast_slice(&water_indices),
287+
label: Some(&format!("water-chunk-vertex-{}-{}", self.x, self.y)),
288+
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
289+
});
290+
247291
(
248292
indices.len() as u32,
293+
water_indices.len() as u32,
249294
chunk_vertex_buffer,
250295
chunk_index_buffer,
296+
chunk_water_vertex_buffer,
297+
chunk_water_index_buffer,
251298
)
252299
}
253300
pub fn get_bind_group_layout() -> wgpu::BindGroupLayoutDescriptor<'static> {
@@ -477,6 +524,7 @@ impl Chunk {
477524
chunk_bind_group,
478525
chunk_position_buffer,
479526
indices: 0,
527+
water_indices: 0,
480528
outside_blocks: vec![],
481529
visible: true,
482530
};

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub mod state;
4343
pub mod structures;
4444
pub mod ui;
4545
pub mod utils;
46+
mod water;
4647
pub mod world;
4748

4849
async fn run(event_loop: EventLoop<()>, window: Window) {

src/pipeline.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,12 @@ impl Pipeline {
173173
&bind_group_0_layout,
174174
&bind_group_1_layout,
175175
&state.world.chunk_data_layout,
176-
&state.player.read().unwrap().camera.position_bind_group_layout
176+
&state
177+
.player
178+
.read()
179+
.unwrap()
180+
.camera
181+
.position_bind_group_layout,
177182
],
178183
push_constant_ranges: &[],
179184
});
@@ -268,6 +273,7 @@ pub trait PipelineTrait {
268273
#[derive(Debug, Clone, Copy, PartialEq)]
269274
pub enum PipelineType {
270275
WORLD,
276+
WATER,
271277
UI,
272278
}
273279

src/shaders/shader.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn fs_main(in: FragmentInput) -> @location(0) vec4<f32> {
8080
color *= max(dot(in.normals, normalize(light_direction)), 0.2);
8181
color += vec4<f32>(vec3<f32>(ambient_light), 0.0);
8282
color *= 1.0 - (in.ao * 0.9);
83-
color = mix(color, vec4<f32>(0.1, 0.2, 0.3, 1.0), in.fog);
83+
color = mix(color, vec4<f32>(0.03, 0.64, 0.97, 1.0), in.fog);
8484

8585
return color;
8686
}

src/shaders/water_shader.wgsl

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
2+
3+
struct VertexInput {
4+
@builtin(vertex_index) vertex_index: u32,
5+
@location(0) position: vec3<f32>,
6+
@location(1) normal: vec3<f32>,
7+
@location(2) tex_coords: vec2<f32>,
8+
@location(3) ao: f32,
9+
10+
}
11+
struct InstanceInput {
12+
// @location(2) instance_transform: vec3<f32>,
13+
@builtin(instance_index) instance_index: u32,
14+
};
15+
16+
17+
struct VertexOutput {
18+
@builtin(position) clip_position: vec4<f32>,
19+
@location(0) tex_coords: vec2<f32>,
20+
@location(1) normals: vec3<f32>,
21+
@location(2) chunk_position: vec2<i32>,
22+
@location(3) block_type: u32,
23+
@location(4) ao: f32,
24+
@location(5) fog: f32
25+
}
26+
27+
28+
@group(0) @binding(0)
29+
var<uniform> projection: mat4x4<f32>;
30+
@group(0) @binding(1)
31+
var<uniform> view: mat4x4<f32>;
32+
@group(2) @binding(0)
33+
var <uniform> current_chunk: vec2<i32>;
34+
@group(3) @binding(0)
35+
var <uniform> player_position: vec3<f32>;
36+
37+
38+
@vertex
39+
fn vs_main(in: VertexInput, instance_data: InstanceInput) -> VertexOutput {
40+
var out: VertexOutput;
41+
42+
43+
let chunk_offset = vec3<f32>(f32(current_chunk.x) * 16.0, 0.0, f32(current_chunk.y) * 16.0);
44+
let block_position = in.position + chunk_offset;
45+
46+
let player_dist = distance(player_position, block_position);
47+
48+
out.fog = min(pow(player_dist / 80.0, 6.0), 1.0);
49+
out.clip_position = projection * view * (vec4<f32>(block_position, 1.0));
50+
out.normals = in.normal;
51+
out.tex_coords = in.tex_coords;
52+
out.ao = in.ao;
53+
54+
return out;
55+
}
56+
57+
58+
@group(1) @binding(0)
59+
var diffuse: texture_2d<f32>;
60+
@group(1) @binding(1)
61+
var t_sampler: sampler;
62+
63+
struct FragmentInput {
64+
@location(0) tex_coords: vec2<f32>,
65+
@location(1) normals: vec3<f32>,
66+
@location(2) current_chunk: vec2<i32>,
67+
@location(3) block_type: u32,
68+
@location(4) ao: f32,
69+
@location(5) fog: f32
70+
}
71+
72+
73+
@fragment
74+
fn fs_main(in: FragmentInput) -> @location(0) vec4<f32> {
75+
var color: vec4<f32>;
76+
color = textureSample(diffuse, t_sampler, in.tex_coords);
77+
color.a = 0.1;
78+
79+
return color;
80+
}

src/state.rs

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::collision::CollisionBox;
77
use crate::persistence::Saveable;
88
use crate::pipeline::{Pipeline, PipelineTrait};
99
use crate::utils::{ChunkFromPosition, RelativeFromAbsolute};
10+
use crate::water::WaterPipeline;
1011
use crate::{
1112
material::Texture,
1213
pipeline::{self, Uniforms},
@@ -110,9 +111,11 @@ impl State {
110111
};
111112

112113
let world_pipeline = Box::new(Pipeline::new(&state));
114+
let water_pipeline = Box::new(WaterPipeline::new(&state));
113115
let ui_pipeline = Box::new(UIPipeline::new(&state));
114116

115117
state.pipelines.push(world_pipeline);
118+
state.pipelines.push(water_pipeline);
116119
state.pipelines.push(ui_pipeline);
117120

118121
state
@@ -326,9 +329,9 @@ impl State {
326329
resolve_target: None,
327330
ops: wgpu::Operations {
328331
load: wgpu::LoadOp::Clear(wgpu::Color {
329-
r: 0.1,
330-
g: 0.2,
331-
b: 0.3,
332+
r: 0.03,
333+
g: 0.64,
334+
b: 0.97,
332335
a: 1.0,
333336
}),
334337
store: wgpu::StoreOp::Store,
@@ -377,6 +380,59 @@ impl State {
377380
};
378381
}
379382
}
383+
{
384+
let mut water_rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
385+
label: None,
386+
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
387+
view: &view,
388+
resolve_target: None,
389+
ops: wgpu::Operations {
390+
load: wgpu::LoadOp::Load,
391+
store: wgpu::StoreOp::Store,
392+
},
393+
})],
394+
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
395+
view: &self.pipelines[0].depth_texture().view,
396+
depth_ops: Some(wgpu::Operations {
397+
load: wgpu::LoadOp::Load,
398+
store: wgpu::StoreOp::Discard,
399+
}),
400+
stencil_ops: None,
401+
}),
402+
timestamp_writes: None,
403+
occlusion_query_set: None,
404+
});
405+
let pipeline = &self.pipelines[1];
406+
407+
water_rpass.set_pipeline(pipeline.pipeline());
408+
409+
water_rpass.set_bind_group(0, pipeline.bind_group_0(), &[]);
410+
water_rpass.set_bind_group(1, pipeline.bind_group_1(), &[]);
411+
water_rpass.set_bind_group(3, &player.camera.position_bind_group, &[]);
412+
413+
for chunk in chunks.iter() {
414+
if chunk.visible {
415+
water_rpass.set_bind_group(2, &chunk.chunk_bind_group, &[]);
416+
water_rpass.set_vertex_buffer(
417+
0,
418+
chunk
419+
.chunk_water_vertex_buffer
420+
.as_ref()
421+
.expect("Vertex buffer not initiated")
422+
.slice(..),
423+
);
424+
water_rpass.set_index_buffer(
425+
chunk
426+
.chunk_water_index_buffer
427+
.as_ref()
428+
.expect("Index buffer not initiated")
429+
.slice(..),
430+
wgpu::IndexFormat::Uint32,
431+
);
432+
water_rpass.draw_indexed(0..chunk.water_indices, 0, 0..1);
433+
};
434+
}
435+
}
380436
{
381437
let mut ui_renderpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
382438
label: None,
@@ -400,7 +456,7 @@ impl State {
400456
occlusion_query_set: None,
401457
});
402458

403-
let pipeline = &self.pipelines[1];
459+
let pipeline = &self.pipelines[2];
404460
ui_renderpass.set_pipeline(pipeline.pipeline());
405461

406462
ui_renderpass.set_bind_group(0, pipeline.bind_group_0(), &[]);

0 commit comments

Comments
 (0)