postprocess render pass

This commit is contained in:
Piotrek
2021-04-26 19:07:02 +02:00
parent 19aefbf287
commit 3a444d6e3a
14 changed files with 179 additions and 24 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ impl ShaderData {
let extension = src_path.extension().expect("File has no extension").to_str().unwrap(); let extension = src_path.extension().expect("File has no extension").to_str().unwrap();
// Create output path // Create output path
let directory = src_path.parent().unwrap().join("bin"); let directory = src_path.parent().unwrap().join(".bin");
create_dir_all(directory.clone()).expect("Failed to create output directory"); create_dir_all(directory.clone()).expect("Failed to create output directory");
let spv_path = directory.join(filename).with_extension(format!("{}.spv", extension)); let spv_path = directory.join(filename).with_extension(format!("{}.spv", extension));
+23 -3
View File
@@ -5,7 +5,7 @@ pub mod buffers;
use buffers::Buffers; use buffers::Buffers;
mod passes; mod passes;
use passes::RaytracePass; use passes::{RaytracePass, PostprocessPass};
pub mod camera; pub mod camera;
use camera::Camera; use camera::Camera;
@@ -17,7 +17,10 @@ pub struct Renderer {
queue: wgpu::Queue, queue: wgpu::Queue,
swapchain_desc: wgpu::SwapChainDescriptor, swapchain_desc: wgpu::SwapChainDescriptor,
swapchain: wgpu::SwapChain, swapchain: wgpu::SwapChain,
// Passes
texture: wgpu::TextureView,
raytrace_pass: RaytracePass, raytrace_pass: RaytracePass,
postprocess_pass: PostprocessPass,
// Buffers // Buffers
buffers: Buffers, buffers: Buffers,
// Other // Other
@@ -58,16 +61,32 @@ impl Renderer {
let aspect = swapchain_desc.width as f32 / swapchain_desc.height as f32; let aspect = swapchain_desc.width as f32 / swapchain_desc.height as f32;
let camera = Camera::new(aspect, 60.0); let camera = Camera::new(aspect, 60.0);
// Middleman texture
let mut texture_descriptor = wgpu::TextureDescriptor {
label: Some("glow_post_process_texture1"),
size: wgpu::Extent3d { width: swapchain_desc.width,
height: swapchain_desc.height,
depth: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: swapchain_desc.format,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
};
let texture = device.create_texture(&texture_descriptor).create_view(&wgpu::TextureViewDescriptor::default());
// Pipeline // Pipeline
let buffers = Buffers::new(&device); let buffers = Buffers::new(&device);
let raytrace_pass = RaytracePass::new(&device, &swapchain_desc, &buffers); let raytrace_pass = RaytracePass::new(&device, &swapchain_desc, &buffers);
let postprocess_pass = PostprocessPass::new(&device, &swapchain_desc, &texture);
// Other // Other
let start = std::time::Instant::now(); let start = std::time::Instant::now();
let changed_bricks: Vec<usize> = Vec::new(); let changed_bricks: Vec<usize> = Vec::new();
println!("Initialized"); println!("Initialized");
Self { surface, device, queue, swapchain_desc, swapchain, raytrace_pass, buffers, camera, start, changed_bricks } Self { surface, device, queue, swapchain_desc, swapchain, texture, raytrace_pass, postprocess_pass, buffers, camera, start, changed_bricks }
} }
/* /*
@@ -117,7 +136,8 @@ impl Renderer {
// Create encoder that will build command buffer for us // Create encoder that will build command buffer for us
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),}); let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),});
self.raytrace_pass.render(&mut encoder, &mut self.buffers, &frame.view); self.raytrace_pass.render(&mut encoder, &mut self.buffers, &self.texture);//&frame.view);
self.postprocess_pass.render(&mut encoder, &frame.view);
// Submit encoder (command buffer) // Submit encoder (command buffer)
self.queue.submit(std::iter::once(encoder.finish())); self.queue.submit(std::iter::once(encoder.finish()));
+3
View File
@@ -1,3 +1,6 @@
mod raytrace; mod raytrace;
pub use raytrace::RaytracePass; pub use raytrace::RaytracePass;
mod postprocess;
pub use postprocess::PostprocessPass;
+116 -2
View File
@@ -1,9 +1,123 @@
pub struct PostprocessPass { pub struct PostprocessPass {
pub pipeline: wgpu::RenderPipeline pipeline: wgpu::RenderPipeline,
bind_group: wgpu::BindGroup
} }
impl PostprocessPass { impl PostprocessPass {
pub fn new(device: &wgpu::Device, swapchain_desc: &wgpu::SwapChainDescriptor) -> Self { pub fn new(device: &wgpu::Device, swapchain_desc: &wgpu::SwapChainDescriptor, texture_view: &wgpu::TextureView) -> Self {
// Vertex shader
let vert_state = wgpu::VertexState {
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\.bin\\fullscreen.vert.spv")),
entry_point: "main",
buffers: &[],
};
// Fragment shader
let frag_state = wgpu::FragmentState {
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\postprocess\\.bin\\main.frag.spv")),
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swapchain_desc.format,
alpha_blend: wgpu::BlendState::REPLACE, //TODO: Change to correct
color_blend: wgpu::BlendState::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
};
// Create bind layout
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Post process bind layout"),
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
count: None,
}
],
});
// Craete texture sampler
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("Post procecss sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: 0.0,
lod_max_clamp: 100.0,
compare: None,
anisotropy_clamp: None,
border_color: None,
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_layout,
entries: &[
wgpu::BindGroupEntry {binding: 0, resource: wgpu::BindingResource::TextureView(&texture_view),},
wgpu::BindGroupEntry {binding: 1, resource: wgpu::BindingResource::Sampler(&sampler),},
],
label: Some("Uniform buffer group"),
});
// Pipeline layout
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Render Pipeline Layout"),
bind_group_layouts: &[&bind_layout],
push_constant_ranges: &[],
});
// Create pipeline
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&pipeline_layout),
vertex: vert_state,
fragment: Some(frag_state),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Cw,
cull_mode: wgpu::CullMode::Back,
polygon_mode: wgpu::PolygonMode::Fill,
},
depth_stencil: None,
multisample: wgpu::MultisampleState { count: 1, mask: !0, alpha_to_coverage_enabled: false }
});
Self { pipeline, bind_group }
}
pub fn render(&mut self, encoder: &mut wgpu::CommandEncoder, attachment: &wgpu::TextureView) {
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Postprocess pass"),
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: &attachment,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
store: true,
},
}],
depth_stencil_attachment: None,
});
pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &self.bind_group, &[]);
pass.draw(0..6, 0..1);
} }
} }
+5 -8
View File
@@ -9,14 +9,14 @@ impl RaytracePass {
// Vertex shader // Vertex shader
let vert_state = wgpu::VertexState { let vert_state = wgpu::VertexState {
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\bin\\shader.vert.spv")), module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\.bin\\fullscreen.vert.spv")),
entry_point: "main", entry_point: "main",
buffers: &[], buffers: &[],
}; };
// Fragment shader // Fragment shader
let frag_state = wgpu::FragmentState { let frag_state = wgpu::FragmentState {
module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\bin\\shader.frag.spv")), module: &device.create_shader_module(&wgpu::include_spirv!("..\\..\\shaders\\raytrace\\.bin\\main.frag.spv")),
entry_point: "main", entry_point: "main",
targets: &[wgpu::ColorTargetState { targets: &[wgpu::ColorTargetState {
format: swapchain_desc.format, format: swapchain_desc.format,
@@ -63,7 +63,7 @@ impl RaytracePass {
pub fn render(&mut self, encoder: &mut wgpu::CommandEncoder, buffers: &mut Buffers, attachment: &wgpu::TextureView) { pub fn render(&mut self, encoder: &mut wgpu::CommandEncoder, buffers: &mut Buffers, attachment: &wgpu::TextureView) {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"), label: Some("Raytrace Pass"),
color_attachments: &[ color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor { wgpu::RenderPassColorAttachmentDescriptor {
attachment: attachment, attachment: attachment,
@@ -86,10 +86,7 @@ impl RaytracePass {
render_pass.set_bind_group(2, &buffers.brick_buffer.bind_group, &[]); render_pass.set_bind_group(2, &buffers.brick_buffer.bind_group, &[]);
render_pass.set_bind_group(3, &buffers.material_buffer.bind_group, &[]); render_pass.set_bind_group(3, &buffers.material_buffer.bind_group, &[]);
// Vertices and indices // Draw 2 triangles
render_pass.draw(0..6, 0..1); // 3. render_pass.draw(0..6, 0..1);
// render_pass.set_vertex_buffer(0, buffers.raster_buffer.vertex_buffer.slice(..));
// render_pass.set_index_buffer(buffers.raster_buffer.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
// render_pass.draw_indexed(0..buffers.raster_buffer.index_len, 0, 0..1);
} }
} }
@@ -1,6 +1,6 @@
#version 450 #version 450
layout(location=0) out vec2 vert_uv; layout(location=0) out vec2 _InUV;
const vec2 positions[6] = vec2[6]( const vec2 positions[6] = vec2[6](
vec2(-1.0, 1.0), vec2(-1.0, 1.0),
@@ -14,6 +14,6 @@ const vec2 positions[6] = vec2[6](
void main() void main()
{ {
vert_uv = positions[gl_VertexIndex]; _InUV = positions[gl_VertexIndex];
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
} }
Binary file not shown.
+22
View File
@@ -0,0 +1,22 @@
#version 450
layout(set=0, binding=0) uniform texture2D _InTexture;
layout(set=0, binding=1) uniform sampler _InTextureSampler;
layout(location=0) in vec2 _InUV;
layout(location=0) out vec4 _OutColor;
void main()
{
// Get color
vec2 uv = vec2(_InUV.x+1.0, -_InUV.y+1.0) * 0.5;
vec3 color = texture(sampler2D(_InTexture, _InTextureSampler), uv).rgb;
// Viniette
color = vec3(1,1,1);
color *= smoothstep(0.0, 0.2, pow(1.0-length(_InUV), 1.5)) + 0.5;
// Return
_OutColor = vec4(color, 1.0);
}
@@ -1,4 +1,3 @@
// shader.frag
#version 450 #version 450
struct Material { struct Material {
@@ -7,8 +6,8 @@ struct Material {
}; };
// Variables // Variables
layout(location=0) in vec2 vert_uv; layout(location=0) in vec2 _InUV;
layout(location=0) out vec4 out_color; layout(location=0) out vec4 _OutColor;
layout(set=0,binding=0) uniform Uniforms { layout(set=0,binding=0) uniform Uniforms {
mat4 _ViewMatrix; mat4 _ViewMatrix;
@@ -61,7 +60,7 @@ vec3 randomHemisphere(vec3 dir)
vec3 solve() vec3 solve()
{ {
// Calculate ray direction // Calculate ray direction
vec3 view_dir = (_ProjMatrixInv * vec4(vert_uv, 0, 1)).xyz; vec3 view_dir = (_ProjMatrixInv * vec4(_InUV, 0, 1)).xyz;
vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz; vec3 rayDir = normalize(_ViewMatrix * vec4(view_dir,0)).xyz;
Ray primaryRay = Ray(_CamPos / SCALE, rayDir); Ray primaryRay = Ray(_CamPos / SCALE, rayDir);
@@ -91,6 +90,6 @@ vec3 solve()
void main() void main()
{ {
seed = 420 * vert_uv.x + 1337 * vert_uv.y + _Time * 1234; seed = 420 * _InUV.x + 1337 * _InUV.y + _Time * 1234;
out_color = vec4(solve(), 1); _OutColor = vec4(solve(), 1);
} }