deferred
mitchellhansen 4 years ago
parent 8cc76b7052
commit 5d4e6f8bed

@ -1,28 +1,28 @@
use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread::current; use std::thread::current;
use std::time::Duration; use std::time::Duration;
use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
use bytemuck::__core::mem;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use bytemuck::__core::mem;
use cgmath::{ use cgmath::{
vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3, Transform,
Transform, Vector3, vec3, Vector3,
}; };
use futures::executor::LocalPool; use futures::executor::LocalPool;
use imgui::sys::ImGuiContext;
use imgui::*; use imgui::*;
use imgui::sys::ImGuiContext;
use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig}; use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig};
use legion::world::SubWorld;
use legion::*; use legion::*;
use legion::world::SubWorld;
use rapier3d::parry::motion::RigidMotionComposition; use rapier3d::parry::motion::RigidMotionComposition;
use wgpu::util::DeviceExt;
use wgpu::{ use wgpu::{
BackendBit, BindGroup, BindGroupLayout, Buffer, BufferBindingType, CommandEncoder, Device, BackendBit, BindGroup, BindGroupLayout, Buffer, BufferBindingType, CommandEncoder, Device,
Features, FragmentState, Instance, Queue, Surface, SwapChain, SwapChainDescriptor, Features, FragmentState, Instance, Queue, Surface, SwapChain, SwapChainDescriptor,
SwapChainFrame, TextureView, VertexState, SwapChainFrame, TextureView, VertexState,
}; };
use wgpu::util::DeviceExt;
use winit_24::dpi::PhysicalSize; use winit_24::dpi::PhysicalSize;
use winit_24::platform::unix::x11::ffi::Time; use winit_24::platform::unix::x11::ffi::Time;
use winit_24::window::Window; use winit_24::window::Window;
@ -33,7 +33,7 @@ use crate::current_ui;
use crate::geometry::{load_obj, RawMesh, Vertex}; use crate::geometry::{load_obj, RawMesh, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform}; use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw}; use crate::light::{DirectionalLight, LightRaw};
use crate::render::{EntityUniforms, ForwardUniforms, ShadowUniforms, CameraProjectionView}; use crate::render::{CameraProjectionView, EntityUniforms, ForwardUniforms, ShadowUniforms};
/// A render pass consists of a pipeline, bindgroup, and uniform buf /// A render pass consists of a pipeline, bindgroup, and uniform buf
/// The uniform buf is just the ShadowUniforms or ForwardUniforms /// The uniform buf is just the ShadowUniforms or ForwardUniforms
@ -47,7 +47,6 @@ pub struct Pass {
} }
pub struct RenderState { pub struct RenderState {
swapchain: SwapChain, swapchain: SwapChain,
swapchain_description: SwapChainDescriptor, swapchain_description: SwapChainDescriptor,
instance: Arc<Instance>, instance: Arc<Instance>,
@ -84,12 +83,14 @@ pub struct RenderState {
impl RenderState { impl RenderState {
const MAX_LIGHTS: usize = 10; const MAX_LIGHTS: usize = 10;
const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
const G_BUFFER_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba32Float;
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
const SHADOW_SIZE: wgpu::Extent3d = wgpu::Extent3d { const SHADOW_SIZE: wgpu::Extent3d = wgpu::Extent3d {
width: 1024, width: 1024,
height: 1024, height: 1024,
depth: Self::MAX_LIGHTS as u32, depth: Self::MAX_LIGHTS as u32,
}; };
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
/// Generate a projection matrix with no look-at yet /// Generate a projection matrix with no look-at yet
pub fn generate_matrix(&self) -> cgmath::Matrix4<f32> { pub fn generate_matrix(&self) -> cgmath::Matrix4<f32> {
@ -220,6 +221,113 @@ impl RenderState {
} }
} }
// Create a render pass with the ability to add external bindings
pub fn create_render_pass(
device: &Device,
external_binding_layout: &BindGroupLayout,
vertex_description: &wgpu::VertexBufferLayout,
uniform_size: u64,
label: Option<&str>,
) -> Option<Pass> {
// 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()),
size: uniform_size,
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
// 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 = 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),
},
},
],
});
let vs_module =
device.create_shader_module(&wgpu::include_spirv!("../../shaders/bake.vert.spv"));
let fs_module =
device.create_shader_module(&wgpu::include_spirv!("../../shaders/bake.frag.spv"));
// The bind group layouts are accessed by layout(set = X, binding = x)
// in the shader.
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some(format!("{} pipeline layout", label.unwrap_or("unnamed")).as_str()),
bind_group_layouts: &[&bind_group_layout, external_binding_layout],
push_constant_ranges: &[],
});
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some(format!("{} render pipeline", label.unwrap_or("unnamed")).as_str()),
layout: Some(&pipeline_layout),
vertex: VertexState {
module: &vs_module,
entry_point: "main",
buffers: &[vertex_description.clone()],
},
fragment: Some(FragmentState {
module: &fs_module,
entry_point: "main",
targets: &[],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
..Default::default()
},
depth_stencil: Some(wgpu::DepthStencilState {
format: wgpu::TextureFormat::Depth32Float,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::LessEqual,
stencil: wgpu::StencilState::default(),
bias: wgpu::DepthBiasState {
constant: 2, // corresponds to bilinear filtering
slope_scale: 2.0,
clamp: 0.0,
},
clamp_depth: device.features().contains(
wgpu::Features::DEPTH_CLAMPING
),
}),
multisample: wgpu::MultisampleState::default(),
});
Some(Pass {
pipeline,
bind_group,
uniform_buf,
})
}
pub fn init(window: &Window, imgui_context: &mut ImguiContext) -> RenderState { pub fn init(window: &Window, imgui_context: &mut ImguiContext) -> RenderState {
// Grab the GPU instance, and query its features // Grab the GPU instance, and query its features
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY); let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
@ -314,8 +422,23 @@ impl RenderState {
// This pass is just going to forward the vertex info to the fragments // This pass is just going to forward the vertex info to the fragments
// And they are going to render to the gbuffer // And they are going to render to the gbuffer
let g_buffer_pass = { let g_buffer_pass = Self::create_render_pass(
&device,
&entity_bind_group_layout,
&vb_desc,
mem::size_of::<CameraProjectionView>() as wgpu::BufferAddress,
Some("g-buffer"),
);
let shadow_pass = Self::create_render_pass(
&device,
&entity_bind_group_layout,
&vb_desc,
mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress,
Some("shadow-pass"),
);
let g_buffer_pass = {
let uniform_size = mem::size_of::<CameraProjectionView>() as wgpu::BufferAddress; let uniform_size = mem::size_of::<CameraProjectionView>() as wgpu::BufferAddress;
// The g-buffers camera projection matrix that we stream data to // The g-buffers camera projection matrix that we stream data to
@ -342,6 +465,10 @@ impl RenderState {
}], }],
}); });
//sudo rm /usr/bin/ld
//sudo ln -s /usr/bin/lld /usr/bin/ld
//sudo ln -s /usr/bin/x86_64-linux-gnu-ld /usr/bin/ld
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("g-buffers uniform bind group"), label: Some("g-buffers uniform bind group"),
layout: &bind_group_layout, layout: &bind_group_layout,
@ -355,7 +482,6 @@ impl RenderState {
}, },
}, },
], ],
}); });
let vs_module = let vs_module =
@ -392,7 +518,7 @@ impl RenderState {
..Default::default() ..Default::default()
}, },
depth_stencil: Some(wgpu::DepthStencilState { depth_stencil: Some(wgpu::DepthStencilState {
format: Self::SHADOW_FORMAT, format: wgpu::TextureFormat::Depth32Float,
depth_write_enabled: true, depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::LessEqual, depth_compare: wgpu::CompareFunction::LessEqual,
stencil: wgpu::StencilState::default(), stencil: wgpu::StencilState::default(),
@ -401,7 +527,9 @@ impl RenderState {
slope_scale: 2.0, slope_scale: 2.0,
clamp: 0.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(), multisample: wgpu::MultisampleState::default(),
}); });
@ -413,6 +541,7 @@ impl RenderState {
} }
}; };
let shadow_pass = { let shadow_pass = {
let uniform_size = mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress; let uniform_size = mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress;
@ -591,8 +720,7 @@ impl RenderState {
ty: wgpu::BufferBindingType::Uniform, ty: wgpu::BufferBindingType::Uniform,
min_binding_size: wgpu::BufferSize::new(mem::size_of::< min_binding_size: wgpu::BufferSize::new(mem::size_of::<
ForwardUniforms, ForwardUniforms,
>( >()
)
as _), as _),
has_dynamic_offset: false, has_dynamic_offset: false,
}, },
@ -760,20 +888,20 @@ impl RenderState {
size: wgpu::Extent3d { size: wgpu::Extent3d {
width: sc_desc.width, width: sc_desc.width,
height: sc_desc.height, height: sc_desc.height,
depth: 1, depth: 5,
}, },
mip_level_count: 1, mip_level_count: 1,
sample_count: 1, sample_count: 1,
dimension: wgpu::TextureDimension::D2, dimension: wgpu::TextureDimension::D2,
format: Self::DEPTH_FORMAT, format: Self::DEPTH_FORMAT,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT, usage: wgpu::TextureUsage::RENDER_ATTACHMENT | wgpu::TextureUsage::SAMPLED,
label: Some("g-buffer depth texture"), label: Some("g-buffer depth texture"),
}); });
// I need one of these for each of the g-buffer elements I'm calculating // 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_depth_texture_views = (0..4)
.map(|i| { .map(|i| {
Arc::new(shadow_texture.create_view(&wgpu::TextureViewDescriptor { Arc::new(g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor {
label: Some("g-buffer depth texture"), label: Some("g-buffer depth texture"),
format: None, format: None,
dimension: Some(wgpu::TextureViewDimension::D2), dimension: Some(wgpu::TextureViewDimension::D2),
@ -795,7 +923,6 @@ impl RenderState {
ImguiRenderer::new(&mut imgui_context.context, &device, &queue, renderer_config); ImguiRenderer::new(&mut imgui_context.context, &device, &queue, renderer_config);
RenderState { RenderState {
gbuffer_pass: g_buffer_pass, gbuffer_pass: g_buffer_pass,
gbuffer_cam_projection_buffer: g_buffer_camera_projection_uniform, gbuffer_cam_projection_buffer: g_buffer_camera_projection_uniform,
gbuffer_depth: g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor::default()), gbuffer_depth: g_buffer_depth_texture.create_view(&wgpu::TextureViewDescriptor::default()),

Loading…
Cancel
Save