+9
-3
.gitignore
+9
-3
.gitignore
+11
-19
Cargo.lock
+11
-19
Cargo.lock
···
266
266
"fs_extra",
267
267
"futures",
268
268
"glam",
269
-
"glob",
270
269
"image",
271
270
"itertools",
272
271
"log",
···
946
945
dependencies = [
947
946
"bytemuck",
948
947
]
949
-
950
-
[[package]]
951
-
name = "glob"
952
-
version = "0.3.2"
953
-
source = "registry+https://github.com/rust-lang/crates.io-index"
954
-
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
955
948
956
949
[[package]]
957
950
name = "glow"
···
2148
2141
dependencies = [
2149
2142
"rand_chacha",
2150
2143
"rand_core",
2151
-
"zerocopy 0.8.16",
2144
+
"zerocopy 0.8.17",
2152
2145
]
2153
2146
2154
2147
[[package]]
···
2168
2161
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
2169
2162
dependencies = [
2170
2163
"getrandom 0.3.1",
2171
-
"zerocopy 0.8.16",
2164
+
"zerocopy 0.8.17",
2172
2165
]
2173
2166
2174
2167
[[package]]
···
3049
3042
3050
3043
[[package]]
3051
3044
name = "wasm-bindgen-futures"
3052
-
version = "0.4.50"
3045
+
version = "0.4.45"
3053
3046
source = "registry+https://github.com/rust-lang/crates.io-index"
3054
-
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
3047
+
checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b"
3055
3048
dependencies = [
3056
3049
"cfg-if",
3057
3050
"js-sys",
3058
-
"once_cell",
3059
3051
"wasm-bindgen",
3060
3052
"web-sys",
3061
3053
]
···
3621
3613
3622
3614
[[package]]
3623
3615
name = "winit"
3624
-
version = "0.30.8"
3616
+
version = "0.30.9"
3625
3617
source = "registry+https://github.com/rust-lang/crates.io-index"
3626
-
checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f"
3618
+
checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0"
3627
3619
dependencies = [
3628
3620
"ahash",
3629
3621
"android-activity",
···
3800
3792
3801
3793
[[package]]
3802
3794
name = "zerocopy"
3803
-
version = "0.8.16"
3795
+
version = "0.8.17"
3804
3796
source = "registry+https://github.com/rust-lang/crates.io-index"
3805
-
checksum = "7b8c07a70861ce02bad1607b5753ecb2501f67847b9f9ada7c160fff0ec6300c"
3797
+
checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
3806
3798
dependencies = [
3807
-
"zerocopy-derive 0.8.16",
3799
+
"zerocopy-derive 0.8.17",
3808
3800
]
3809
3801
3810
3802
[[package]]
···
3820
3812
3821
3813
[[package]]
3822
3814
name = "zerocopy-derive"
3823
-
version = "0.8.16"
3815
+
version = "0.8.17"
3824
3816
source = "registry+https://github.com/rust-lang/crates.io-index"
3825
-
checksum = "5226bc9a9a9836e7428936cde76bb6b22feea1a8bfdbc0d241136e4d13417e25"
3817
+
checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
3826
3818
dependencies = [
3827
3819
"proc-macro2",
3828
3820
"quote",
+2
-3
Cargo.toml
+2
-3
Cargo.toml
···
27
27
28
28
[build-dependencies]
29
29
fs_extra = "1.3"
30
-
glob = "0.3"
31
30
32
31
[lib]
33
32
crate-type = ["cdylib", "rlib"]
···
35
34
[target.'cfg(target_arch = "wasm32")'.dependencies]
36
35
console_error_panic_hook = "0.1.6"
37
36
console_log = "1.0"
38
-
wgpu = { version = "24", features = ["webgl"]}
37
+
wgpu = { version = "24", features = ["webgl"] }
39
38
wasm-bindgen = "0.2"
40
39
wasm-bindgen-futures = "0.4"
41
40
web-sys = { version = "0.3", features = [
···
43
42
"Window",
44
43
"Element",
45
44
"Location",
46
-
]}
45
+
] }
47
46
reqwest = "0.12"
+537
-204
src/gfx.rs
+537
-204
src/gfx.rs
···
1
+
use std::borrow::Borrow;
1
2
mod camera;
3
+
mod light;
2
4
mod model;
3
5
mod resources;
4
6
mod texture;
5
7
6
-
use std::sync::Arc;
7
-
8
+
use egui::text_selection::text_cursor_state::slice_char_range;
9
+
use egui::Key::A;
8
10
use egui_wgpu::ScreenDescriptor;
9
-
use glam::{vec3, IVec3, Quat, Vec3};
11
+
use glam::{vec3, IVec3, Mat4, Quat, Vec3, Vec4, Vec4Swizzles};
12
+
use light::LightUniform;
13
+
use std::ops::Deref;
14
+
use std::{f32::consts::PI, path::Path, sync::Arc};
10
15
use wgpu::util::DeviceExt;
16
+
use wgpu::BindingResource;
11
17
use winit::{
12
18
dpi::PhysicalSize,
13
19
event::{ElementState, KeyEvent, WindowEvent},
···
16
22
window::Window,
17
23
};
18
24
25
+
use crate::gfx::camera::CameraUniform;
26
+
use crate::gfx::model::DrawLight;
19
27
use crate::{
20
-
app::WASM_WIN_SIZE, gfx::model::Vertex, gui::EguiRenderer, world::map::{sl3get, Block, WorldMap, CHUNK_SIZE}, world::World, Instance, InstanceRaw
28
+
app::WASM_WIN_SIZE,
29
+
gfx::model::Vertex,
30
+
gui::EguiRenderer,
31
+
world::map::{sl3get, Block, WorldMap, CHUNK_SIZE},
32
+
world::World,
33
+
Instance, InstanceRaw,
21
34
};
22
35
23
-
#[repr(C)]
24
-
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
25
-
pub(crate) struct LightUniform {
26
-
position: Vec3,
27
-
_pad: u32,
28
-
color: Vec3,
29
-
_pad2: u32,
30
-
}
31
-
impl LightUniform {
32
-
pub fn new(position: Vec3, color: Vec3) -> LightUniform {
33
-
LightUniform {
34
-
position,
35
-
color,
36
-
_pad: 0,
37
-
_pad2: 0,
38
-
}
39
-
}
40
-
}
41
-
42
36
pub struct CameraState {
43
-
pub positioning: camera::Camera,
37
+
pub object: camera::Camera,
44
38
pub controller: camera::CameraController,
45
-
pub uniform: camera::CameraUniform,
46
-
pub buffer: wgpu::Buffer,
47
-
pub bind_group: wgpu::BindGroup,
39
+
pub uniform: CameraUniform,
48
40
}
49
41
pub struct InteractState {
50
42
pub clear_color: wgpu::Color,
···
58
50
}
59
51
60
52
pub struct LightState {
61
-
pub uniform: LightUniform,
62
-
pub buffer: wgpu::Buffer,
63
-
pub bind_group: wgpu::BindGroup,
53
+
pub object: camera::Camera,
54
+
pub uniform: CameraUniform,
55
+
pub shadow_map: texture::Texture,
64
56
}
65
57
66
58
pub struct RenderPipelines {
···
117
109
vertex_layouts: &[wgpu::VertexBufferLayout],
118
110
shader: wgpu::ShaderModuleDescriptor,
119
111
polygon_mode: wgpu::PolygonMode,
112
+
label: Option<&str>,
120
113
) -> wgpu::RenderPipeline {
121
114
let shader = device.create_shader_module(shader);
122
115
123
116
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
124
-
label: Some("Render Pipeline"),
117
+
label,
125
118
layout: Some(layout),
126
119
vertex: wgpu::VertexState {
127
120
module: &shader,
···
171
164
})
172
165
}
173
166
167
+
pub enum OneOrTwo<T> {
168
+
One(T),
169
+
Two(T, T),
170
+
}
171
+
172
+
impl<T> OneOrTwo<T> {
173
+
pub fn one(&mut self) -> &mut T {
174
+
match self {
175
+
OneOrTwo::One(t) => t,
176
+
OneOrTwo::Two(_, _) => {
177
+
panic!("Used one() on a Two.")
178
+
}
179
+
}
180
+
}
181
+
pub fn two(&mut self) -> (&mut T, &mut T) {
182
+
match self {
183
+
OneOrTwo::One(t) => panic!("Used two() on a One."),
184
+
OneOrTwo::Two(x, y) => (x, y),
185
+
}
186
+
}
187
+
}
188
+
pub struct Pass {
189
+
pipeline: OneOrTwo<wgpu::RenderPipeline>,
190
+
bind_group: wgpu::BindGroup,
191
+
uniform_bufs: Vec<wgpu::Buffer>,
192
+
}
193
+
174
194
pub struct Gfx {
175
195
pub surface: wgpu::Surface<'static>,
176
196
pub device: wgpu::Device,
177
197
pub queue: wgpu::Queue,
178
198
pub surface_config: wgpu::SurfaceConfiguration,
179
-
pub render_pipelines: RenderPipelines,
199
+
// pub render_pipelines: RenderPipelines,
180
200
pub depth_texture: texture::Texture,
201
+
202
+
// pub shadow_map_buffer: wgpu::Buffer,
203
+
// pub shadow_bind_group: wgpu::BindGroup,
204
+
pub shadow_pass: Pass,
205
+
pub forward_pass: Pass,
181
206
182
207
pub object: ObjectState,
183
208
pub camera: CameraState,
···
297
322
target: Vec3::ZERO,
298
323
up: Vec3::Y,
299
324
aspect: surface_config.width as f32 / surface_config.height as f32,
300
-
fovy: 45.0,
325
+
fovy: PI / 2.,
301
326
znear: 0.1,
302
327
zfar: 1000.0,
303
328
};
304
329
let camera_controller = camera::CameraController::new(0.2);
305
330
let mut camera_uniform = camera::CameraUniform::new();
306
331
camera_uniform.update_view_proj(&camera);
307
-
let camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
308
-
label: Some("Camera Buffer"),
309
-
contents: bytemuck::cast_slice(&[camera_uniform]),
310
-
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
311
-
});
312
-
let camera_bind_group_layout =
313
-
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
314
-
entries: &[wgpu::BindGroupLayoutEntry {
315
-
binding: 0,
316
-
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
317
-
ty: wgpu::BindingType::Buffer {
318
-
ty: wgpu::BufferBindingType::Uniform,
319
-
has_dynamic_offset: false,
320
-
min_binding_size: None,
321
-
},
322
-
count: None,
323
-
}],
324
-
label: Some("camera_bind_group_layout"),
325
-
});
326
-
let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
327
-
layout: &camera_bind_group_layout,
328
-
entries: &[wgpu::BindGroupEntry {
329
-
binding: 0,
330
-
resource: camera_buffer.as_entire_binding(),
331
-
}],
332
-
label: Some("camera_bind_group"),
333
-
});
332
+
333
+
// let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
334
+
// layout: &camera_bind_group_layout,
335
+
// entries: &[wgpu::BindGroupEntry {
336
+
// binding: 0,
337
+
// resource: camera_buffer.as_entire_binding(),
338
+
// }],
339
+
// label: Some("camera_bind_group"),
340
+
// });
334
341
let camera_state = CameraState {
335
-
positioning: camera,
342
+
object: camera,
336
343
controller: camera_controller,
337
344
uniform: camera_uniform,
338
-
buffer: camera_buffer,
339
-
bind_group: camera_bind_group,
340
345
};
341
346
342
347
// MAP LOAD
···
361
366
.await
362
367
.unwrap();
363
368
364
-
let light_uniform = LightUniform::new(Vec3::splat(90.0).with_y(40.0), vec3(1.0, 1.0, 0.5));
369
+
log::info!("Light setup!");
370
+
let light = camera::Camera {
371
+
eye: vec3(90., 40., 90.),
372
+
target: Vec3::ZERO,
373
+
up: Vec3::Y,
374
+
aspect: surface_config.width as f32 / surface_config.height as f32,
375
+
fovy: PI / 2.,
376
+
znear: 0.1,
377
+
zfar: 1000.0,
378
+
};
379
+
let mut light_uniform = camera::CameraUniform::new();
380
+
light_uniform.update_view_proj(&light);
381
+
382
+
//let light_uniform = LightUniform::new(Vec3::splat(90.0).with_y(40.0), vec3(1.0, 1.0, 1.0));
365
383
366
-
let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
367
-
label: Some("Light VB"),
368
-
contents: bytemuck::cast_slice(&[light_uniform]),
369
-
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
384
+
log::info!("Shadowmap setup!");
385
+
let shadow_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
386
+
label: Some("Shadow Sampler"),
387
+
address_mode_u: wgpu::AddressMode::ClampToEdge,
388
+
address_mode_v: wgpu::AddressMode::ClampToEdge,
389
+
address_mode_w: wgpu::AddressMode::ClampToEdge,
390
+
mag_filter: wgpu::FilterMode::Linear,
391
+
min_filter: wgpu::FilterMode::Linear,
392
+
mipmap_filter: wgpu::FilterMode::Nearest,
393
+
compare: Some(wgpu::CompareFunction::LessEqual),
394
+
..Default::default()
370
395
});
371
396
372
-
let light_bind_group_layout =
373
-
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
374
-
entries: &[wgpu::BindGroupLayoutEntry {
375
-
binding: 0,
376
-
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
377
-
ty: wgpu::BindingType::Buffer {
378
-
ty: wgpu::BufferBindingType::Uniform,
379
-
has_dynamic_offset: false,
380
-
min_binding_size: None,
381
-
},
382
-
count: None,
383
-
}],
384
-
label: None,
397
+
log::info!("asdfasdgf");
398
+
399
+
let shadow_map =
400
+
texture::Texture::create_depth_texture(&device, &surface_config, "Shadow Map");
401
+
// let shadow_texture = device.create_texture(&wgpu::TextureDescriptor {
402
+
// size: wgpu::Extent3d {
403
+
// width: 1024,
404
+
// height: 1024,
405
+
// depth_or_array_layers: 10,
406
+
// },
407
+
// mip_level_count: 1,
408
+
// sample_count: 1,
409
+
// dimension: wgpu::TextureDimension::D2,
410
+
// format: wgpu::TextureFormat::Depth32Float,
411
+
// usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
412
+
// label: Some("Shadow texture"),
413
+
// view_formats: &[],
414
+
// });
415
+
// For forward pass
416
+
// let shadow_view = shadow_texture.create_view(&wgpu::TextureViewDescriptor::default());
417
+
418
+
log::info!("alskjgsdl;kfgjs;dkjl");
419
+
// For light in shadow pass
420
+
// let light_shadow_map = shadow_texture.create_view(&wgpu::TextureViewDescriptor {
421
+
// label: Some("Shadow Map"),
422
+
// format: Some(wgpu::TextureFormat::Depth32Float),
423
+
// dimension: Some(wgpu::TextureViewDimension::D2),
424
+
// usage: None,
425
+
// aspect: wgpu::TextureAspect::All,
426
+
// base_mip_level: 0,
427
+
// mip_level_count: None,
428
+
// base_array_layer: 0 as u32,
429
+
// array_layer_count: Some(1),
430
+
// });
431
+
432
+
// let shadow_map_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
433
+
// label: Some("Shadow Map Buffer"),
434
+
// contents: bytemuck::cast_slice(&[camera_uniform]),
435
+
// usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
436
+
// });
437
+
438
+
// let shadow_bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
439
+
// entries: &[wgpu::BindGroupLayoutEntry {
440
+
// binding: 0,
441
+
// visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
442
+
// ty: wgpu::BindingType::Buffer {
443
+
// ty: wgpu::BufferBindingType::Uniform,
444
+
// has_dynamic_offset: false,
445
+
// min_binding_size: None,
446
+
// },
447
+
// count: None,
448
+
// }],
449
+
// label: None,
450
+
// });
451
+
// let shadow_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
452
+
// layout: &shadow_bgl,
453
+
// entries: &[wgpu::BindGroupEntry {
454
+
// binding: 0,
455
+
// resource: light_buffer.as_entire_binding(),
456
+
// }],
457
+
// label: None,
458
+
// });
459
+
460
+
log::info!("Pipeline setup!");
461
+
// New stuff goes above here!
462
+
463
+
log::info!("Pipeline/Globals setup!");
464
+
// let render_pipeline = {
465
+
// let shader = wgpu::ShaderModuleDescriptor {
466
+
// label: Some("Normal Shader"),
467
+
// source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
468
+
// };
469
+
// create_render_pipeline(
470
+
// &device,
471
+
// &render_pipeline_layout,
472
+
// surface_config.format,
473
+
// Some(texture::Texture::DEPTH_FORMAT),
474
+
// &[model::ModelVertex::desc(), InstanceRaw::desc()],
475
+
// shader,
476
+
// wgpu::PolygonMode::Fill,
477
+
// Some("Normal Render Pipeline"),
478
+
// )
479
+
// };
480
+
//
481
+
// //let fill_pipeline = render_pipeline(wgpu::PolygonMode::Fill);
482
+
// let wireframe_render_pipeline = if (device.features() & wgpu::Features::POLYGON_MODE_LINE)
483
+
// == wgpu::Features::POLYGON_MODE_LINE
484
+
// {
485
+
// Some({
486
+
// let shader = wgpu::ShaderModuleDescriptor {
487
+
// label: Some("Normal Shader"),
488
+
// source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
489
+
// };
490
+
// create_render_pipeline(
491
+
// &device,
492
+
// &render_pipeline_layout,
493
+
// surface_config.format,
494
+
// Some(texture::Texture::DEPTH_FORMAT),
495
+
// &[model::ModelVertex::desc(), InstanceRaw::desc()],
496
+
// shader,
497
+
// wgpu::PolygonMode::Line,
498
+
// Some("Normal Render Pipeline"),
499
+
// )
500
+
// })
501
+
// } else {
502
+
// None
503
+
// };
504
+
505
+
fn bgl_t(binding: u32) -> wgpu::BindGroupLayoutEntry {
506
+
wgpu::BindGroupLayoutEntry {
507
+
binding,
508
+
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
509
+
ty: wgpu::BindingType::Buffer {
510
+
ty: wgpu::BufferBindingType::Uniform,
511
+
has_dynamic_offset: false,
512
+
min_binding_size: None,
513
+
},
514
+
count: None,
515
+
}
516
+
}
517
+
fn bge(binding: u32, resource: BindingResource<'_>) -> wgpu::BindGroupEntry {
518
+
wgpu::BindGroupEntry { binding, resource }
519
+
}
520
+
521
+
log::info!("Pipeline/Shadow setup!");
522
+
523
+
let shadow_pass = {
524
+
let camera_buffer = device.create_buffer(&wgpu::BufferDescriptor {
525
+
label: Some("Camera Buffer"),
526
+
size: size_of::<camera::CameraUniform>() as wgpu::BufferAddress,
527
+
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
528
+
mapped_at_creation: false,
529
+
});
530
+
let light_buffer = device.create_buffer(&wgpu::BufferDescriptor {
531
+
label: Some("Light VB"),
532
+
size: size_of::<CameraUniform>() as wgpu::BufferAddress,
533
+
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
534
+
mapped_at_creation: false,
385
535
});
386
536
387
-
let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
388
-
layout: &light_bind_group_layout,
389
-
entries: &[wgpu::BindGroupEntry {
390
-
binding: 0,
391
-
resource: light_buffer.as_entire_binding(),
392
-
}],
393
-
label: None,
394
-
});
537
+
let bind_group_layout =
538
+
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
539
+
label: None,
540
+
entries: &[
541
+
// Camera
542
+
bgl_t(0),
543
+
// Light position
544
+
bgl_t(1),
545
+
],
546
+
});
395
547
396
-
// New stuff goes above here!
397
-
let render_pipeline_layout =
398
-
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
399
-
label: Some("Render Pipeline Layout"),
400
-
bind_group_layouts: &[
401
-
&texture_bind_group_layout,
402
-
&camera_bind_group_layout,
403
-
&light_bind_group_layout,
548
+
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
549
+
label: None,
550
+
layout: &bind_group_layout,
551
+
entries: &[
552
+
bge(0, camera_buffer.as_entire_binding()),
553
+
bge(1, light_buffer.as_entire_binding()),
404
554
],
555
+
});
556
+
557
+
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
558
+
label: Some("Shadow Pipeline Layout"),
559
+
bind_group_layouts: &[&bind_group_layout],
405
560
push_constant_ranges: &[],
406
561
});
407
562
408
-
let render_pipeline = {
409
563
let shader = wgpu::ShaderModuleDescriptor {
410
-
label: Some("Normal Shader"),
411
-
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
564
+
label: Some("Shadow Shader"),
565
+
source: wgpu::ShaderSource::Wgsl(include_str!("shadows.wgsl").into()),
412
566
};
413
-
create_render_pipeline(
567
+
568
+
let shader = device.create_shader_module(shader);
569
+
570
+
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
571
+
label: Some("Shadows Render Pipeline"),
572
+
layout: Some(&pipeline_layout),
573
+
vertex: wgpu::VertexState {
574
+
module: &shader,
575
+
entry_point: Some("vs_main"),
576
+
buffers: &[model::ModelVertex::desc(), InstanceRaw::desc()],
577
+
compilation_options: Default::default(),
578
+
},
579
+
fragment: None,
580
+
primitive: wgpu::PrimitiveState {
581
+
topology: wgpu::PrimitiveTopology::TriangleList,
582
+
strip_index_format: None,
583
+
front_face: wgpu::FrontFace::Ccw,
584
+
cull_mode: Some(wgpu::Face::Back),
585
+
// Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE
586
+
polygon_mode: wgpu::PolygonMode::Fill,
587
+
// Requires Features::DEPTH_CLIP_CONTROL
588
+
unclipped_depth: false,
589
+
// Requires Features::CONSERVATIVE_RASTERIZATION
590
+
conservative: false,
591
+
},
592
+
depth_stencil: Some(wgpu::DepthStencilState {
593
+
format: wgpu::TextureFormat::Depth32Float,
594
+
depth_write_enabled: true,
595
+
depth_compare: wgpu::CompareFunction::Less,
596
+
stencil: wgpu::StencilState::default(),
597
+
bias: wgpu::DepthBiasState::default(),
598
+
}),
599
+
multisample: wgpu::MultisampleState {
600
+
count: 1,
601
+
mask: !0,
602
+
alpha_to_coverage_enabled: false,
603
+
},
604
+
multiview: None,
605
+
cache: None,
606
+
});
607
+
608
+
Pass {
609
+
pipeline: OneOrTwo::One(pipeline),
610
+
bind_group,
611
+
uniform_bufs: vec![camera_buffer, light_buffer],
612
+
}
613
+
};
614
+
615
+
let forward_pass = {
616
+
let camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
617
+
label: Some("Camera Buffer"),
618
+
contents: bytemuck::cast_slice(&[camera_uniform]),
619
+
usage: wgpu::BufferUsages::UNIFORM
620
+
| wgpu::BufferUsages::COPY_DST
621
+
| wgpu::BufferUsages::COPY_SRC,
622
+
});
623
+
let light_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
624
+
label: Some("Light VB"),
625
+
contents: bytemuck::cast_slice(&[light_uniform]),
626
+
usage: wgpu::BufferUsages::UNIFORM
627
+
| wgpu::BufferUsages::COPY_DST
628
+
| wgpu::BufferUsages::COPY_SRC,
629
+
});
630
+
631
+
let bind_group_layout =
632
+
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
633
+
entries: &[
634
+
// Camera positional Data
635
+
bgl_t(0),
636
+
// Light positional data
637
+
bgl_t(1),
638
+
// Shadowmap
639
+
wgpu::BindGroupLayoutEntry {
640
+
binding: 2,
641
+
visibility: wgpu::ShaderStages::FRAGMENT,
642
+
ty: wgpu::BindingType::Texture {
643
+
sample_type: wgpu::TextureSampleType::Depth,
644
+
view_dimension: wgpu::TextureViewDimension::D2,
645
+
multisampled: false,
646
+
},
647
+
count: None,
648
+
},
649
+
wgpu::BindGroupLayoutEntry {
650
+
binding: 3,
651
+
visibility: wgpu::ShaderStages::FRAGMENT,
652
+
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
653
+
count: None,
654
+
},
655
+
],
656
+
label: None,
657
+
});
658
+
659
+
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
660
+
layout: &bind_group_layout,
661
+
entries: &[
662
+
bge(0, camera_buffer.as_entire_binding()),
663
+
bge(1, light_buffer.as_entire_binding()),
664
+
bge(2, BindingResource::TextureView(&shadow_map.view)),
665
+
bge(3, BindingResource::Sampler(&shadow_map.sampler)),
666
+
],
667
+
label: None,
668
+
});
669
+
670
+
let render_pipeline = create_render_pipeline(
414
671
&device,
415
-
&render_pipeline_layout,
672
+
&device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
673
+
label: Some("Render Pipeline Layout"),
674
+
bind_group_layouts: &[&texture_bind_group_layout, &bind_group_layout],
675
+
push_constant_ranges: &[],
676
+
}),
416
677
surface_config.format,
417
678
Some(texture::Texture::DEPTH_FORMAT),
418
679
&[model::ModelVertex::desc(), InstanceRaw::desc()],
419
-
shader,
420
-
wgpu::PolygonMode::Fill,
421
-
)
422
-
};
423
-
424
-
//let fill_pipeline = render_pipeline(wgpu::PolygonMode::Fill);
425
-
let wireframe_render_pipeline = if (device.features() & wgpu::Features::POLYGON_MODE_LINE)
426
-
== wgpu::Features::POLYGON_MODE_LINE
427
-
{
428
-
Some({
429
-
let shader = wgpu::ShaderModuleDescriptor {
680
+
wgpu::ShaderModuleDescriptor {
430
681
label: Some("Normal Shader"),
431
682
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
432
-
};
433
-
create_render_pipeline(
434
-
&device,
435
-
&render_pipeline_layout,
436
-
surface_config.format,
437
-
Some(texture::Texture::DEPTH_FORMAT),
438
-
&[model::ModelVertex::desc(), InstanceRaw::desc()],
439
-
shader,
440
-
wgpu::PolygonMode::Line,
441
-
)
442
-
})
443
-
} else {
444
-
None
445
-
};
683
+
},
684
+
wgpu::PolygonMode::Fill,
685
+
Some("Normal Render Pipeline"),
686
+
);
446
687
447
-
let light_render_pipeline = {
448
-
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
449
-
label: Some("Light Pipeline Layout"),
450
-
bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout],
451
-
push_constant_ranges: &[],
452
-
});
453
-
let shader = wgpu::ShaderModuleDescriptor {
454
-
label: Some("Light Shader"),
455
-
source: wgpu::ShaderSource::Wgsl(include_str!("light.wgsl").into()),
456
-
};
457
-
create_render_pipeline(
688
+
log::info!("Pipeline/Light setup!");
689
+
let light_render_pipeline = create_render_pipeline(
458
690
&device,
459
-
&layout,
691
+
&device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
692
+
label: Some("Light Pipeline Layout"),
693
+
bind_group_layouts: &[&bind_group_layout],
694
+
push_constant_ranges: &[],
695
+
}),
460
696
surface_config.format,
461
697
Some(texture::Texture::DEPTH_FORMAT),
462
-
&[model::ModelVertex::desc()],
463
-
shader,
698
+
&[model::ModelVertex::desc(), InstanceRaw::desc()],
699
+
wgpu::ShaderModuleDescriptor {
700
+
label: Some("Light Shader"),
701
+
source: wgpu::ShaderSource::Wgsl(include_str!("light.wgsl").into()),
702
+
},
464
703
wgpu::PolygonMode::Fill,
465
-
)
704
+
Some("Light Render Pipeline"),
705
+
);
706
+
707
+
Pass {
708
+
pipeline: OneOrTwo::Two(render_pipeline, light_render_pipeline),
709
+
bind_group,
710
+
uniform_bufs: vec![camera_buffer, light_buffer],
711
+
}
466
712
};
713
+
714
+
log::debug!("Initialized!");
467
715
468
716
Self {
469
717
surface,
···
472
720
surface_config,
473
721
depth_texture,
474
722
camera: camera_state,
723
+
shadow_pass,
724
+
forward_pass,
475
725
interact: InteractState {
476
726
wireframe: false,
477
727
clear_color: wgpu::Color {
···
480
730
b: 0.3,
481
731
a: 1.0,
482
732
},
483
-
},
484
-
render_pipelines: RenderPipelines {
485
-
camera: render_pipeline,
486
-
camera_wireframe: wireframe_render_pipeline,
487
-
light: light_render_pipeline,
488
733
},
489
734
object: ObjectState {
490
735
model: obj_model,
···
493
738
remake: false,
494
739
},
495
740
light: LightState {
741
+
object: light,
496
742
uniform: light_uniform,
497
-
buffer: light_buffer,
498
-
bind_group: light_bind_group,
743
+
shadow_map,
499
744
},
500
745
}
501
746
}
···
507
752
508
753
self.surface_config.width = new_size.width;
509
754
self.surface_config.height = new_size.height;
510
-
self.camera.positioning.aspect =
755
+
self.camera.object.aspect =
511
756
self.surface_config.width as f32 / self.surface_config.height as f32;
512
757
self.surface.configure(&self.device, &self.surface_config);
513
758
···
531
776
return None;
532
777
}
533
778
534
-
let chunk_offset = IVec3::from(*coords).as_vec3() * (SPACE_BETWEEN * CHUNK_SIZE.0 as f32);
779
+
let chunk_offset =
780
+
IVec3::from(*coords).as_vec3() * (SPACE_BETWEEN * CHUNK_SIZE.0 as f32);
535
781
536
782
let mapping = |n| SPACE_BETWEEN * (n as f32 - CHUNK_SIZE.0 as f32 / 2.0);
537
783
let position = vec3(
···
552
798
}
553
799
554
800
pub fn update_instance_buf(&mut self, map: &WorldMap) {
555
-
let instances = Self::remake_instance_buf(&map);
801
+
let instances = Self::remake_instance_buf(map);
556
802
557
803
let instance_data = instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
558
804
let instance_buffer = self
···
585
831
label: Some("Render Encoder"),
586
832
});
587
833
588
-
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
589
-
label: Some("Render Pass"),
590
-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
591
-
view: &view,
592
-
resolve_target: None,
593
-
ops: wgpu::Operations {
594
-
load: wgpu::LoadOp::Clear(self.interact.clear_color),
595
-
store: wgpu::StoreOp::Store,
596
-
},
597
-
})],
598
-
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
599
-
view: &self.depth_texture.view,
600
-
depth_ops: Some(wgpu::Operations {
601
-
load: wgpu::LoadOp::Clear(1.0),
602
-
store: wgpu::StoreOp::Store,
834
+
log::debug!("Hi renderer!");
835
+
836
+
encoder.push_debug_group("Shadow pass");
837
+
use crate::gfx::model::DrawModel;
838
+
839
+
// Shadow-map Pass
840
+
{
841
+
let Pass {
842
+
pipeline,
843
+
bind_group,
844
+
uniform_bufs,
845
+
} = &mut self.shadow_pass;
846
+
847
+
encoder.copy_buffer_to_buffer(
848
+
&self.forward_pass.uniform_bufs[0],
849
+
0,
850
+
&uniform_bufs[0],
851
+
0,
852
+
size_of::<CameraUniform>() as wgpu::BufferAddress,
853
+
);
854
+
encoder.copy_buffer_to_buffer(
855
+
&self.forward_pass.uniform_bufs[1],
856
+
0,
857
+
&uniform_bufs[1],
858
+
0,
859
+
size_of::<CameraUniform>() as wgpu::BufferAddress,
860
+
);
861
+
862
+
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
863
+
label: Some("Shadow Render Pass"),
864
+
color_attachments: &[],
865
+
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
866
+
view: &self.light.shadow_map.view, // Shadow map written here
867
+
depth_ops: Some(wgpu::Operations {
868
+
load: wgpu::LoadOp::Clear(1.0),
869
+
store: wgpu::StoreOp::Store,
870
+
}),
871
+
stencil_ops: None,
872
+
}),
873
+
occlusion_query_set: None,
874
+
timestamp_writes: None,
875
+
});
876
+
render_pass.set_pipeline(pipeline.one());
877
+
render_pass.set_vertex_buffer(1, self.object.instance_buffer.slice(..));
878
+
879
+
render_pass.draw_light_model_instanced(
880
+
&self.object.model,
881
+
0..self.object.instances.len() as u32,
882
+
&[bind_group],
883
+
);
884
+
885
+
drop(render_pass);
886
+
}
887
+
888
+
encoder.pop_debug_group();
889
+
890
+
encoder.push_debug_group("Forward pass");
891
+
892
+
{
893
+
let Pass {
894
+
pipeline,
895
+
bind_group,
896
+
uniform_bufs,
897
+
} = &mut self.forward_pass;
898
+
899
+
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
900
+
label: Some("Forward Render Pass"),
901
+
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
902
+
view: &view,
903
+
resolve_target: None,
904
+
ops: wgpu::Operations {
905
+
load: wgpu::LoadOp::Clear(self.interact.clear_color),
906
+
store: wgpu::StoreOp::Store,
907
+
},
908
+
})],
909
+
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
910
+
view: &self.depth_texture.view,
911
+
depth_ops: Some(wgpu::Operations {
912
+
load: wgpu::LoadOp::Clear(1.0),
913
+
store: wgpu::StoreOp::Store,
914
+
}),
915
+
stencil_ops: None,
603
916
}),
604
-
stencil_ops: None,
605
-
}),
606
-
occlusion_query_set: None,
607
-
timestamp_writes: None,
608
-
});
917
+
occlusion_query_set: None,
918
+
timestamp_writes: None,
919
+
});
609
920
610
-
render_pass.set_vertex_buffer(1, self.object.instance_buffer.slice(..));
921
+
render_pass.set_vertex_buffer(1, self.object.instance_buffer.slice(..));
611
922
612
-
use crate::gfx::model::DrawLight;
613
-
render_pass.set_pipeline(&self.render_pipelines.light);
614
-
render_pass.draw_light_model(
615
-
&self.object.model,
616
-
&self.camera.bind_group,
617
-
&self.light.bind_group,
618
-
);
923
+
// use crate::gfx::model::DrawLight;
924
+
// render_pass.set_pipeline(pipeline.two().1);
925
+
// render_pass.draw_light_model(
926
+
// &self.object.model,
927
+
// &self.camera.bind_group,
928
+
// &self.light.bind_group,
929
+
// );
619
930
620
-
use crate::gfx::model::DrawModel;
621
-
render_pass.set_pipeline(
622
-
self.interact
623
-
.wireframe
624
-
.then_some(self.render_pipelines.camera_wireframe.as_ref())
625
-
.flatten()
626
-
.unwrap_or(&self.render_pipelines.camera),
627
-
);
931
+
// render_pass.set_pipeline(&self.render_pipelines.cam);
932
+
// render_pass.draw_model_instanced(
933
+
// &self.object.model,
934
+
// 0..self.object.instances.len() as u32,
935
+
// &self.camera.bind_group,
936
+
// &self.light.bind_group,
937
+
// );
628
938
629
-
render_pass.draw_model_instanced(
630
-
&self.object.model,
631
-
0..self.object.instances.len() as u32,
632
-
&self.camera.bind_group,
633
-
&self.light.bind_group,
634
-
);
939
+
/* render_pass.set_pipeline(
940
+
self.interact
941
+
.wireframe
942
+
.then_some(self.render_pipelines.camera_wireframe.as_ref())
943
+
.flatten()
944
+
.unwrap_or(&self.render_pipelines.camera),
945
+
);*/
946
+
947
+
render_pass.set_pipeline(pipeline.two().0);
948
+
949
+
render_pass.draw_model_instanced(
950
+
&self.object.model,
951
+
0..self.object.instances.len() as u32,
952
+
&[bind_group],
953
+
);
954
+
955
+
drop(render_pass);
956
+
}
635
957
636
958
// drop render pass before we submit to drop the mut borrow on encoder
637
-
drop(render_pass);
959
+
960
+
encoder.pop_debug_group();
638
961
639
962
// Layer EGUI on top of frame!
640
963
···
671
994
pub fn update(&mut self, world: &mut World) {
672
995
self.camera
673
996
.controller
674
-
.update_camera(&mut self.camera.positioning);
675
-
self.camera
676
-
.uniform
677
-
.update_view_proj(&self.camera.positioning);
997
+
.update_camera(&mut self.camera.object);
998
+
999
+
// dbg
1000
+
//self.camera.object.eye = self.light.uniform.view_pos;
1001
+
1002
+
self.camera.uniform.update_view_proj(&self.camera.object);
678
1003
self.queue.write_buffer(
679
-
&self.camera.buffer,
1004
+
&self.forward_pass.uniform_bufs[0],
680
1005
0,
681
1006
bytemuck::cast_slice(&[self.camera.uniform]),
682
1007
);
683
1008
684
-
let old_position: Vec3 = self.light.uniform.position;
685
-
self.light.uniform.position =
686
-
Quat::from_axis_angle(vec3(0.0, 1.0, 0.0), 0.01) * old_position;
1009
+
self.light.object.eye =
1010
+
Quat::from_axis_angle(vec3(0.0, 1.0, 0.0), 0.01) * self.light.object.eye;
1011
+
self.light.uniform.update_view_proj(&self.light.object);
1012
+
1013
+
// let old_position: Vec3 = self.light.uniform.view_pos;
1014
+
// self.light.uniform.view_pos =
1015
+
// Quat::from_axis_angle(vec3(0.0, 1.0, 0.0), 0.01) * old_position;
1016
+
// self.light
1017
+
// .uniform
1018
+
// .update_view_proj(self.surface_config.width as f32 / self.surface_config.height as f32);
1019
+
687
1020
self.queue.write_buffer(
688
-
&self.light.buffer,
1021
+
&self.forward_pass.uniform_bufs[1],
689
1022
0,
690
1023
bytemuck::cast_slice(&[self.light.uniform]),
691
1024
);
+2
-2
src/gfx/camera.rs
+2
-2
src/gfx/camera.rs
+46
src/gfx/light.rs
+46
src/gfx/light.rs
···
1
+
use std::f32::consts::PI;
2
+
3
+
use crate::gfx::camera::Camera;
4
+
use glam::{vec3, Mat4, Vec3, Vec4};
5
+
6
+
#[repr(C)]
7
+
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
8
+
pub(crate) struct LightUniform {
9
+
pub view_pos: Vec3,
10
+
_pad: u32,
11
+
pub view_proj: Mat4,
12
+
pub color: Vec3,
13
+
_pad2: u32,
14
+
}
15
+
impl LightUniform {
16
+
pub fn new(position: Vec3, color: Vec3) -> LightUniform {
17
+
LightUniform {
18
+
view_pos: position,
19
+
view_proj: {
20
+
let view = Mat4::look_at_rh(position, Vec3::ZERO, Vec3::Y);
21
+
let proj = Mat4::perspective_rh(PI / 2., 1.0, 0.1, 1000.0);
22
+
23
+
view * proj
24
+
},
25
+
color,
26
+
_pad: 0,
27
+
_pad2: 0,
28
+
}
29
+
}
30
+
31
+
pub fn update_view_proj(&mut self, aspect_ratio: f32) {
32
+
self.view_proj = {
33
+
let view = Mat4::look_at_rh(vec3(50., 20., 50.), Vec3::ZERO, Vec3::Y);
34
+
let proj = Mat4::perspective_rh(PI / 2., aspect_ratio, 0.1, 1000.0);
35
+
36
+
view * proj
37
+
};
38
+
}
39
+
40
+
// pub fn build_view_projection_matrix(&self) -> Mat4 {
41
+
// let view = Mat4::look_at_rh(self.eye, self.target, self.up);
42
+
// let proj = Mat4::perspective_rh(self.fovy, self.aspect, self.znear, self.zfar);
43
+
44
+
// proj * view
45
+
// }
46
+
}
+30
-79
src/gfx/model.rs
+30
-79
src/gfx/model.rs
···
1
-
use std::ops::Range;
2
-
3
1
use super::texture;
2
+
use std::ops::Range;
3
+
use wasm_bindgen::__rt::__wbindgen_exn_store;
4
4
5
5
pub trait Vertex {
6
6
fn desc() -> wgpu::VertexBufferLayout<'static>;
···
66
66
&mut self,
67
67
mesh: &'a Mesh,
68
68
material: &'a Material,
69
-
camera_bind_group: &'a wgpu::BindGroup,
70
-
light_bind_group: &'a wgpu::BindGroup,
69
+
bind_groups: &[&'a wgpu::BindGroup],
71
70
);
72
71
fn draw_mesh_instanced(
73
72
&mut self,
74
73
mesh: &'a Mesh,
75
74
material: &'a Material,
76
75
instances: Range<u32>,
77
-
camera_bind_group: &'a wgpu::BindGroup,
78
-
light_bind_group: &'a wgpu::BindGroup,
79
-
);
80
-
fn draw_model(
81
-
&mut self,
82
-
model: &'a Model,
83
-
camera_bind_group: &'a wgpu::BindGroup,
84
-
light_bind_group: &'a wgpu::BindGroup,
76
+
bind_groups: &[&'a wgpu::BindGroup],
85
77
);
78
+
fn draw_model(&mut self, model: &'a Model, bind_groups: &[&'a wgpu::BindGroup]);
86
79
fn draw_model_instanced(
87
80
&mut self,
88
81
model: &'a Model,
89
82
instances: Range<u32>,
90
-
camera_bind_group: &'a wgpu::BindGroup,
91
-
light_bind_group: &'a wgpu::BindGroup,
83
+
bind_groups: &[&'a wgpu::BindGroup],
92
84
);
93
85
}
94
86
···
100
92
&mut self,
101
93
mesh: &'b Mesh,
102
94
material: &'b Material,
103
-
camera_bind_group: &'b wgpu::BindGroup,
104
-
light_bind_group: &'b wgpu::BindGroup,
95
+
bind_groups: &[&'b wgpu::BindGroup],
105
96
) {
106
-
self.draw_mesh_instanced(mesh, material, 0..1, camera_bind_group, light_bind_group);
97
+
self.draw_mesh_instanced(mesh, material, 0..1, bind_groups);
107
98
}
108
99
109
100
fn draw_mesh_instanced(
···
111
102
mesh: &'b Mesh,
112
103
material: &'a Material,
113
104
instances: Range<u32>,
114
-
camera_bind_group: &'b wgpu::BindGroup,
115
-
light_bind_group: &'b wgpu::BindGroup,
105
+
bind_groups: &[&'b wgpu::BindGroup],
116
106
) {
117
107
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
118
108
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
119
109
self.set_bind_group(0, &material.bind_group, &[]);
120
-
self.set_bind_group(1, camera_bind_group, &[]);
121
-
self.set_bind_group(2, light_bind_group, &[]);
110
+
for (i, group) in bind_groups.iter().enumerate() {
111
+
self.set_bind_group((i + 1) as u32, *group, &[]);
112
+
}
122
113
self.draw_indexed(0..mesh.num_elements, 0, instances);
123
114
}
124
-
fn draw_model(
125
-
&mut self,
126
-
model: &'b Model,
127
-
camera_bind_group: &'b wgpu::BindGroup,
128
-
light_bind_group: &'b wgpu::BindGroup,
129
-
) {
130
-
self.draw_model_instanced(model, 0..1, camera_bind_group, light_bind_group);
115
+
fn draw_model(&mut self, model: &'b Model, bind_groups: &[&'b wgpu::BindGroup]) {
116
+
self.draw_model_instanced(model, 0..1, bind_groups);
131
117
}
132
118
133
119
fn draw_model_instanced(
134
120
&mut self,
135
121
model: &'b Model,
136
122
instances: Range<u32>,
137
-
camera_bind_group: &'b wgpu::BindGroup,
138
-
light_bind_group: &'b wgpu::BindGroup,
123
+
bind_groups: &[&'b wgpu::BindGroup],
139
124
) {
140
125
for mesh in &model.meshes {
141
126
let material = &model.materials[mesh.material];
142
-
self.draw_mesh_instanced(
143
-
mesh,
144
-
material,
145
-
instances.clone(),
146
-
camera_bind_group,
147
-
light_bind_group,
148
-
);
127
+
self.draw_mesh_instanced(mesh, material, instances.clone(), bind_groups);
149
128
}
150
129
}
151
130
}
152
131
153
132
pub trait DrawLight<'a> {
154
-
fn draw_light_mesh(
155
-
&mut self,
156
-
mesh: &'a Mesh,
157
-
camera_bind_group: &'a wgpu::BindGroup,
158
-
light_bind_group: &'a wgpu::BindGroup,
159
-
);
133
+
fn draw_light_mesh(&mut self, mesh: &'a Mesh, bind_groups: &[&'a wgpu::BindGroup]);
160
134
fn draw_light_mesh_instanced(
161
135
&mut self,
162
136
mesh: &'a Mesh,
163
137
instances: Range<u32>,
164
-
camera_bind_group: &'a wgpu::BindGroup,
165
-
light_bind_group: &'a wgpu::BindGroup,
138
+
bind_groups: &[&'a wgpu::BindGroup],
166
139
);
167
140
168
-
fn draw_light_model(
169
-
&mut self,
170
-
model: &'a Model,
171
-
camera_bind_group: &'a wgpu::BindGroup,
172
-
light_bind_group: &'a wgpu::BindGroup,
173
-
);
141
+
fn draw_light_model(&mut self, model: &'a Model, bind_groups: &[&'a wgpu::BindGroup]);
174
142
fn draw_light_model_instanced(
175
143
&mut self,
176
144
model: &'a Model,
177
145
instances: Range<u32>,
178
-
camera_bind_group: &'a wgpu::BindGroup,
179
-
light_bind_group: &'a wgpu::BindGroup,
146
+
bind_groups: &[&'a wgpu::BindGroup],
180
147
);
181
148
}
182
149
···
184
151
where
185
152
'b: 'a,
186
153
{
187
-
fn draw_light_mesh(
188
-
&mut self,
189
-
mesh: &'b Mesh,
190
-
camera_bind_group: &'b wgpu::BindGroup,
191
-
light_bind_group: &'b wgpu::BindGroup,
192
-
) {
193
-
self.draw_light_mesh_instanced(mesh, 0..1, camera_bind_group, light_bind_group);
154
+
fn draw_light_mesh(&mut self, mesh: &'b Mesh, bind_groups: &[&'b wgpu::BindGroup]) {
155
+
self.draw_light_mesh_instanced(mesh, 0..1, bind_groups);
194
156
}
195
157
196
158
fn draw_light_mesh_instanced(
197
159
&mut self,
198
160
mesh: &'b Mesh,
199
161
instances: Range<u32>,
200
-
camera_bind_group: &'b wgpu::BindGroup,
201
-
light_bind_group: &'b wgpu::BindGroup,
162
+
bind_groups: &[&'b wgpu::BindGroup],
202
163
) {
203
164
self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
204
165
self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
205
-
self.set_bind_group(0, camera_bind_group, &[]);
206
-
self.set_bind_group(1, light_bind_group, &[]);
166
+
for (i, group) in bind_groups.iter().enumerate() {
167
+
self.set_bind_group(i as u32, *group, &[]);
168
+
}
207
169
self.draw_indexed(0..mesh.num_elements, 0, instances);
208
170
}
209
171
210
-
fn draw_light_model(
211
-
&mut self,
212
-
model: &'b Model,
213
-
camera_bind_group: &'b wgpu::BindGroup,
214
-
light_bind_group: &'b wgpu::BindGroup,
215
-
) {
216
-
self.draw_light_model_instanced(model, 0..1, camera_bind_group, light_bind_group);
172
+
fn draw_light_model(&mut self, model: &'b Model, bind_groups: &[&'b wgpu::BindGroup]) {
173
+
self.draw_light_model_instanced(model, 0..1, bind_groups);
217
174
}
218
175
fn draw_light_model_instanced(
219
176
&mut self,
220
177
model: &'b Model,
221
178
instances: Range<u32>,
222
-
camera_bind_group: &'b wgpu::BindGroup,
223
-
light_bind_group: &'b wgpu::BindGroup,
179
+
bind_groups: &[&'b wgpu::BindGroup],
224
180
) {
225
181
for mesh in &model.meshes {
226
-
self.draw_light_mesh_instanced(
227
-
mesh,
228
-
instances.clone(),
229
-
camera_bind_group,
230
-
light_bind_group,
231
-
);
182
+
self.draw_light_mesh_instanced(mesh, instances.clone(), bind_groups);
232
183
}
233
184
}
234
185
}
+29
-19
src/gui.rs
+29
-19
src/gui.rs
···
2
2
use glam::{ivec2, ivec3, IVec2};
3
3
use winit::window::Window;
4
4
5
-
use crate::{gfx::Gfx, world::map::{chunk_scramble_dispatch, ChunkScramble}, world::World};
5
+
use crate::{
6
+
gfx::Gfx,
7
+
world::map::{chunk_scramble_dispatch, ChunkScramble},
8
+
world::World,
9
+
};
6
10
7
11
pub struct EguiRenderer {
8
12
state: egui_winit::State,
···
54
58
renderer,
55
59
frame_started: false,
56
60
scale_factor: 1.0,
57
-
chunk_influence: (0,0)
61
+
chunk_influence: (0, 0),
58
62
}
59
63
}
60
64
61
65
pub fn handle_input(&mut self, window: &Window, event: &winit::event::WindowEvent) -> bool {
62
-
let EventResponse {consumed, ..} = self.state.on_window_event(window, event);
66
+
let EventResponse { consumed, .. } = self.state.on_window_event(window, event);
63
67
consumed
64
68
}
65
69
···
83
87
}
84
88
85
89
#[cfg(not(target_arch = "wasm32"))]
86
-
self.ctx().set_pixels_per_point(screen_descriptor.pixels_per_point);
90
+
self.ctx()
91
+
.set_pixels_per_point(screen_descriptor.pixels_per_point);
87
92
88
93
let full_output = self.ctx().end_pass();
89
94
···
96
101
.tessellate(full_output.shapes, self.ctx().pixels_per_point());
97
102
98
103
#[cfg(target_arch = "wasm32")]
99
-
let tris = self
100
-
.ctx()
101
-
.tessellate(full_output.shapes, 1.0);
104
+
let tris = self.ctx().tessellate(full_output.shapes, 1.0);
102
105
103
106
for (id, image_delta) in &full_output.textures_delta.set {
104
107
self.renderer
···
168
171
169
172
ui.separator();
170
173
171
-
ui.add(egui::Slider::new(&mut gfx.camera.controller.speed, 0.1..=10.0).text("Cam Speed"));
174
+
ui.add(
175
+
egui::Slider::new(&mut gfx.camera.controller.speed, 0.1..=10.0)
176
+
.text("Cam Speed"),
177
+
);
172
178
173
179
ui.separator();
174
180
175
-
ui.label(format!("The camera is pointing at {:?}", gfx.camera.positioning.target));
176
-
ui.add(egui::Slider::new(&mut gfx.camera.positioning.eye.x, -500.0..=500.0).text("Cam X"));
177
-
ui.add(egui::Slider::new(&mut gfx.camera.positioning.eye.y, -500.0..=500.0).text("Cam Y"));
178
-
ui.add(egui::Slider::new(&mut gfx.camera.positioning.eye.z, -500.0..=500.0).text("Cam Z"));
181
+
ui.label(format!(
182
+
"The camera is pointing at {:?}",
183
+
gfx.camera.object.target
184
+
));
185
+
ui.add(
186
+
egui::Slider::new(&mut gfx.camera.object.eye.x, -500.0..=500.0).text("Cam X"),
187
+
);
188
+
ui.add(
189
+
egui::Slider::new(&mut gfx.camera.object.eye.y, -500.0..=500.0).text("Cam Y"),
190
+
);
191
+
ui.add(
192
+
egui::Slider::new(&mut gfx.camera.object.eye.z, -500.0..=500.0).text("Cam Z"),
193
+
);
179
194
180
195
ui.separator();
181
196
ui.horizontal(|ui| {
···
200
215
});
201
216
202
217
ui.horizontal(|ui| {
203
-
let pos = ivec3(chunk_x,0,chunk_z);
218
+
let pos = ivec3(chunk_x, 0, chunk_z);
204
219
205
220
if ui.button("Random").clicked() {
206
221
let c = chunk_scramble_dispatch(ChunkScramble::Random)(pos);
···
220
235
});
221
236
222
237
ui.separator();
223
-
224
238
225
239
ui.horizontal(|ui| {
226
-
227
240
if ui.button("Save").clicked() {
228
241
world.save().unwrap();
229
242
}
···
231
244
*world = World::load().unwrap();
232
245
gfx.object.remake = true;
233
246
}
234
-
235
247
});
236
-
237
-
238
248
});
239
249
240
250
self.scale_factor = scale_factor;
241
251
self.chunk_influence = (chunk_x, chunk_z);
242
252
}
243
-
}
253
+
}
+8
-8
src/lib.rs
+8
-8
src/lib.rs
···
38
38
use std::mem;
39
39
40
40
wgpu::VertexBufferLayout {
41
-
array_stride: mem::size_of::<InstanceRaw>() as wgpu::BufferAddress,
41
+
array_stride: size_of::<InstanceRaw>() as wgpu::BufferAddress,
42
42
step_mode: wgpu::VertexStepMode::Instance,
43
43
attributes: &[
44
44
wgpu::VertexAttribute {
···
47
47
format: wgpu::VertexFormat::Float32x4,
48
48
},
49
49
wgpu::VertexAttribute {
50
-
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
50
+
offset: size_of::<[f32; 4]>() as wgpu::BufferAddress,
51
51
shader_location: 6,
52
52
format: wgpu::VertexFormat::Float32x4,
53
53
},
54
54
wgpu::VertexAttribute {
55
-
offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
55
+
offset: size_of::<[f32; 8]>() as wgpu::BufferAddress,
56
56
shader_location: 7,
57
57
format: wgpu::VertexFormat::Float32x4,
58
58
},
59
59
wgpu::VertexAttribute {
60
-
offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
60
+
offset: size_of::<[f32; 12]>() as wgpu::BufferAddress,
61
61
shader_location: 8,
62
62
format: wgpu::VertexFormat::Float32x4,
63
63
},
64
64
wgpu::VertexAttribute {
65
-
offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress,
65
+
offset: size_of::<[f32; 16]>() as wgpu::BufferAddress,
66
66
shader_location: 9,
67
67
format: wgpu::VertexFormat::Float32x3,
68
68
},
69
69
wgpu::VertexAttribute {
70
-
offset: mem::size_of::<[f32; 19]>() as wgpu::BufferAddress,
70
+
offset: size_of::<[f32; 19]>() as wgpu::BufferAddress,
71
71
shader_location: 10,
72
72
format: wgpu::VertexFormat::Float32x3,
73
73
},
74
74
wgpu::VertexAttribute {
75
-
offset: mem::size_of::<[f32; 22]>() as wgpu::BufferAddress,
75
+
offset: size_of::<[f32; 22]>() as wgpu::BufferAddress,
76
76
shader_location: 11,
77
77
format: wgpu::VertexFormat::Float32x3,
78
78
},
···
88
88
console_log::init_with_level(log::Level::Debug).expect("Couldn't initialize logger");
89
89
} else {
90
90
//env_logger::init();
91
-
env_logger::builder().filter_level(log::LevelFilter::Info).init();
91
+
env_logger::builder().filter_level(log::LevelFilter::Warn).init();
92
92
}
93
93
}
94
94
}
+5
-9
src/light.wgsl
+5
-9
src/light.wgsl
···
5
5
@group(0) @binding(0)
6
6
var<uniform> camera: Camera;
7
7
8
-
struct Light {
9
-
position: vec3<f32>,
10
-
color: vec3<f32>,
11
-
}
12
-
13
-
@group(1) @binding(0)
14
-
var<uniform> light: Light;
8
+
@group(0) @binding(1)
9
+
var<uniform> light: Camera;
15
10
16
11
struct VertexInput {
17
12
@location(0) position: vec3<f32>,
···
27
22
model: VertexInput,
28
23
) -> VertexOutput {
29
24
let scale = 0.75;
25
+
let light_color = vec3<f32>(1.0, 1.0, 1.0);
30
26
var out: VertexOutput;
31
-
out.clip_position = camera.view_proj * vec4<f32>(model.position * scale + light.position, 1.0);
32
-
out.color = light.color;
27
+
out.clip_position = camera.view_proj * vec4<f32>(model.position * scale + light.view_pos.xyz, 1.0);
28
+
out.color = light_color;
33
29
return out;
34
30
}
35
31
+31
-12
src/shader.wgsl
+31
-12
src/shader.wgsl
···
18
18
@group(1) @binding(0)
19
19
var<uniform> camera: Camera;
20
20
21
+
@group(1) @binding(1)
22
+
var<uniform> light: Camera;
21
23
22
-
struct Light {
23
-
position: vec3<f32>,
24
-
color: vec3<f32>,
25
-
}
26
-
@group(2) @binding(0)
27
-
var<uniform> light: Light;
28
24
29
25
struct VertexInput {
30
26
@location(0) position: vec3<f32>,
···
74
70
@group(0) @binding(1)
75
71
var s_diffuse: sampler;
76
72
73
+
@group(1) @binding(2)
74
+
var t_shadow: texture_depth_2d;
75
+
@group(1) @binding(3)
76
+
var s_shadow: sampler_comparison;
77
+
78
+
79
+
fn fetch_shadow(homogeneous_coords: vec4<f32>) -> f32 {
80
+
if (homogeneous_coords.w <= 0.0) {
81
+
return 1.0;
82
+
}
83
+
// compensate for the Y-flip difference between the NDC and texture coordinates
84
+
let flip_correction = vec2<f32>(0.5, -0.5);
85
+
// compute texture coordinates for shadow lookup
86
+
let proj_correction = 1.0 / homogeneous_coords.w;
87
+
let light_local = homogeneous_coords.xy * flip_correction * proj_correction + vec2<f32>(0.5, 0.5);
88
+
// do the lookup, using HW PCF and comparison
89
+
return textureSampleCompareLevel(t_shadow, s_shadow, light_local, homogeneous_coords.z * proj_correction);
90
+
}
91
+
77
92
@fragment
78
93
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
94
+
let light_color = vec3<f32>(1.0, 1.0, 1.0);
95
+
79
96
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
80
97
81
98
let ambient_strength = 0.1;
82
-
let ambient_color = light.color * ambient_strength;
99
+
let ambient_color = light_color * ambient_strength;
83
100
84
-
let light_dir = normalize(light.position - in.world_position);
101
+
let light_dir = normalize(light.view_pos.xyz - in.world_position.xyz);
85
102
let diffuse_strength = max(dot(in.world_normal, light_dir), 0.0);
86
-
let diffuse_color = light.color * diffuse_strength;
103
+
let diffuse_color = light_color * diffuse_strength;
87
104
88
-
let view_dir = normalize(camera.view_pos.xyz - in.world_position);
105
+
let view_dir = normalize(camera.view_pos.xyz - in.world_position.xyz);
89
106
let half_dir = normalize(view_dir + light_dir);
90
107
91
108
let specular_strength = pow(max(dot(in.world_normal, half_dir), 0.0), 32.0);
92
-
let specular_color = specular_strength * light.color;
109
+
let specular_color = specular_strength * light_color;
93
110
94
-
let result = (ambient_color + diffuse_color + specular_color) * object_color.xyz;
111
+
let shadow = fetch_shadow(light.view_proj * vec4<f32>(in.world_position, 1.0));
112
+
113
+
let result = (ambient_color + diffuse_color + specular_color) * shadow * object_color.xyz;
95
114
96
115
return vec4<f32>(result, object_color.a);
97
116
}
+50
src/shadows.wgsl
+50
src/shadows.wgsl
···
1
+
// Vertex shader
2
+
3
+
// TODO CITE
4
+
// Somewhat referenced from:
5
+
// https://github.com/gfx-rs/wgpu/blob/trunk/examples/features/src/shadow/shader.wgsl
6
+
7
+
struct InstanceInput {
8
+
@location(5) model_matrix_0: vec4<f32>,
9
+
@location(6) model_matrix_1: vec4<f32>,
10
+
@location(7) model_matrix_2: vec4<f32>,
11
+
@location(8) model_matrix_3: vec4<f32>,
12
+
13
+
@location(9) normal_matrix_0: vec3<f32>,
14
+
@location(10) normal_matrix_1: vec3<f32>,
15
+
@location(11) normal_matrix_2: vec3<f32>,
16
+
};
17
+
18
+
struct Camera {
19
+
view_pos: vec4<f32>,
20
+
view_proj: mat4x4<f32>,
21
+
}
22
+
@group(0) @binding(0)
23
+
var<uniform> camera: Camera;
24
+
25
+
@group(0) @binding(1)
26
+
var<uniform> light: Camera;
27
+
28
+
struct VertexInput {
29
+
@location(0) position: vec3<f32>,
30
+
@location(1) tex_coords: vec2<f32>,
31
+
@location(2) normal: vec3<f32>,
32
+
}
33
+
34
+
@vertex
35
+
fn vs_main(
36
+
model: VertexInput,
37
+
instance: InstanceInput,
38
+
) -> @builtin(position) vec4<f32> {
39
+
40
+
let model_matrix = mat4x4<f32> (
41
+
instance.model_matrix_0,
42
+
instance.model_matrix_1,
43
+
instance.model_matrix_2,
44
+
instance.model_matrix_3,
45
+
);
46
+
47
+
let world_position: vec4<f32> = model_matrix * vec4<f32>(model.position, 1.0);
48
+
49
+
return light.view_proj * world_position;
50
+
}
+14
-13
src/world/map.rs
+14
-13
src/world/map.rs
···
1
1
use bincode::{Decode, Encode};
2
2
use glam::{ivec2, ivec3, IVec2, IVec3};
3
3
use itertools::Itertools;
4
-
use rand::{distr::{Distribution, StandardUniform}, Rng};
4
+
use rand::{
5
+
distr::{Distribution, StandardUniform},
6
+
Rng,
7
+
};
5
8
use std::collections::HashMap;
6
9
7
10
// I have arbitrarily decided that this is (x,z,y) where +y is up.
···
45
48
}
46
49
}
47
50
48
-
49
51
fn new_chunk(world_pos: IVec3) -> Chunk {
50
52
let blocks = itertools::iproduct!(0..CHUNK_SIZE.0, 0..CHUNK_SIZE.1, 0..CHUNK_SIZE.2)
51
53
.map(|(x, z, y)| {
52
-
let tile_pos = ivec3(x as _,y as _,z as _);
54
+
let tile_pos = ivec3(x as _, y as _, z as _);
53
55
54
56
// let (xf, zf, yf) = (
55
57
// (x as i32 + (world_x * CHUNK_SIZE.0 as i32)) as f32,
···
58
60
// );
59
61
let tile_pos_worldspace = (tile_pos + (world_pos * CHUNK_SIZE.0 as i32)).as_vec3();
60
62
61
-
let sines = f32::sin(tile_pos_worldspace.x * 0.1) + f32::sin(tile_pos_worldspace.z * 0.1);
63
+
let sines =
64
+
f32::sin(tile_pos_worldspace.x * 0.1) + f32::sin(tile_pos_worldspace.z * 0.1);
62
65
63
66
// Pretty arbitrary numbers! Just trying to get something interesting
64
-
let n = (((sines / 4. + 0.5) * CHUNK_SIZE.2 as f32).round() as i32) <= tile_pos_worldspace.y as _;
67
+
let n = (((sines / 4. + 0.5) * CHUNK_SIZE.2 as f32).round() as i32)
68
+
<= tile_pos_worldspace.y as _;
65
69
66
70
if n {
67
71
Block::Brick
···
82
86
let mut chunks = HashMap::new();
83
87
84
88
for (x, z) in itertools::iproduct!(iter.clone(), iter) {
85
-
let p = ivec3(x,0,z);
89
+
let p = ivec3(x, 0, z);
86
90
chunks.insert(p.into(), new_chunk(p));
87
91
chunks.insert(p.with_y(1).into(), new_chunk(p.with_y(1)));
88
-
89
92
}
90
93
91
94
WorldMap { chunks }
···
106
109
.collect_array()
107
110
.unwrap(),
108
111
},
109
-
C::Random => |_| {
110
-
Chunk {
111
-
blocks: rand::rng().random()
112
-
}
113
-
}
112
+
C::Random => |_| Chunk {
113
+
blocks: rand::rng().random(),
114
+
},
114
115
}
115
116
}
116
117
···
118
119
Normal,
119
120
Inverse,
120
121
Random,
121
-
}
122
+
}