Draft ambient occlusion
This commit is contained in:
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
layout(input_attachment_index = 0, set = 1, binding = 0) uniform subpassInput u_color;
|
layout(input_attachment_index = 0, set = 1, binding = 0) uniform subpassInput u_color;
|
||||||
layout(input_attachment_index = 1, set = 1, binding = 1) uniform subpassInput u_normals;
|
layout(input_attachment_index = 1, set = 1, binding = 1) uniform subpassInput u_normals;
|
||||||
layout(input_attachment_index = 2, set = 1, binding = 2) uniform subpassInput u_depth;
|
layout(input_attachment_index = 2, set = 1, binding = 2) uniform subpassInput u_ao_r_m;
|
||||||
|
layout(input_attachment_index = 3, set = 1, binding = 3) uniform subpassInput u_depth;
|
||||||
|
|
||||||
layout(location = 0) in vec2 v_pos;
|
layout(location = 0) in vec2 v_pos;
|
||||||
layout(location = 0) out vec4 f_color;
|
layout(location = 0) out vec4 f_color;
|
||||||
@@ -22,7 +23,7 @@ vec3 calculate_view_position(float depth)
|
|||||||
return (view_position.xyz / view_position.w);
|
return (view_position.xyz / view_position.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 shading(vec3 normal, vec3 position)
|
vec3 shading(vec3 normal, vec3 position, float ao)
|
||||||
{
|
{
|
||||||
vec3 accum = vec3(0., 0., 0.);
|
vec3 accum = vec3(0., 0., 0.);
|
||||||
|
|
||||||
@@ -32,16 +33,17 @@ vec3 shading(vec3 normal, vec3 position)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//return vec3(int(position.x * 256.0) ^ int(position.y * 256.0) ^ int(position.z * 256.0));
|
//return vec3(int(position.x * 256.0) ^ int(position.y * 256.0) ^ int(position.z * 256.0));
|
||||||
return accum;
|
return accum * ao;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 col = subpassLoad(u_color).xyz;
|
|
||||||
vec3 normal = subpassLoad(u_normals).xyz;
|
|
||||||
float depth = subpassLoad(u_depth).x;
|
float depth = subpassLoad(u_depth).x;
|
||||||
if (depth == 1.0) {
|
if (depth == 1.0) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
vec3 col = subpassLoad(u_color).xyz;
|
||||||
|
vec3 normal = subpassLoad(u_normals).xyz;
|
||||||
|
float ao = subpassLoad(u_ao_r_m).x;
|
||||||
vec3 position = calculate_view_position(depth);
|
vec3 position = calculate_view_position(depth);
|
||||||
f_color = vec4(col * shading(normal, position), 1.0);
|
f_color = vec4(col * shading(normal, position, ao), 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-16
@@ -44,7 +44,11 @@ use vulkano::{
|
|||||||
QueueCreateInfo, QueueFlags, physical::PhysicalDeviceType,
|
QueueCreateInfo, QueueFlags, physical::PhysicalDeviceType,
|
||||||
},
|
},
|
||||||
format::{ClearValue, Format},
|
format::{ClearValue, Format},
|
||||||
image::{Image, ImageCreateInfo, ImageType, ImageUsage, SampleCount, view::ImageView},
|
image::{
|
||||||
|
Image, ImageAspects, ImageCreateInfo, ImageSubresourceRange, ImageType, ImageUsage,
|
||||||
|
SampleCount,
|
||||||
|
view::{ImageView, ImageViewCreateInfo},
|
||||||
|
},
|
||||||
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
||||||
memory::allocator::{
|
memory::allocator::{
|
||||||
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
|
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
|
||||||
@@ -219,6 +223,7 @@ struct RenderContext {
|
|||||||
framebuffers: Vec<Arc<Framebuffer>>,
|
framebuffers: Vec<Arc<Framebuffer>>,
|
||||||
color_buffer: Arc<ImageView>,
|
color_buffer: Arc<ImageView>,
|
||||||
material_buffer: Arc<ImageView>,
|
material_buffer: Arc<ImageView>,
|
||||||
|
ao_r_m_buffer: Arc<ImageView>,
|
||||||
normal_buffer: Arc<ImageView>,
|
normal_buffer: Arc<ImageView>,
|
||||||
depth_buffer: Arc<ImageView>,
|
depth_buffer: Arc<ImageView>,
|
||||||
camera_buffers: Vec<Subbuffer<Camera>>,
|
camera_buffers: Vec<Subbuffer<Camera>>,
|
||||||
@@ -641,6 +646,12 @@ impl ApplicationHandler for App {
|
|||||||
load_op: Clear,
|
load_op: Clear,
|
||||||
store_op: DontCare,
|
store_op: DontCare,
|
||||||
},
|
},
|
||||||
|
ao_r_m: {
|
||||||
|
format: Format::A2B10G10R10_UNORM_PACK32,
|
||||||
|
samples: 1,
|
||||||
|
load_op: Clear,
|
||||||
|
store_op: DontCare,
|
||||||
|
},
|
||||||
normals: {
|
normals: {
|
||||||
format: Format::R16G16B16A16_SFLOAT,
|
format: Format::R16G16B16A16_SFLOAT,
|
||||||
samples: 1,
|
samples: 1,
|
||||||
@@ -648,7 +659,7 @@ impl ApplicationHandler for App {
|
|||||||
store_op: DontCare,
|
store_op: DontCare,
|
||||||
},
|
},
|
||||||
depth: {
|
depth: {
|
||||||
format: Format::D16_UNORM,
|
format: Format::D24_UNORM_S8_UINT,
|
||||||
samples: 1,
|
samples: 1,
|
||||||
load_op: Clear,
|
load_op: Clear,
|
||||||
store_op: DontCare,
|
store_op: DontCare,
|
||||||
@@ -660,14 +671,14 @@ impl ApplicationHandler for App {
|
|||||||
input: [],
|
input: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: [color, normals],
|
color: [color, normals, ao_r_m],
|
||||||
depth_stencil: {},
|
depth_stencil: {},
|
||||||
input: [material, depth],
|
input: [material, depth],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: [final_color],
|
color: [final_color],
|
||||||
depth_stencil: {},
|
depth_stencil: {},
|
||||||
input: [color, normals, depth],
|
input: [color, normals, ao_r_m, depth],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
color: [final_color],
|
color: [final_color],
|
||||||
@@ -683,8 +694,14 @@ impl ApplicationHandler for App {
|
|||||||
depth_range: 0.0..=1.0,
|
depth_range: 0.0..=1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (framebuffers, color_buffer, material_buffer, normal_buffer, depth_buffer) =
|
let (
|
||||||
framebuffer_generation(&images, &render_pass, &self.memory_allocator);
|
framebuffers,
|
||||||
|
color_buffer,
|
||||||
|
material_buffer,
|
||||||
|
ao_r_m_buffer,
|
||||||
|
normal_buffer,
|
||||||
|
depth_buffer,
|
||||||
|
) = framebuffer_generation(&images, &render_pass, &self.memory_allocator);
|
||||||
|
|
||||||
let lighting_pipeline = pipeline_recompile(
|
let lighting_pipeline = pipeline_recompile(
|
||||||
&render_pass,
|
&render_pass,
|
||||||
@@ -722,6 +739,7 @@ impl ApplicationHandler for App {
|
|||||||
framebuffers,
|
framebuffers,
|
||||||
color_buffer,
|
color_buffer,
|
||||||
material_buffer,
|
material_buffer,
|
||||||
|
ao_r_m_buffer,
|
||||||
normal_buffer,
|
normal_buffer,
|
||||||
depth_buffer,
|
depth_buffer,
|
||||||
camera_buffers,
|
camera_buffers,
|
||||||
@@ -897,11 +915,11 @@ impl App {
|
|||||||
|
|
||||||
fn update_camera_uniform(&self, rcx: &mut RenderContext, index: usize) {
|
fn update_camera_uniform(&self, rcx: &mut RenderContext, index: usize) {
|
||||||
let near = 0.01;
|
let near = 0.01;
|
||||||
let far = 100.0;
|
|
||||||
|
|
||||||
let aspect_ratio =
|
let aspect_ratio =
|
||||||
rcx.swapchain.image_extent()[0] as f32 / rcx.swapchain.image_extent()[1] as f32;
|
rcx.swapchain.image_extent()[0] as f32 / rcx.swapchain.image_extent()[1] as f32;
|
||||||
let proj = Mat4::perspective_rh(std::f32::consts::FRAC_PI_2, aspect_ratio, near, far);
|
let proj =
|
||||||
|
Mat4::perspective_infinite_reverse_rh(std::f32::consts::FRAC_PI_2, aspect_ratio, near);
|
||||||
let view = Mat4::from_euler(EulerRot::XYZ, self.cstate.forward.x.to_radians(), self.cstate.forward.y.to_radians(), self.cstate.forward.z.to_radians())
|
let view = Mat4::from_euler(EulerRot::XYZ, self.cstate.forward.x.to_radians(), self.cstate.forward.y.to_radians(), self.cstate.forward.z.to_radians())
|
||||||
//* Mat4::from_rotation_z(std::f32::consts::PI)
|
//* Mat4::from_rotation_z(std::f32::consts::PI)
|
||||||
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
|
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
|
||||||
@@ -1048,7 +1066,8 @@ impl App {
|
|||||||
[
|
[
|
||||||
WriteDescriptorSet::image_view(0, rcx.color_buffer.clone()),
|
WriteDescriptorSet::image_view(0, rcx.color_buffer.clone()),
|
||||||
WriteDescriptorSet::image_view(1, rcx.normal_buffer.clone()),
|
WriteDescriptorSet::image_view(1, rcx.normal_buffer.clone()),
|
||||||
WriteDescriptorSet::image_view(2, rcx.depth_buffer.clone()),
|
WriteDescriptorSet::image_view(2, rcx.ao_r_m_buffer.clone()),
|
||||||
|
WriteDescriptorSet::image_view(3, rcx.depth_buffer.clone()),
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
@@ -1279,6 +1298,7 @@ impl App {
|
|||||||
rcx.framebuffers,
|
rcx.framebuffers,
|
||||||
rcx.color_buffer,
|
rcx.color_buffer,
|
||||||
rcx.material_buffer,
|
rcx.material_buffer,
|
||||||
|
rcx.ao_r_m_buffer,
|
||||||
rcx.normal_buffer,
|
rcx.normal_buffer,
|
||||||
rcx.depth_buffer,
|
rcx.depth_buffer,
|
||||||
) = framebuffer_generation(&new_images, &rcx.render_pass, &self.memory_allocator);
|
) = framebuffer_generation(&new_images, &rcx.render_pass, &self.memory_allocator);
|
||||||
@@ -1355,7 +1375,8 @@ impl App {
|
|||||||
Some(ClearValue::Uint([0, 0, 0, 0])),
|
Some(ClearValue::Uint([0, 0, 0, 0])),
|
||||||
Some([0.12, 0.1, 0.1, 1.0].into()),
|
Some([0.12, 0.1, 0.1, 1.0].into()),
|
||||||
Some([0.0, 0.0, 0.0, 1.0].into()),
|
Some([0.0, 0.0, 0.0, 1.0].into()),
|
||||||
Some(1.0.into()),
|
Some([0.0, 0.0, 0.0, 1.0].into()),
|
||||||
|
Some((0.0, 0).into()),
|
||||||
],
|
],
|
||||||
..RenderPassBeginInfo::framebuffer(rcx.framebuffers[image_index].clone())
|
..RenderPassBeginInfo::framebuffer(rcx.framebuffers[image_index].clone())
|
||||||
},
|
},
|
||||||
@@ -1471,13 +1492,13 @@ fn framebuffer_generation(
|
|||||||
Arc<ImageView>,
|
Arc<ImageView>,
|
||||||
Arc<ImageView>,
|
Arc<ImageView>,
|
||||||
Arc<ImageView>,
|
Arc<ImageView>,
|
||||||
|
Arc<ImageView>,
|
||||||
) {
|
) {
|
||||||
let depth_buffer = ImageView::new_default(
|
let depth_buffer = Image::new(
|
||||||
Image::new(
|
|
||||||
allocator.clone(),
|
allocator.clone(),
|
||||||
ImageCreateInfo {
|
ImageCreateInfo {
|
||||||
image_type: ImageType::Dim2d,
|
image_type: ImageType::Dim2d,
|
||||||
format: Format::D16_UNORM,
|
format: Format::D24_UNORM_S8_UINT,
|
||||||
extent: images[0].extent(),
|
extent: images[0].extent(),
|
||||||
usage: ImageUsage::DEPTH_STENCIL_ATTACHMENT
|
usage: ImageUsage::DEPTH_STENCIL_ATTACHMENT
|
||||||
| ImageUsage::INPUT_ATTACHMENT
|
| ImageUsage::INPUT_ATTACHMENT
|
||||||
@@ -1486,7 +1507,19 @@ fn framebuffer_generation(
|
|||||||
},
|
},
|
||||||
AllocationCreateInfo::default(),
|
AllocationCreateInfo::default(),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap();
|
||||||
|
|
||||||
|
let depth_buffer_ds = ImageView::new_default(depth_buffer.clone()).unwrap();
|
||||||
|
let depth_buffer_d = ImageView::new(
|
||||||
|
depth_buffer.clone(),
|
||||||
|
ImageViewCreateInfo {
|
||||||
|
subresource_range: ImageSubresourceRange {
|
||||||
|
aspects: ImageAspects::DEPTH,
|
||||||
|
mip_levels: 0..1,
|
||||||
|
array_layers: 0..1,
|
||||||
|
},
|
||||||
|
..ImageViewCreateInfo::from_image(&depth_buffer.clone())
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1526,6 +1559,24 @@ fn framebuffer_generation(
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let ao_r_m_buffer = ImageView::new_default(
|
||||||
|
Image::new(
|
||||||
|
allocator.clone(),
|
||||||
|
ImageCreateInfo {
|
||||||
|
image_type: ImageType::Dim2d,
|
||||||
|
format: Format::A2B10G10R10_UNORM_PACK32,
|
||||||
|
extent: images[0].extent(),
|
||||||
|
usage: ImageUsage::COLOR_ATTACHMENT
|
||||||
|
| ImageUsage::INPUT_ATTACHMENT
|
||||||
|
| ImageUsage::TRANSIENT_ATTACHMENT,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
AllocationCreateInfo::default(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let normal_buffer = ImageView::new_default(
|
let normal_buffer = ImageView::new_default(
|
||||||
Image::new(
|
Image::new(
|
||||||
allocator.clone(),
|
allocator.clone(),
|
||||||
@@ -1555,8 +1606,9 @@ fn framebuffer_generation(
|
|||||||
view,
|
view,
|
||||||
material_buffer.clone(),
|
material_buffer.clone(),
|
||||||
color_buffer.clone(),
|
color_buffer.clone(),
|
||||||
|
ao_r_m_buffer.clone(),
|
||||||
normal_buffer.clone(),
|
normal_buffer.clone(),
|
||||||
depth_buffer.clone(),
|
depth_buffer_ds.clone(),
|
||||||
],
|
],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -1569,8 +1621,9 @@ fn framebuffer_generation(
|
|||||||
framebuffers,
|
framebuffers,
|
||||||
color_buffer,
|
color_buffer,
|
||||||
material_buffer,
|
material_buffer,
|
||||||
|
ao_r_m_buffer,
|
||||||
normal_buffer,
|
normal_buffer,
|
||||||
depth_buffer,
|
depth_buffer_d,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ layout(input_attachment_index = 1, set = 2, binding = 1) uniform subpassInput u_
|
|||||||
|
|
||||||
layout(location = 0) out vec4 f_color;
|
layout(location = 0) out vec4 f_color;
|
||||||
layout(location = 1) out vec4 f_normal;
|
layout(location = 1) out vec4 f_normal;
|
||||||
|
layout(location = 2) out vec4 f_ao_r_m;
|
||||||
|
|
||||||
float scene(vec4 p) {
|
float scene(vec4 p) {
|
||||||
return length(p.xyz) - 1.0;
|
return length(p.xyz) - 1.0;
|
||||||
@@ -40,6 +41,20 @@ vec3 getNormal(vec3 p) {
|
|||||||
return normalize(n - (scene(vec4(p, camera_uniforms.campos_and_time.w))));
|
return normalize(n - (scene(vec4(p, camera_uniforms.campos_and_time.w))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float AO_INSTENSITY = 0.1;
|
||||||
|
const float AO_STEP = 0.01;
|
||||||
|
const uint AO_MAX_ITER = 10;
|
||||||
|
|
||||||
|
float getOcclusion(vec3 p, vec3 n) {
|
||||||
|
float ao = 0.0;
|
||||||
|
float dist;
|
||||||
|
for (uint i = 0; i < AO_MAX_ITER; i++) {
|
||||||
|
dist = AO_STEP * i;
|
||||||
|
ao += max((dist - scene(vec4(p + n * dist, camera_uniforms.campos_and_time.w))) / dist, 0.0);
|
||||||
|
}
|
||||||
|
return 1.0 - ao * AO_INSTENSITY;
|
||||||
|
}
|
||||||
|
|
||||||
//Implicit Surface Entrypoint
|
//Implicit Surface Entrypoint
|
||||||
void main() {
|
void main() {
|
||||||
if (subpassLoad(u_material).x != object_uniforms.material) {
|
if (subpassLoad(u_material).x != object_uniforms.material) {
|
||||||
@@ -59,5 +74,7 @@ void main() {
|
|||||||
|
|
||||||
f_normal = vec4(normalize(rotation * n), 1.0);
|
f_normal = vec4(normalize(rotation * n), 1.0);
|
||||||
|
|
||||||
|
f_ao_r_m.x = getOcclusion(position, n);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -267,7 +267,7 @@ fn deferred_pipelines_recompile(
|
|||||||
..RasterizationState::default()
|
..RasterizationState::default()
|
||||||
}),
|
}),
|
||||||
depth_stencil_state: Some(DepthStencilState {
|
depth_stencil_state: Some(DepthStencilState {
|
||||||
depth: Some(DepthState::simple()),
|
depth: Some(DepthState::reverse()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
multisample_state: Some(MultisampleState::default()),
|
multisample_state: Some(MultisampleState::default()),
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ float scene(vec4 p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float EPSILON = .001;
|
const float EPSILON = .001;
|
||||||
const uint MAX_STEPS = 10;
|
const uint MAX_STEPS = 50;
|
||||||
const float NEARPLANE = 0.;
|
const float NEARPLANE = 0.;
|
||||||
float FARPLANE = length(object_uniforms.dimensions / 32.);
|
float FARPLANE = length(object_uniforms.dimensions / 32.);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user