diff --git a/Cargo.toml b/Cargo.toml index f6d25fc..dd7e5aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ toml = "0.5.8" cgmath = "0.18.0" rapier3d = { version = "0.5.0", features = ["simd-nightly", "parallel"] } nalgebra = "0.24.1" -legion = "0.3.1" +legion = "0.4.0" wgpu = "0.7.0" imgui = "0.7.0" imgui-wgpu = "0.14.0" diff --git a/note.md b/note.md new file mode 100644 index 0000000..b421f10 --- /dev/null +++ b/note.md @@ -0,0 +1,26 @@ +# Texture Samplers +|GLSL sampler|OpenGL texture enum|Texture type| +|---|---|---| +gsampler1D | GL_TEXTURE_1D | 1D texture +gsampler2D | GL_TEXTURE_2D | 2D texture +gsampler3D | GL_TEXTURE_3D | 3D texture +gsamplerCube | GL_TEXTURE_CUBE_MAP | Cubemap Texture +gsampler2DRect | GL_TEXTURE_RECTANGLE | Rectangle Texture +gsampler1DArray | GL_TEXTURE_1D_ARRAY | 1D Array Texture +gsampler2DArray | GL_TEXTURE_2D_ARRAY | 2D Array Texture +gsamplerCubeArray | GL_TEXTURE_CUBE_MAP_ARRAY | Cubemap Array Texture +gsamplerBuffer | GL_TEXTURE_BUFFER | Buffer Texture +gsampler2DMS | GL_TEXTURE_2D_MULTISAMPLE | Multisample Texture +gsampler2DMSArray | GL_TEXTURE_2D_MULTISAMPLE_ARRAY | Multisample Array Texture + + +# Shadow Samplers +|GLSL sampler|OpenGL texture enum| +|---|---| +sampler1DShadow | GL_TEXTURE_1D +sampler2DShadow | GL_TEXTURE_2D +samplerCubeShadow | GL_TEXTURE_CUBE_MAP +sampler2DRectShadow | GL_TEXTURE_RECTANGLE +sampler1DArrayShadow | GL_TEXTURE_1D_ARRAY +sampler2DArrayShadow | GL_TEXTURE_2D_ARRAY +samplerCubeArrayShadow | GL_TEXTURE_CUBE_MAP_ARRAY \ No newline at end of file diff --git a/shaders/g_buffer_input.frag b/shaders/g_buffer_input.frag index f0bcb49..2a6b21d 100644 --- a/shaders/g_buffer_input.frag +++ b/shaders/g_buffer_input.frag @@ -1,4 +1,22 @@ #version 450 +layout(location = 0) in vec3 v_Normal; +layout(location = 1) in vec4 v_Position; +layout(location = 2) in vec2 v_Uv; + +layout(location = 0) out vec4 o_Normal; +layout(location = 1) out vec4 o_Position; +layout(location = 2) out vec4 o_Uv; + +// so I need to have my 3 color attachments and 1? sampler. + +layout(set = 0, binding = 1) uniform texture2DArray t_Uv; +layout(set = 0, binding = 2) uniform gsampler2D s_Uv; + +// I also need my 1 depth texture and its sampler +layout(set = 0, binding = 3) uniform texture2DArray t_Shadow; +layout(set = 0, binding = 4) uniform samplerShadow s_Shadow; + void main() { + } diff --git a/shaders/g_buffer_input.vert b/shaders/g_buffer_input.vert index c4c4145..b556972 100644 --- a/shaders/g_buffer_input.vert +++ b/shaders/g_buffer_input.vert @@ -2,6 +2,11 @@ layout(location = 0) in vec4 a_Pos; + +layout(location = 0) out vec3 v_Normal; +layout(location = 1) out vec4 v_Position; +layout(location = 2) out vec2 v_Uv; + layout(set = 0, binding = 0) uniform Globals { mat4 u_ViewProj; }; diff --git a/src/render/state.rs b/src/render/state.rs index 281f1ed..bfc8527 100644 --- a/src/render/state.rs +++ b/src/render/state.rs @@ -1,28 +1,28 @@ -use std::{iter, num::NonZeroU32, ops::Range, rc::Rc}; use std::cell::RefCell; use std::sync::{Arc, Mutex}; use std::thread::current; use std::time::Duration; +use std::{iter, num::NonZeroU32, ops::Range, rc::Rc}; -use bytemuck::{Pod, Zeroable}; use bytemuck::__core::mem; +use bytemuck::{Pod, Zeroable}; use cgmath::{ - Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3, Transform, - vec3, Vector3, + vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3, + Transform, Vector3, }; use futures::executor::LocalPool; -use imgui::*; use imgui::sys::ImGuiContext; +use imgui::*; use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig}; -use legion::*; use legion::world::SubWorld; +use legion::*; use rapier3d::parry::motion::RigidMotionComposition; +use wgpu::util::DeviceExt; use wgpu::{ BackendBit, BindGroup, BindGroupLayout, Buffer, BufferBindingType, CommandEncoder, Device, Features, FragmentState, Instance, Queue, Surface, SwapChain, SwapChainDescriptor, SwapChainFrame, TextureView, VertexState, }; -use wgpu::util::DeviceExt; use winit_24::dpi::PhysicalSize; use winit_24::platform::unix::x11::ffi::Time; use winit_24::window::Window; @@ -39,7 +39,7 @@ use crate::render::{CameraProjectionView, EntityUniforms, ForwardUniforms, Shado /// The uniform buf is just the ShadowUniforms or ForwardUniforms /// They are uniform across all cu's. /// And the bindgroup is just the localbindgroup (the EntityUniforms) and the rest -/// +/// pub struct Pass { pub pipeline: wgpu::RenderPipeline, pub bind_group: wgpu::BindGroup, @@ -223,7 +223,6 @@ impl RenderState { } } - // Create a render pass with the ability to add external bindings pub fn create_render_pass( device: &Device, @@ -232,8 +231,6 @@ impl RenderState { uniform_size: u64, label: Option<&str>, ) -> Option { - - // The g-buffers camera projection matrix that we stream data to let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { label: Some(format!("{} uniform-buffer", label.unwrap_or("unnamed")).as_str()), @@ -243,34 +240,31 @@ impl RenderState { }); // Uniform bind group for the view matrix - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some(format!("{} bind group layout", label.unwrap_or("unnamed")).as_str()), - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, // global - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - min_binding_size: wgpu::BufferSize::new(uniform_size), - has_dynamic_offset: false, - }, - count: None, - }], - }); + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some(format!("{} bind group layout", label.unwrap_or("unnamed")).as_str()), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, // global + visibility: wgpu::ShaderStage::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + min_binding_size: wgpu::BufferSize::new(uniform_size), + has_dynamic_offset: false, + }, + count: None, + }], + }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some(format!("{} uniform bind group", label.unwrap_or("unnamed")).as_str()), layout: &bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - offset: 0, - size: wgpu::BufferSize::new(uniform_size), - }, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer { + buffer: &uniform_buf, + offset: 0, + size: wgpu::BufferSize::new(uniform_size), }, - ], + }], }); let vs_module = @@ -316,9 +310,7 @@ impl RenderState { slope_scale: 2.0, clamp: 0.0, }, - clamp_depth: device.features().contains( - wgpu::Features::DEPTH_CLAMPING - ), + clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING), }), multisample: wgpu::MultisampleState::default(), }); @@ -455,16 +447,37 @@ impl RenderState { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("g-buffer input pass bindgroup layout (cam)"), - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, // global - visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - min_binding_size: wgpu::BufferSize::new(uniform_size), - has_dynamic_offset: false, + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, // global + visibility: wgpu::ShaderStage::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + min_binding_size: wgpu::BufferSize::new(uniform_size), + has_dynamic_offset: false, + }, + count: None, }, - count: None, - }], + wgpu::BindGroupLayoutEntry { + binding: 1, // texture2DArray + visibility: wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Texture { + multisampled: false, + sample_type: wgpu::TextureSampleType::Depth, + view_dimension: wgpu::TextureViewDimension::D2Array, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, // samplerShadow + visibility: wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { + filtering: false, + comparison: true, + }, + count: None, + }, + ], }); //sudo rm /usr/bin/ld @@ -474,16 +487,14 @@ impl RenderState { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("g-buffers uniform bind group"), layout: &bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - offset: 0, - size: wgpu::BufferSize::new(uniform_size), - }, + entries: &[wgpu::BindGroupEntry { + binding: 0, // globals + resource: wgpu::BindingResource::Buffer { + buffer: &uniform_buf, + offset: 0, + size: wgpu::BufferSize::new(uniform_size), }, - ], + }], }); let vs_module = @@ -529,9 +540,7 @@ impl RenderState { slope_scale: 2.0, clamp: 0.0, }, - clamp_depth: device.features().contains( - wgpu::Features::DEPTH_CLAMPING - ), + clamp_depth: device.features().contains(wgpu::Features::DEPTH_CLAMPING), }), multisample: wgpu::MultisampleState::default(), }); @@ -543,7 +552,6 @@ impl RenderState { } }; - let shadow_pass = { let uniform_size = mem::size_of::() as wgpu::BufferAddress; @@ -581,16 +589,14 @@ impl RenderState { // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - offset: 0, - size: wgpu::BufferSize::new(uniform_size), - }, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Buffer { + buffer: &uniform_buf, + offset: 0, + size: wgpu::BufferSize::new(uniform_size), }, - ], + }], label: Some("Shadow uniform bind group"), }); @@ -704,14 +710,18 @@ impl RenderState { proj: *mx_projection.as_ref(), }; - let g_buffer_camera_projection_uniform = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("g-buffer camera projection uniform buffer"), - contents: bytemuck::bytes_of(&g_buffer_camera_projection_matrix), - usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, - }); + let g_buffer_camera_projection_uniform = + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("g-buffer camera projection uniform buffer"), + contents: bytemuck::bytes_of(&g_buffer_camera_projection_matrix), + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + }); let forward_pass = { // Create pipeline layout + let forward_uniform_size = + mem::size_of::() as wgpu::BufferAddress; + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ @@ -720,10 +730,7 @@ impl RenderState { visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, - min_binding_size: wgpu::BufferSize::new(mem::size_of::< - ForwardUniforms, - >() - as _), + min_binding_size: wgpu::BufferSize::new(forward_uniform_size), has_dynamic_offset: false, }, count: None, @@ -739,7 +746,7 @@ impl RenderState { count: None, }, wgpu::BindGroupLayoutEntry { - binding: 2, + binding: 2, // texture2DArray visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Texture { multisampled: false, @@ -749,7 +756,7 @@ impl RenderState { count: None, }, wgpu::BindGroupLayoutEntry { - binding: 3, + binding: 3, // samplerShadow visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Sampler { filtering: false, @@ -903,21 +910,22 @@ impl RenderState { // I need one of these for each of the g-buffer elements I'm calculating let mut g_buffer_depth_texture_views = (0..4) .map(|i| { - Arc::new(g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor { - label: Some("g-buffer depth texture"), - format: None, - dimension: Some(wgpu::TextureViewDimension::D2), - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - level_count: None, - base_array_layer: i as u32, - array_layer_count: NonZeroU32::new(1), - })) + Arc::new( + g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor { + label: Some("g-buffer depth texture"), + format: None, + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + level_count: None, + base_array_layer: i as u32, + array_layer_count: NonZeroU32::new(1), + }), + ) }) .collect::>(); - - let g_buffer_depth_texture = device.create_texture(&wgpu::TextureDescriptor { + let g_buffer_data_texture = device.create_texture(&wgpu::TextureDescriptor { size: wgpu::Extent3d { width: sc_desc.width, height: sc_desc.height, @@ -932,18 +940,20 @@ impl RenderState { }); // I need one of these for each of the g-buffer elements I'm calculating - let mut g_buffer_depth_texture_views = (0..4) + let mut g_buffer_data_texture_views = (0..4) .map(|i| { - Arc::new(g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor { - label: Some("g-buffer depth texture"), - format: None, - dimension: Some(wgpu::TextureViewDimension::D2), - aspect: wgpu::TextureAspect::All, - base_mip_level: 0, - level_count: None, - base_array_layer: i as u32, - array_layer_count: NonZeroU32::new(1), - })) + Arc::new( + g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor { + label: Some("g-buffer depth texture"), + format: None, + dimension: Some(wgpu::TextureViewDimension::D2), + aspect: wgpu::TextureAspect::All, + base_mip_level: 0, + level_count: None, + base_array_layer: i as u32, + array_layer_count: NonZeroU32::new(1), + }), + ) }) .collect::>(); @@ -958,8 +968,12 @@ impl RenderState { RenderState { gbuffer_pass: g_buffer_pass, gbuffer_cam_projection_buffer: g_buffer_camera_projection_uniform, - gbuffer_depth_texture: g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor::default()), - gbuffer_target_views: g_buffer_depth_texture_views, + gbuffer_depth_texture: g_buffer_depth_texture + .create_view(&wgpu::TextureViewDescriptor::default()), + gbuffer_depth_views: g_buffer_depth_texture_views, + gbuffer_target_texture: g_buffer_data_texture + .create_view(&wgpu::TextureViewDescriptor::default()), + gbuffer_target_views: g_buffer_data_texture_views, swapchain: swap_chain, queue: queue, @@ -968,7 +982,8 @@ impl RenderState { lights_are_dirty: true, shadow_pass, forward_pass, - forward_depth: forward_depth_texture.create_view(&wgpu::TextureViewDescriptor::default()), + forward_depth: forward_depth_texture + .create_view(&wgpu::TextureViewDescriptor::default()), entity_bind_group_layout: entity_bind_group_layout, shadow_target_views: shadow_target_views, light_uniform_buf,