diff --git a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc index 27d7c15e0cadc8aa8585b74ebfa987032eb74359..0ae60f64e7294388ee7e2eeb04a82c08da3aa087 100644 --- a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc +++ b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_data.inc @@ -20,6 +20,7 @@ struct DualLayerReprojectionTransform struct DualLayerReprojectionSubdivideParameters { + uvec2 layer_resolution; float subdivision_threshold; float interpupillary_distance; uint layer_offset; diff --git a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp index d731c53ab137a3aeeb007377a2125086b2b96dcb..ce9db34fb13a5e7b2d192d96c8d1b4c392baea66 100644 --- a/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp +++ b/res/dpr/strategy/dual_layer_reprojection/dual_layer_reprojection_subdivide.comp @@ -32,8 +32,48 @@ float linear_depth(mat4 projection_matrix, float log_depth) return projection_matrix[3][2] / (log_depth * projection_matrix[2][3] - projection_matrix[2][2]); } +vec2 compute_gradient(ivec2 coord) +{ + if(coord.x - 1 < 0 || coord.x + 1 >= parameters.layer_resolution.x) + { + return vec2(0.0); + } + + if(coord.y - 1 < 0 || coord.y + 1 >= parameters.layer_resolution.y) + { + return vec2(0.0); + } + + vec2 gradient = vec2(0.0); + + for(int offset_x = -1; offset_x <= 1; offset_x++) + { + for(int offset_y = -1; offset_y <= 1; offset_y++) + { + if(offset_x == 0 && offset_y == 0) + { + continue; + } + + ivec2 image_coord = coord + ivec2(offset_x, offset_y) + ivec2(parameters.layer_offset, 0); + float layer_depth = texelFetch(sampler_layer_depth, image_coord, 0).x; + + vec2 weights = vec2(0.0); + weights.x = -offset_y * (2.0 - abs(offset_x)); + weights.y = -offset_x * (2.0 - abs(offset_y)); + + gradient += weights * layer_depth; + } + } + + return gradient; +} + void main() { + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + vec2 layer_gradient = compute_gradient(coord); + layer_integer_depth_min = 0xFFFFFFFF; layer_integer_depth_max = 0x0; @@ -49,14 +89,13 @@ void main() for(int offset_y = local_coord.y - int(parameters.cell_border); offset_y < cell_size.y + int(parameters.cell_border); offset_y += cell_size.y) { ivec2 image_coord = cell_coord * cell_size + ivec2(offset_x, offset_y); - ivec2 image_size = ivec2(textureSize(sampler_layer_depth, 0).xy); - if(image_coord.x < 0 || image_coord.x >= image_size.x) + if(image_coord.x < 0 || image_coord.x >= parameters.layer_resolution.x) { continue; } - if(image_coord.y < 0 || image_coord.y >= image_size.y) + if(image_coord.y < 0 || image_coord.y >= parameters.layer_resolution.y) { continue; } @@ -80,13 +119,14 @@ void main() float layer_parallax_delta = abs(layer_max_parallax - layer_min_parallax); + vec4 layer_encoded_depth = imageLoad(image_layer_encoded_depth, coord + ivec2(parameters.layer_offset, 0)); + layer_encoded_depth.x = 0.0; + layer_encoded_depth.z = dot(layer_gradient, layer_gradient); + if(layer_parallax_delta > parameters.subdivision_threshold) { - ivec2 coord = ivec2(gl_GlobalInvocationID.xy); - - vec4 layer_encoded_depth = imageLoad(image_layer_encoded_depth, coord + ivec2(parameters.layer_offset, 0)); layer_encoded_depth.x = 1.0; - - imageStore(image_layer_encoded_depth, coord + ivec2(parameters.layer_offset, 0), layer_encoded_depth); } + + imageStore(image_layer_encoded_depth, coord + ivec2(parameters.layer_offset, 0), layer_encoded_depth); } \ No newline at end of file diff --git a/src/strategy/dual_layer_reprojection.cpp b/src/strategy/dual_layer_reprojection.cpp index bd0f071135daa562f6792a2094aae01d4fd752de..60d20fbb0d3effe3396c8e3540ad76933418399d 100644 --- a/src/strategy/dual_layer_reprojection.cpp +++ b/src/strategy/dual_layer_reprojection.cpp @@ -1186,7 +1186,10 @@ void DualLayerReprojection::process_layer_subdivide_pass(VkCommandBuffer command vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, this->layer_subdivide_pipeline_layout->get(), 0, 1, &this->layer_descriptor_sets[index], 0, nullptr); vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, this->layer_subdivide_pipeline_layout->get(), 1, 1, &this->layer_encoded_depth_descriptor_sets[index], 0, nullptr); + glm::uvec2 subdivide_resolution = this->get_headset()->get_framebuffer_resolution(); + glsl::DualLayerReprojectionSubdivideParameters parameters; + parameters.layer_resolution = subdivide_resolution; parameters.subdivision_threshold = this->subdivision_threshold; parameters.interpupillary_distance = this->get_headset()->get_interpupillary_distance(); parameters.layer_offset = 0; @@ -1199,14 +1202,14 @@ void DualLayerReprojection::process_layer_subdivide_pass(VkCommandBuffer command vkCmdPushConstants(command_buffer, this->layer_subdivide_pipeline_layout->get(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(parameters), ¶meters); - glm::uvec2 work_group_count = this->layer_resolution / glm::uvec2(DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE); + glm::uvec2 work_group_count = subdivide_resolution / glm::uvec2(DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE); - if (this->layer_resolution.x % DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE > 0) + if (subdivide_resolution.x % DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE > 0) { work_group_count.x += 1; } - if (this->layer_resolution.y % DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE > 0) + if (subdivide_resolution.x % DUAL_LAYER_REPROJECTION_SUBDIVIDE_GROUP_SIZE > 0) { work_group_count.y += 1; }