thinking about shaders

deferred
mitchellhansen 4 years ago
parent 813d2f6f2f
commit 7fb89e7d6e

@ -36,16 +36,17 @@ float fetch_shadow(int light_id, vec4 homogeneous_coords) {
if (homogeneous_coords.w <= 0.0) {
return 1.0;
}
// compensate for the Y-flip difference between the NDC and texture coordinates
// compensate for the Y-flip difference between the normalized device
// coordinates (NDC) and texture coordinates
const vec2 flip_correction = vec2(0.5, -0.5);
// compute texture coordinates for shadow lookup
vec4 light_local = vec4(
// I don't know what kind of jank shit is going on on this line
homogeneous_coords.xy * flip_correction/homogeneous_coords.w + 0.5,
light_id,
homogeneous_coords.z / homogeneous_coords.w
light_id, // array layer
homogeneous_coords.z / homogeneous_coords.w // D-Ref
);
// do the lookup, using HW PCF and comparison
// do the lookup, using HW percentage closer filtering(PCF) and comparison
return texture(sampler2DArrayShadow(t_Shadow, s_Shadow), light_local);
}

@ -0,0 +1,4 @@
#version 450
void main() {
}

@ -0,0 +1,20 @@
#version 450
layout(location = 0) in vec4 a_Pos;
layout(set = 0, binding = 0) uniform Globals {
mat4 u_ViewProj;
};
layout(set = 0, binding = 1) uniform Globals {
mat4 u_ViewProj;
};
layout(set = 1, binding = 0) uniform Entity {
mat4 u_World;
vec4 u_Color;
};
void main() {
gl_Position = u_ViewProj * u_World * vec4(a_Pos);
}

@ -66,3 +66,12 @@ pub struct ShadowUniforms {
unsafe impl Pod for ShadowUniforms {}
unsafe impl Zeroable for ShadowUniforms {}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct CameraProjectionView {
proj: [[f32; 4]; 4],
}
unsafe impl Pod for CameraProjectionView {}
unsafe impl Zeroable for CameraProjectionView {}

@ -33,11 +33,13 @@ use crate::current_ui;
use crate::geometry::{load_obj, RawMesh, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw};
use crate::render::{EntityUniforms, ForwardUniforms, ShadowUniforms};
use crate::render::{EntityUniforms, ForwardUniforms, ShadowUniforms, CameraProjectionView};
/// A render pass consists of a pipeline, bindgroup, and uniform buf
/// 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,
@ -45,6 +47,7 @@ pub struct Pass {
}
pub struct RenderState {
swapchain: SwapChain,
swapchain_description: SwapChainDescriptor,
instance: Arc<Instance>,
@ -62,6 +65,8 @@ pub struct RenderState {
pub(in crate::render) forward_pass: Pass,
pub(in crate::render) forward_depth: wgpu::TextureView,
pub(in crate::render) gbuffer_pass: Pass,
entity_bind_group_layout: BindGroupLayout,
pub(in crate::render) light_uniform_buf: wgpu::Buffer,
@ -302,6 +307,107 @@ impl RenderState {
hands-off global lighting / point lights
*/
// This pass is just going to forward the vertex info to the fragments
// And they are going to render to the gbuffer
let g_buffer_pass = {
let uniform_size = mem::size_of::<CameraProjectionView>() as wgpu::BufferAddress;
// Pretty sure this is the camera projction
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,
},
count: None,
}],
});
// Pipeline is similar between passes, but with a different label
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("g-buffer input pipeline layout"),
bind_group_layouts: &[&bind_group_layout, &entity_bind_group_layout],
push_constant_ranges: &[],
});
// Holds the shadow uniforms, which is just a 4 vec of quaternians
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("shadow pass shadow uniform buffer"),
size: uniform_size,
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
// Create bind group
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Shadow 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),
},
},
],
});
// Create the render pipeline
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"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("shadow"),
layout: Some(&pipeline_layout),
vertex: VertexState {
module: &vs_module,
entry_point: "main",
buffers: &[vb_desc.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: Self::SHADOW_FORMAT,
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(),
});
Pass {
pipeline,
bind_group,
uniform_buf,
}
};
let shadow_pass = {
let uniform_size = mem::size_of::<ShadowUniforms>() as wgpu::BufferAddress;
@ -356,14 +462,6 @@ impl RenderState {
size: wgpu::BufferSize::new(uniform_size),
},
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &g_buffer,
offset: 0,
size: wgpu::BufferSize::new(uniform_size),
},
},
],
label: Some("Shadow uniform bind group"),
});
@ -655,6 +753,7 @@ impl RenderState {
shadow_pass,
forward_pass,
forward_depth: depth_texture.create_view(&wgpu::TextureViewDescriptor::default()),
gbuffer_pass: g_buffer_pass,
entity_bind_group_layout: entity_bind_group_layout,
shadow_target_views: shadow_target_views,
light_uniform_buf,

@ -36,9 +36,7 @@ use crate::geometry::{load_obj, Vertex};
use crate::imgui_supp::imgui_support::{ImguiContext, ImguiPlatform};
use crate::light::{DirectionalLight, LightRaw};
use crate::render::state::RenderState;
use crate::render::{
insert_debug_marker_checked, pop_debug_group_checked, push_debug_group_checked, EntityUniforms,
};
use crate::render::{insert_debug_marker_checked, pop_debug_group_checked, push_debug_group_checked, EntityUniforms, ForwardUniforms};
#[system]
#[write_component(Camera)]
@ -235,6 +233,7 @@ pub fn render_test(
mesh_stack.push(mesh.clone());
}
// Update the light uniforms only if flagged
if renderer.lights_are_dirty {
renderer.lights_are_dirty = false;
let mut query = <(&mut DirectionalLight, &mut Position)>::query();
@ -247,6 +246,39 @@ pub fn render_test(
}
}
// Render the g buffer
push_debug_group_checked("g-buffer stuff", &mut encoder);
{
insert_debug_marker_checked("render entities", &mut encoder);
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("render pass"),
color_attachments: &[],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &light.target_view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
}),
stencil_ops: None,
}),
});
pass.set_pipeline(&renderer.shadow_pass.pipeline);
pass.set_bind_group(0, &renderer.shadow_pass.bind_group, &[]);
for mesh in &mesh_stack {
pass.set_bind_group(1, &mesh.bind_group, &[]);
// TODO, pipe through this index format through the mesh
pass.set_index_buffer(mesh.index_buffer.slice(..), mesh.index_format);
pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
pass.draw_indexed(0..mesh.index_count as u32, 0, 0..1);
}
}
pop_debug_group_checked(&mut encoder);
push_debug_group_checked("shadow passes", &mut encoder);
let mut query = <(&mut DirectionalLight, &mut Position)>::query();
@ -327,6 +359,7 @@ pub fn render_test(
let mut query = <(&mut Position, &mut Mesh)>::query();
// I could use that mesh stack here lol
for (pos, mesh) in query.iter_mut(world) {
pass.set_bind_group(1, &mesh.bind_group, &[]);
// TODO: Pipe this in through the mesh
@ -335,9 +368,11 @@ pub fn render_test(
pass.draw_indexed(0..mesh.index_count as u32, 0, 0..1);
}
}
pop_debug_group_checked(&mut encoder);
pop_debug_group_checked(&mut encoder);
// Run the Imgui render
{
let mut imgui_context = &mut imgui_context.lock().unwrap().context;
let mut imgui_platform = &mut imgui_platform.lock().unwrap().platform;

Loading…
Cancel
Save