debug rendering
This commit is contained in:
@@ -143,7 +143,7 @@ pub fn render_collider_debug() -> Vec<DrawCall>
|
|||||||
index_buffer: wireframe_box.index_buffer.clone(),
|
index_buffer: wireframe_box.index_buffer.clone(),
|
||||||
num_indices: wireframe_box.num_indices,
|
num_indices: wireframe_box.num_indices,
|
||||||
model,
|
model,
|
||||||
pipeline: Pipeline::Standard,
|
pipeline: Pipeline::DebugLines,
|
||||||
instance_buffer: Some(instance_buffer),
|
instance_buffer: Some(instance_buffer),
|
||||||
num_instances: 1,
|
num_instances: 1,
|
||||||
tile_scale: 4.0,
|
tile_scale: 4.0,
|
||||||
@@ -176,7 +176,7 @@ pub fn render_collider_debug() -> Vec<DrawCall>
|
|||||||
index_buffer: heightfield_mesh.index_buffer.clone(),
|
index_buffer: heightfield_mesh.index_buffer.clone(),
|
||||||
num_indices: heightfield_mesh.num_indices,
|
num_indices: heightfield_mesh.num_indices,
|
||||||
model: Mat4::IDENTITY,
|
model: Mat4::IDENTITY,
|
||||||
pipeline: Pipeline::Standard,
|
pipeline: Pipeline::DebugLines,
|
||||||
instance_buffer: Some(instance_buffer),
|
instance_buffer: Some(instance_buffer),
|
||||||
num_instances: 1,
|
num_instances: 1,
|
||||||
tile_scale: 4.0,
|
tile_scale: 4.0,
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
pub mod collider_debug;
|
pub mod collider_debug;
|
||||||
|
pub mod mode;
|
||||||
|
|
||||||
|
pub use mode::DebugMode;
|
||||||
|
|||||||
46
src/debug/mode.rs
Normal file
46
src/debug/mode.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum DebugMode
|
||||||
|
{
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Normals,
|
||||||
|
Uv,
|
||||||
|
Depth,
|
||||||
|
Wireframe,
|
||||||
|
Colliders,
|
||||||
|
ShadowMap,
|
||||||
|
SnowLight,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugMode
|
||||||
|
{
|
||||||
|
pub fn cycle(self) -> Self
|
||||||
|
{
|
||||||
|
match self
|
||||||
|
{
|
||||||
|
DebugMode::None => DebugMode::Normals,
|
||||||
|
DebugMode::Normals => DebugMode::Uv,
|
||||||
|
DebugMode::Uv => DebugMode::Depth,
|
||||||
|
DebugMode::Depth => DebugMode::Wireframe,
|
||||||
|
DebugMode::Wireframe => DebugMode::Colliders,
|
||||||
|
DebugMode::Colliders => DebugMode::ShadowMap,
|
||||||
|
DebugMode::ShadowMap => DebugMode::SnowLight,
|
||||||
|
DebugMode::SnowLight => DebugMode::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_u32(self) -> u32
|
||||||
|
{
|
||||||
|
match self
|
||||||
|
{
|
||||||
|
DebugMode::None => 0,
|
||||||
|
DebugMode::Normals => 1,
|
||||||
|
DebugMode::Uv => 2,
|
||||||
|
DebugMode::Depth => 3,
|
||||||
|
DebugMode::Wireframe => 4,
|
||||||
|
DebugMode::Colliders => 5,
|
||||||
|
DebugMode::ShadowMap => 6,
|
||||||
|
DebugMode::SnowLight => 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/main.rs
15
src/main.rs
@@ -16,6 +16,8 @@ mod texture;
|
|||||||
mod utility;
|
mod utility;
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
|
use crate::debug::{collider_debug, DebugMode};
|
||||||
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use glam::Vec3;
|
use glam::Vec3;
|
||||||
@@ -94,6 +96,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|||||||
render::set_snow_depth(&snow_layer.depth_texture_view);
|
render::set_snow_depth(&snow_layer.depth_texture_view);
|
||||||
|
|
||||||
let mut noclip_mode = true;
|
let mut noclip_mode = true;
|
||||||
|
let mut debug_mode = DebugMode::default();
|
||||||
|
|
||||||
let camera_entity = CameraBundle {
|
let camera_entity = CameraBundle {
|
||||||
position: camera_spawn,
|
position: camera_spawn,
|
||||||
@@ -146,6 +149,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|||||||
|
|
||||||
noclip_toggle_system(&mut world, &input_state, camera_entity, &mut noclip_mode);
|
noclip_toggle_system(&mut world, &input_state, camera_entity, &mut noclip_mode);
|
||||||
|
|
||||||
|
if input_state.debug_cycle_just_pressed
|
||||||
|
{
|
||||||
|
debug_mode = debug_mode.cycle();
|
||||||
|
println!("Debug mode: {:?}", debug_mode);
|
||||||
|
}
|
||||||
|
|
||||||
camera_input_system(&mut world, &input_state);
|
camera_input_system(&mut world, &input_state);
|
||||||
|
|
||||||
if noclip_mode
|
if noclip_mode
|
||||||
@@ -183,6 +192,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|||||||
let mut draw_calls = render_system(&world);
|
let mut draw_calls = render_system(&world);
|
||||||
draw_calls.extend(snow_layer.get_draw_calls());
|
draw_calls.extend(snow_layer.get_draw_calls());
|
||||||
|
|
||||||
|
if debug_mode == DebugMode::Colliders
|
||||||
|
{
|
||||||
|
draw_calls.extend(collider_debug::render_collider_debug());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((camera_entity, camera_component)) = world.active_camera()
|
if let Some((camera_entity, camera_component)) = world.active_camera()
|
||||||
{
|
{
|
||||||
if let Some(camera_transform) = world.transforms.get(camera_entity)
|
if let Some(camera_transform) = world.transforms.get(camera_entity)
|
||||||
@@ -201,6 +215,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>>
|
|||||||
&draw_calls,
|
&draw_calls,
|
||||||
time,
|
time,
|
||||||
delta,
|
delta,
|
||||||
|
debug_mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
232
src/render/debug_overlay.rs
Normal file
232
src/render/debug_overlay.rs
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
use crate::postprocess::ScreenVertex;
|
||||||
|
|
||||||
|
pub struct DebugOverlay
|
||||||
|
{
|
||||||
|
pipeline_shadow: wgpu::RenderPipeline,
|
||||||
|
pipeline_snow_light: wgpu::RenderPipeline,
|
||||||
|
shadow_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
|
snow_light_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugOverlay
|
||||||
|
{
|
||||||
|
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self
|
||||||
|
{
|
||||||
|
let shader_source = std::fs::read_to_string("src/shaders/debug_overlay.wgsl")
|
||||||
|
.expect("Failed to read debug_overlay.wgsl");
|
||||||
|
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: Some("Debug Overlay Shader"),
|
||||||
|
source: wgpu::ShaderSource::Wgsl(shader_source.into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let shadow_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("Shadow Debug Bind Group Layout"),
|
||||||
|
entries: &[wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
sample_type: wgpu::TextureSampleType::Depth,
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2Array,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
let snow_light_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("Snow Light Debug Bind Group Layout"),
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Texture {
|
||||||
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 2,
|
||||||
|
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let shadow_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Shadow Debug Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[&shadow_bind_group_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
let snow_light_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Snow Light Debug Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[&snow_light_bind_group_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
let color_target = wgpu::ColorTargetState {
|
||||||
|
format,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pipeline_shadow = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Shadow Debug Pipeline"),
|
||||||
|
layout: Some(&shadow_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("vs_main"),
|
||||||
|
buffers: &[ScreenVertex::desc()],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("fs_shadow_map"),
|
||||||
|
targets: &[Some(color_target.clone())],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
cull_mode: None,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState::default(),
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let pipeline_snow_light =
|
||||||
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Snow Light Debug Pipeline"),
|
||||||
|
layout: Some(&snow_light_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("vs_main"),
|
||||||
|
buffers: &[ScreenVertex::desc()],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("fs_snow_light"),
|
||||||
|
targets: &[Some(color_target)],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
cull_mode: None,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState::default(),
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pipeline_shadow,
|
||||||
|
pipeline_snow_light,
|
||||||
|
shadow_bind_group_layout,
|
||||||
|
snow_light_bind_group_layout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_shadow_map(
|
||||||
|
&self,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
target: &wgpu::TextureView,
|
||||||
|
shadow_view: &wgpu::TextureView,
|
||||||
|
quad_vb: &wgpu::Buffer,
|
||||||
|
quad_ib: &wgpu::Buffer,
|
||||||
|
quad_num_indices: u32,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("Shadow Debug Bind Group"),
|
||||||
|
layout: &self.shadow_bind_group_layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(shadow_view),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Shadow Debug Pass"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: target,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
depth_slice: None,
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
pass.set_pipeline(&self.pipeline_shadow);
|
||||||
|
pass.set_bind_group(0, &bind_group, &[]);
|
||||||
|
pass.set_vertex_buffer(0, quad_vb.slice(..));
|
||||||
|
pass.set_index_buffer(quad_ib.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
|
pass.draw_indexed(0..quad_num_indices, 0, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_snow_light(
|
||||||
|
&self,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
target: &wgpu::TextureView,
|
||||||
|
snow_light_view: &wgpu::TextureView,
|
||||||
|
snow_light_sampler: &wgpu::Sampler,
|
||||||
|
quad_vb: &wgpu::Buffer,
|
||||||
|
quad_ib: &wgpu::Buffer,
|
||||||
|
quad_num_indices: u32,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("Snow Light Debug Bind Group"),
|
||||||
|
layout: &self.snow_light_bind_group_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::TextureView(snow_light_view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 2,
|
||||||
|
resource: wgpu::BindingResource::Sampler(snow_light_sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Snow Light Debug Pass"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: target,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
depth_slice: None,
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
pass.set_pipeline(&self.pipeline_snow_light);
|
||||||
|
pass.set_bind_group(0, &bind_group, &[]);
|
||||||
|
pass.set_vertex_buffer(0, quad_vb.slice(..));
|
||||||
|
pass.set_index_buffer(quad_ib.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
|
pass.draw_indexed(0..quad_num_indices, 0, 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
mod bind_group;
|
mod bind_group;
|
||||||
|
mod debug_overlay;
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
mod shadow;
|
mod shadow;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
pub use types::{DrawCall, Pipeline, Spotlight, SpotlightRaw, Uniforms, MAX_SPOTLIGHTS};
|
pub use types::{DrawCall, Pipeline, Spotlight, SpotlightRaw, Uniforms, MAX_SPOTLIGHTS};
|
||||||
|
|
||||||
|
use crate::debug::DebugMode;
|
||||||
use crate::postprocess::{create_blit_pipeline, create_fullscreen_quad, LowResFramebuffer};
|
use crate::postprocess::{create_blit_pipeline, create_fullscreen_quad, LowResFramebuffer};
|
||||||
use crate::texture::{DitherTextures, FlowmapTexture};
|
use crate::texture::{DitherTextures, FlowmapTexture};
|
||||||
|
use pipeline::{create_debug_lines_pipeline, create_main_pipeline, create_snow_clipmap_pipeline,
|
||||||
|
create_wireframe_pipeline};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use pipeline::{create_main_pipeline, create_snow_clipmap_pipeline};
|
|
||||||
|
|
||||||
pub struct Renderer
|
pub struct Renderer
|
||||||
{
|
{
|
||||||
pub device: wgpu::Device,
|
pub device: wgpu::Device,
|
||||||
@@ -22,6 +24,10 @@ pub struct Renderer
|
|||||||
|
|
||||||
standard_pipeline: wgpu::RenderPipeline,
|
standard_pipeline: wgpu::RenderPipeline,
|
||||||
snow_clipmap_pipeline: wgpu::RenderPipeline,
|
snow_clipmap_pipeline: wgpu::RenderPipeline,
|
||||||
|
wireframe_pipeline: Option<wgpu::RenderPipeline>,
|
||||||
|
debug_lines_pipeline: Option<wgpu::RenderPipeline>,
|
||||||
|
debug_overlay: Option<debug_overlay::DebugOverlay>,
|
||||||
|
wireframe_supported: bool,
|
||||||
|
|
||||||
uniform_buffer: wgpu::Buffer,
|
uniform_buffer: wgpu::Buffer,
|
||||||
bind_group_layout: wgpu::BindGroupLayout,
|
bind_group_layout: wgpu::BindGroupLayout,
|
||||||
@@ -84,8 +90,21 @@ impl Renderer
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| "Failed to find adapter")?;
|
.map_err(|_| "Failed to find adapter")?;
|
||||||
|
|
||||||
|
let wireframe_supported =
|
||||||
|
adapter.features().contains(wgpu::Features::POLYGON_MODE_LINE);
|
||||||
|
let required_features = if wireframe_supported
|
||||||
|
{
|
||||||
|
wgpu::Features::POLYGON_MODE_LINE
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wgpu::Features::empty()
|
||||||
|
};
|
||||||
let (device, queue) = adapter
|
let (device, queue) = adapter
|
||||||
.request_device(&wgpu::DeviceDescriptor::default())
|
.request_device(&wgpu::DeviceDescriptor {
|
||||||
|
required_features,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let size = window.size();
|
let size = window.size();
|
||||||
@@ -442,6 +461,20 @@ impl Renderer
|
|||||||
|
|
||||||
let blit_pipeline = create_blit_pipeline(&device, config.format, &blit_bind_group_layout);
|
let blit_pipeline = create_blit_pipeline(&device, config.format, &blit_bind_group_layout);
|
||||||
|
|
||||||
|
let wireframe_pipeline = if wireframe_supported
|
||||||
|
{
|
||||||
|
Some(create_wireframe_pipeline(&device, config.format, &bind_group_layout))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let debug_lines_pipeline =
|
||||||
|
Some(create_debug_lines_pipeline(&device, config.format, &bind_group_layout));
|
||||||
|
|
||||||
|
let debug_overlay = Some(debug_overlay::DebugOverlay::new(&device, config.format));
|
||||||
|
|
||||||
let shadow_bind_group_layout =
|
let shadow_bind_group_layout =
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
label: Some("Shadow Bind Group Layout"),
|
label: Some("Shadow Bind Group Layout"),
|
||||||
@@ -465,6 +498,10 @@ impl Renderer
|
|||||||
framebuffer,
|
framebuffer,
|
||||||
standard_pipeline,
|
standard_pipeline,
|
||||||
snow_clipmap_pipeline,
|
snow_clipmap_pipeline,
|
||||||
|
wireframe_pipeline,
|
||||||
|
debug_lines_pipeline,
|
||||||
|
debug_overlay,
|
||||||
|
wireframe_supported,
|
||||||
uniform_buffer,
|
uniform_buffer,
|
||||||
bind_group_layout,
|
bind_group_layout,
|
||||||
bind_group,
|
bind_group,
|
||||||
@@ -508,6 +545,7 @@ impl Renderer
|
|||||||
draw_calls: &[DrawCall],
|
draw_calls: &[DrawCall],
|
||||||
time: f32,
|
time: f32,
|
||||||
delta_time: f32,
|
delta_time: f32,
|
||||||
|
debug_mode: DebugMode,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let light_view_projections = self.calculate_light_view_projections();
|
let light_view_projections = self.calculate_light_view_projections();
|
||||||
@@ -563,6 +601,7 @@ impl Renderer
|
|||||||
draw_call.enable_dissolve,
|
draw_call.enable_dissolve,
|
||||||
draw_call.enable_snow_light,
|
draw_call.enable_snow_light,
|
||||||
&self.spotlights,
|
&self.spotlights,
|
||||||
|
debug_mode.as_u32(),
|
||||||
);
|
);
|
||||||
self.queue
|
self.queue
|
||||||
.write_buffer(&self.uniform_buffer, 0, bytemuck::cast_slice(&[uniforms]));
|
.write_buffer(&self.uniform_buffer, 0, bytemuck::cast_slice(&[uniforms]));
|
||||||
@@ -614,6 +653,10 @@ impl Renderer
|
|||||||
{
|
{
|
||||||
Pipeline::Standard => &self.standard_pipeline,
|
Pipeline::Standard => &self.standard_pipeline,
|
||||||
Pipeline::SnowClipmap => &self.snow_clipmap_pipeline,
|
Pipeline::SnowClipmap => &self.snow_clipmap_pipeline,
|
||||||
|
Pipeline::DebugLines => self
|
||||||
|
.debug_lines_pipeline
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(&self.standard_pipeline),
|
||||||
};
|
};
|
||||||
render_pass.set_pipeline(pipeline);
|
render_pass.set_pipeline(pipeline);
|
||||||
render_pass.set_bind_group(0, &self.bind_group, &[]);
|
render_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||||
@@ -636,6 +679,138 @@ impl Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if debug_mode == DebugMode::Wireframe
|
||||||
|
{
|
||||||
|
if let Some(ref wireframe_pipeline) = self.wireframe_pipeline
|
||||||
|
{
|
||||||
|
for draw_call in draw_calls.iter()
|
||||||
|
{
|
||||||
|
if matches!(draw_call.pipeline, Pipeline::SnowClipmap | Pipeline::DebugLines)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let uniforms = Uniforms::new(
|
||||||
|
draw_call.model,
|
||||||
|
*view,
|
||||||
|
*projection,
|
||||||
|
&light_view_projections,
|
||||||
|
camera_position,
|
||||||
|
player_position,
|
||||||
|
self.terrain_height_scale,
|
||||||
|
time,
|
||||||
|
self.shadow_bias,
|
||||||
|
draw_call.tile_scale,
|
||||||
|
draw_call.enable_dissolve,
|
||||||
|
draw_call.enable_snow_light,
|
||||||
|
&self.spotlights,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
self.queue.write_buffer(
|
||||||
|
&self.uniform_buffer,
|
||||||
|
0,
|
||||||
|
bytemuck::cast_slice(&[uniforms]),
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut wire_pass =
|
||||||
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Wireframe Pass"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: &self.framebuffer.view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
depth_slice: None,
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: Some(
|
||||||
|
wgpu::RenderPassDepthStencilAttachment {
|
||||||
|
view: &self.framebuffer.depth_view,
|
||||||
|
depth_ops: Some(wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
}),
|
||||||
|
stencil_ops: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
wire_pass.set_pipeline(wireframe_pipeline);
|
||||||
|
wire_pass.set_bind_group(0, &self.bind_group, &[]);
|
||||||
|
wire_pass.set_vertex_buffer(0, draw_call.vertex_buffer.slice(..));
|
||||||
|
|
||||||
|
if let Some(ref instance_buffer) = draw_call.instance_buffer
|
||||||
|
{
|
||||||
|
wire_pass.set_vertex_buffer(1, instance_buffer.slice(..));
|
||||||
|
}
|
||||||
|
|
||||||
|
wire_pass.set_index_buffer(
|
||||||
|
draw_call.index_buffer.slice(..),
|
||||||
|
wgpu::IndexFormat::Uint32,
|
||||||
|
);
|
||||||
|
wire_pass.draw_indexed(
|
||||||
|
0..draw_call.num_indices,
|
||||||
|
0,
|
||||||
|
0..draw_call.num_instances,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug_mode == DebugMode::ShadowMap
|
||||||
|
{
|
||||||
|
if let Some(ref overlay) = self.debug_overlay
|
||||||
|
{
|
||||||
|
let shadow_view = &self.shadow_map_view;
|
||||||
|
let framebuffer_view = &self.framebuffer.view;
|
||||||
|
let quad_vb = &self.quad_vb;
|
||||||
|
let quad_ib = &self.quad_ib;
|
||||||
|
let quad_num = self.quad_num_indices;
|
||||||
|
let device = &self.device;
|
||||||
|
overlay.render_shadow_map(
|
||||||
|
&mut encoder,
|
||||||
|
framebuffer_view,
|
||||||
|
shadow_view,
|
||||||
|
quad_vb,
|
||||||
|
quad_ib,
|
||||||
|
quad_num,
|
||||||
|
device,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if debug_mode == DebugMode::SnowLight
|
||||||
|
{
|
||||||
|
if let Some(ref overlay) = self.debug_overlay
|
||||||
|
{
|
||||||
|
let snow_light_view = self
|
||||||
|
.snow_light_accumulation
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| s.read_view())
|
||||||
|
.unwrap_or(&self.dummy_snow_light_view);
|
||||||
|
let framebuffer_view = &self.framebuffer.view;
|
||||||
|
let quad_vb = &self.quad_vb;
|
||||||
|
let quad_ib = &self.quad_ib;
|
||||||
|
let quad_num = self.quad_num_indices;
|
||||||
|
let device = &self.device;
|
||||||
|
let sampler = &self.dummy_snow_light_sampler;
|
||||||
|
overlay.render_snow_light(
|
||||||
|
&mut encoder,
|
||||||
|
framebuffer_view,
|
||||||
|
snow_light_view,
|
||||||
|
sampler,
|
||||||
|
quad_vb,
|
||||||
|
quad_ib,
|
||||||
|
quad_num,
|
||||||
|
device,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
|
|
||||||
let frame = match self.surface.get_current_texture()
|
let frame = match self.surface.get_current_texture()
|
||||||
@@ -849,6 +1024,7 @@ pub fn render(
|
|||||||
draw_calls: &[DrawCall],
|
draw_calls: &[DrawCall],
|
||||||
time: f32,
|
time: f32,
|
||||||
delta_time: f32,
|
delta_time: f32,
|
||||||
|
debug_mode: DebugMode,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GLOBAL_RENDERER.with(|r| {
|
GLOBAL_RENDERER.with(|r| {
|
||||||
@@ -862,6 +1038,7 @@ pub fn render(
|
|||||||
draw_calls,
|
draw_calls,
|
||||||
time,
|
time,
|
||||||
delta_time,
|
delta_time,
|
||||||
|
debug_mode,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,6 +136,150 @@ pub fn create_main_pipeline(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_wireframe_pipeline(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
format: wgpu::TextureFormat,
|
||||||
|
bind_group_layout: &wgpu::BindGroupLayout,
|
||||||
|
) -> wgpu::RenderPipeline
|
||||||
|
{
|
||||||
|
let compiler = Wesl::new("src/shaders");
|
||||||
|
let shader_source = compiler
|
||||||
|
.compile(&"package::main".parse().unwrap())
|
||||||
|
.inspect_err(|e| eprintln!("WESL error: {e}"))
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: Some("Wireframe Shader"),
|
||||||
|
source: wgpu::ShaderSource::Wgsl(shader_source.into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Wireframe Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[bind_group_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Wireframe Pipeline"),
|
||||||
|
layout: Some(&render_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("vs_main"),
|
||||||
|
buffers: &[
|
||||||
|
crate::loaders::mesh::Vertex::desc(),
|
||||||
|
crate::loaders::mesh::InstanceRaw::desc(),
|
||||||
|
],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("fs_main"),
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
strip_index_format: None,
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: None,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Line,
|
||||||
|
unclipped_depth: false,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
|
format: wgpu::TextureFormat::Depth32Float,
|
||||||
|
depth_write_enabled: false,
|
||||||
|
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||||
|
stencil: wgpu::StencilState::default(),
|
||||||
|
bias: wgpu::DepthBiasState::default(),
|
||||||
|
}),
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_debug_lines_pipeline(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
format: wgpu::TextureFormat,
|
||||||
|
bind_group_layout: &wgpu::BindGroupLayout,
|
||||||
|
) -> wgpu::RenderPipeline
|
||||||
|
{
|
||||||
|
let compiler = Wesl::new("src/shaders");
|
||||||
|
let shader_source = compiler
|
||||||
|
.compile(&"package::main".parse().unwrap())
|
||||||
|
.inspect_err(|e| eprintln!("WESL error: {e}"))
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: Some("Debug Lines Shader"),
|
||||||
|
source: wgpu::ShaderSource::Wgsl(shader_source.into()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("Debug Lines Pipeline Layout"),
|
||||||
|
bind_group_layouts: &[bind_group_layout],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("Debug Lines Pipeline"),
|
||||||
|
layout: Some(&render_pipeline_layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("vs_main"),
|
||||||
|
buffers: &[
|
||||||
|
crate::loaders::mesh::Vertex::desc(),
|
||||||
|
crate::loaders::mesh::InstanceRaw::desc(),
|
||||||
|
],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: Some("fs_main"),
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::LineList,
|
||||||
|
strip_index_format: None,
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: None,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
|
unclipped_depth: false,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
|
format: wgpu::TextureFormat::Depth32Float,
|
||||||
|
depth_write_enabled: false,
|
||||||
|
depth_compare: wgpu::CompareFunction::Always,
|
||||||
|
stencil: wgpu::StencilState::default(),
|
||||||
|
bias: wgpu::DepthBiasState::default(),
|
||||||
|
}),
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_snow_clipmap_pipeline(
|
pub fn create_snow_clipmap_pipeline(
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
format: wgpu::TextureFormat,
|
format: wgpu::TextureFormat,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
|
|
||||||
use super::types::{DrawCall, Uniforms, MAX_SPOTLIGHTS};
|
use super::types::{DrawCall, Pipeline, Uniforms, MAX_SPOTLIGHTS};
|
||||||
use super::Renderer;
|
use super::Renderer;
|
||||||
|
|
||||||
impl Renderer
|
impl Renderer
|
||||||
@@ -31,6 +31,7 @@ impl Renderer
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
&self.spotlights,
|
&self.spotlights,
|
||||||
|
0,
|
||||||
);
|
);
|
||||||
self.queue.write_buffer(
|
self.queue.write_buffer(
|
||||||
&self.uniform_buffer,
|
&self.uniform_buffer,
|
||||||
@@ -84,6 +85,11 @@ impl Renderer
|
|||||||
|
|
||||||
for draw_call in draw_calls.iter()
|
for draw_call in draw_calls.iter()
|
||||||
{
|
{
|
||||||
|
if matches!(draw_call.pipeline, Pipeline::DebugLines)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
shadow_pass.set_vertex_buffer(0, draw_call.vertex_buffer.slice(..));
|
shadow_pass.set_vertex_buffer(0, draw_call.vertex_buffer.slice(..));
|
||||||
|
|
||||||
if let Some(ref instance_buffer) = draw_call.instance_buffer
|
if let Some(ref instance_buffer) = draw_call.instance_buffer
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ pub struct Uniforms
|
|||||||
pub enable_dissolve: u32,
|
pub enable_dissolve: u32,
|
||||||
pub enable_snow_light: u32,
|
pub enable_snow_light: u32,
|
||||||
pub spotlight_count: u32,
|
pub spotlight_count: u32,
|
||||||
pub _padding1: u32,
|
pub debug_mode: u32,
|
||||||
pub _padding2: u32,
|
pub _padding2: u32,
|
||||||
pub _padding3: u32,
|
pub _padding3: u32,
|
||||||
pub spotlights: [SpotlightRaw; MAX_SPOTLIGHTS],
|
pub spotlights: [SpotlightRaw; MAX_SPOTLIGHTS],
|
||||||
@@ -95,6 +95,7 @@ impl Uniforms
|
|||||||
enable_dissolve: bool,
|
enable_dissolve: bool,
|
||||||
enable_snow_light: bool,
|
enable_snow_light: bool,
|
||||||
spotlights: &[Spotlight],
|
spotlights: &[Spotlight],
|
||||||
|
debug_mode: u32,
|
||||||
) -> Self
|
) -> Self
|
||||||
{
|
{
|
||||||
let mut spotlight_array = [SpotlightRaw::default(); MAX_SPOTLIGHTS];
|
let mut spotlight_array = [SpotlightRaw::default(); MAX_SPOTLIGHTS];
|
||||||
@@ -126,7 +127,7 @@ impl Uniforms
|
|||||||
enable_dissolve: if enable_dissolve { 1 } else { 0 },
|
enable_dissolve: if enable_dissolve { 1 } else { 0 },
|
||||||
enable_snow_light: if enable_snow_light { 1 } else { 0 },
|
enable_snow_light: if enable_snow_light { 1 } else { 0 },
|
||||||
spotlight_count: spotlights.len().min(MAX_SPOTLIGHTS) as u32,
|
spotlight_count: spotlights.len().min(MAX_SPOTLIGHTS) as u32,
|
||||||
_padding1: 0,
|
debug_mode,
|
||||||
_padding2: 0,
|
_padding2: 0,
|
||||||
_padding3: 0,
|
_padding3: 0,
|
||||||
spotlights: spotlight_array,
|
spotlights: spotlight_array,
|
||||||
@@ -139,6 +140,7 @@ pub enum Pipeline
|
|||||||
{
|
{
|
||||||
Standard,
|
Standard,
|
||||||
SnowClipmap,
|
SnowClipmap,
|
||||||
|
DebugLines,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrawCall
|
pub struct DrawCall
|
||||||
|
|||||||
42
src/shaders/debug_overlay.wgsl
Normal file
42
src/shaders/debug_overlay.wgsl
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
struct VertexInput {
|
||||||
|
@location(0) position: vec2<f32>,
|
||||||
|
@location(1) uv: vec2<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) clip_position: vec4<f32>,
|
||||||
|
@location(0) uv: vec2<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(input: VertexInput) -> VertexOutput {
|
||||||
|
var output: VertexOutput;
|
||||||
|
output.clip_position = vec4<f32>(input.position, 0.0, 1.0);
|
||||||
|
output.uv = input.uv;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@group(0) @binding(0)
|
||||||
|
var t_shadow: texture_depth_2d_array;
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_shadow_map(input: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
let size = vec2<f32>(textureDimensions(t_shadow));
|
||||||
|
let coord = vec2<i32>(input.uv * size);
|
||||||
|
let depth = textureLoad(t_shadow, coord, 0, 0);
|
||||||
|
let linearized = 1.0 - depth;
|
||||||
|
return vec4<f32>(linearized, linearized, linearized, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@group(0) @binding(1)
|
||||||
|
var t_snow_light: texture_2d<f32>;
|
||||||
|
|
||||||
|
@group(0) @binding(2)
|
||||||
|
var t_sampler: sampler;
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_snow_light(input: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
let value = textureSample(t_snow_light, t_sampler, input.uv).r;
|
||||||
|
let remapped = clamp(value * 10.0, 0.0, 1.0);
|
||||||
|
return vec4<f32>(remapped, remapped, remapped, 1.0);
|
||||||
|
}
|
||||||
@@ -72,6 +72,7 @@ fn vs_main(input: VertexInput) -> VertexOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output.dissolve_amount = dissolve_amount;
|
output.dissolve_amount = dissolve_amount;
|
||||||
|
output.uv = input.uv;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,17 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4<f32>(brightness, brightness, brightness, 1.0);
|
switch uniforms.debug_mode {
|
||||||
|
case 1u { return vec4(in.world_normal * 0.5 + 0.5, 1.0); }
|
||||||
|
case 2u { return vec4(fract(in.uv), 0.0, 1.0); }
|
||||||
|
case 3u {
|
||||||
|
let d = in.clip_position.z / in.clip_position.w;
|
||||||
|
let lin = (d - 0.95) / 0.05;
|
||||||
|
return vec4(vec3(lin), 1.0);
|
||||||
|
}
|
||||||
|
case 4u { return vec4(1.0); }
|
||||||
|
default { return vec4(brightness, brightness, brightness, 1.0); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(1) @binding(0)
|
@group(1) @binding(0)
|
||||||
@@ -172,6 +183,7 @@ fn vs_snow_main(in: VertexInput) -> VertexOutput {
|
|||||||
out.world_normal = normal;
|
out.world_normal = normal;
|
||||||
out.clip_position = uniforms.projection * uniforms.view * vec4<f32>(world_position, 1.0);
|
out.clip_position = uniforms.projection * uniforms.view * vec4<f32>(world_position, 1.0);
|
||||||
out.dissolve_amount = in.instance_dissolve;
|
out.dissolve_amount = in.instance_dissolve;
|
||||||
|
out.uv = uv;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ struct VertexOutput {
|
|||||||
@location(0) world_position: vec3<f32>,
|
@location(0) world_position: vec3<f32>,
|
||||||
@location(1) world_normal: vec3<f32>,
|
@location(1) world_normal: vec3<f32>,
|
||||||
@location(2) dissolve_amount: f32,
|
@location(2) dissolve_amount: f32,
|
||||||
|
@location(3) uv: vec2<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_SPOTLIGHTS: u32 = 4u;
|
const MAX_SPOTLIGHTS: u32 = 4u;
|
||||||
@@ -47,7 +48,7 @@ struct Uniforms {
|
|||||||
enable_dissolve: u32,
|
enable_dissolve: u32,
|
||||||
enable_snow_light: u32,
|
enable_snow_light: u32,
|
||||||
spotlight_count: u32,
|
spotlight_count: u32,
|
||||||
_padding1: u32,
|
debug_mode: u32,
|
||||||
_padding2: u32,
|
_padding2: u32,
|
||||||
_padding3: u32,
|
_padding3: u32,
|
||||||
spotlights: array<Spotlight, 4>,
|
spotlights: array<Spotlight, 4>,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub struct InputState
|
|||||||
|
|
||||||
pub space_just_pressed: bool,
|
pub space_just_pressed: bool,
|
||||||
pub noclip_just_pressed: bool,
|
pub noclip_just_pressed: bool,
|
||||||
|
pub debug_cycle_just_pressed: bool,
|
||||||
|
|
||||||
pub mouse_delta: (f32, f32),
|
pub mouse_delta: (f32, f32),
|
||||||
pub mouse_captured: bool,
|
pub mouse_captured: bool,
|
||||||
@@ -32,6 +33,7 @@ impl InputState
|
|||||||
shift: false,
|
shift: false,
|
||||||
space_just_pressed: false,
|
space_just_pressed: false,
|
||||||
noclip_just_pressed: false,
|
noclip_just_pressed: false,
|
||||||
|
debug_cycle_just_pressed: false,
|
||||||
mouse_delta: (0.0, 0.0),
|
mouse_delta: (0.0, 0.0),
|
||||||
mouse_captured: true,
|
mouse_captured: true,
|
||||||
noclip_mode: false,
|
noclip_mode: false,
|
||||||
@@ -110,6 +112,7 @@ impl InputState
|
|||||||
}
|
}
|
||||||
Keycode::LShift | Keycode::RShift => self.shift = true,
|
Keycode::LShift | Keycode::RShift => self.shift = true,
|
||||||
Keycode::N => self.noclip_just_pressed = true,
|
Keycode::N => self.noclip_just_pressed = true,
|
||||||
|
Keycode::F1 => self.debug_cycle_just_pressed = true,
|
||||||
_ =>
|
_ =>
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
@@ -154,6 +157,7 @@ impl InputState
|
|||||||
{
|
{
|
||||||
self.space_just_pressed = false;
|
self.space_just_pressed = false;
|
||||||
self.noclip_just_pressed = false;
|
self.noclip_just_pressed = false;
|
||||||
|
self.debug_cycle_just_pressed = false;
|
||||||
self.mouse_delta = (0.0, 0.0);
|
self.mouse_delta = (0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user