postprocess render pass
This commit is contained in:
@@ -19,7 +19,7 @@ impl ShaderData {
|
||||
let extension = src_path.extension().expect("File has no extension").to_str().unwrap();
|
||||
|
||||
// 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");
|
||||
let spv_path = directory.join(filename).with_extension(format!("{}.spv", extension));
|
||||
|
||||
|
||||
+23
-3
@@ -5,7 +5,7 @@ pub mod buffers;
|
||||
use buffers::Buffers;
|
||||
|
||||
mod passes;
|
||||
use passes::RaytracePass;
|
||||
use passes::{RaytracePass, PostprocessPass};
|
||||
|
||||
pub mod camera;
|
||||
use camera::Camera;
|
||||
@@ -17,7 +17,10 @@ pub struct Renderer {
|
||||
queue: wgpu::Queue,
|
||||
swapchain_desc: wgpu::SwapChainDescriptor,
|
||||
swapchain: wgpu::SwapChain,
|
||||
// Passes
|
||||
texture: wgpu::TextureView,
|
||||
raytrace_pass: RaytracePass,
|
||||
postprocess_pass: PostprocessPass,
|
||||
// Buffers
|
||||
buffers: Buffers,
|
||||
// Other
|
||||
@@ -58,16 +61,32 @@ impl Renderer {
|
||||
let aspect = swapchain_desc.width as f32 / swapchain_desc.height as f32;
|
||||
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
|
||||
let buffers = Buffers::new(&device);
|
||||
let raytrace_pass = RaytracePass::new(&device, &swapchain_desc, &buffers);
|
||||
let postprocess_pass = PostprocessPass::new(&device, &swapchain_desc, &texture);
|
||||
|
||||
// Other
|
||||
let start = std::time::Instant::now();
|
||||
let changed_bricks: Vec<usize> = Vec::new();
|
||||
|
||||
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
|
||||
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)
|
||||
self.queue.submit(std::iter::once(encoder.finish()));
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
mod raytrace;
|
||||
pub use raytrace::RaytracePass;
|
||||
pub use raytrace::RaytracePass;
|
||||
|
||||
mod postprocess;
|
||||
pub use postprocess::PostprocessPass;
|
||||
@@ -1,9 +1,123 @@
|
||||
pub struct PostprocessPass {
|
||||
pub pipeline: wgpu::RenderPipeline
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
bind_group: wgpu::BindGroup
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -9,14 +9,14 @@ impl RaytracePass {
|
||||
|
||||
// Vertex shader
|
||||
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",
|
||||
buffers: &[],
|
||||
};
|
||||
|
||||
// Fragment shader
|
||||
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",
|
||||
targets: &[wgpu::ColorTargetState {
|
||||
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) {
|
||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Render Pass"),
|
||||
label: Some("Raytrace Pass"),
|
||||
color_attachments: &[
|
||||
wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: attachment,
|
||||
@@ -86,10 +86,7 @@ impl RaytracePass {
|
||||
render_pass.set_bind_group(2, &buffers.brick_buffer.bind_group, &[]);
|
||||
render_pass.set_bind_group(3, &buffers.material_buffer.bind_group, &[]);
|
||||
|
||||
// Vertices and indices
|
||||
render_pass.draw(0..6, 0..1); // 3.
|
||||
// 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);
|
||||
// Draw 2 triangles
|
||||
render_pass.draw(0..6, 0..1);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
#version 450
|
||||
|
||||
layout(location=0) out vec2 vert_uv;
|
||||
layout(location=0) out vec2 _InUV;
|
||||
|
||||
const vec2 positions[6] = vec2[6](
|
||||
vec2(-1.0, 1.0),
|
||||
@@ -14,6 +14,6 @@ const vec2 positions[6] = vec2[6](
|
||||
|
||||
void main()
|
||||
{
|
||||
vert_uv = positions[gl_VertexIndex];
|
||||
_InUV = positions[gl_VertexIndex];
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
}
|
||||
Binary file not shown.
@@ -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);
|
||||
}
|
||||
Binary file not shown.
@@ -1,4 +1,3 @@
|
||||
// shader.frag
|
||||
#version 450
|
||||
|
||||
struct Material {
|
||||
@@ -7,8 +6,8 @@ struct Material {
|
||||
};
|
||||
|
||||
// Variables
|
||||
layout(location=0) in vec2 vert_uv;
|
||||
layout(location=0) out vec4 out_color;
|
||||
layout(location=0) in vec2 _InUV;
|
||||
layout(location=0) out vec4 _OutColor;
|
||||
|
||||
layout(set=0,binding=0) uniform Uniforms {
|
||||
mat4 _ViewMatrix;
|
||||
@@ -61,7 +60,7 @@ vec3 randomHemisphere(vec3 dir)
|
||||
vec3 solve()
|
||||
{
|
||||
// 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;
|
||||
Ray primaryRay = Ray(_CamPos / SCALE, rayDir);
|
||||
|
||||
@@ -91,6 +90,6 @@ vec3 solve()
|
||||
|
||||
void main()
|
||||
{
|
||||
seed = 420 * vert_uv.x + 1337 * vert_uv.y + _Time * 1234;
|
||||
out_color = vec4(solve(), 1);
|
||||
seed = 420 * _InUV.x + 1337 * _InUV.y + _Time * 1234;
|
||||
_OutColor = vec4(solve(), 1);
|
||||
}
|
||||
Reference in New Issue
Block a user