diff --git a/src/xrt/compositor/main/comp_distortion.c b/src/xrt/compositor/main/comp_distortion.c index bdcfa6f1d..4b5499070 100644 --- a/src/xrt/compositor/main/comp_distortion.c +++ b/src/xrt/compositor/main/comp_distortion.c @@ -55,8 +55,7 @@ comp_distortion_init_pipeline_layout(struct comp_distortion *d); static void comp_distortion_init_pipeline(struct comp_distortion *d, VkRenderPass render_pass, - VkPipelineCache pipeline_cache, - enum xrt_distortion_model distortion_model); + VkPipelineCache pipeline_cache); static VkWriteDescriptorSet comp_distortion_get_uniform_write_descriptor_set(struct comp_distortion *d, @@ -175,6 +174,8 @@ comp_distortion_init(struct comp_distortion *d, { d->vk = &c->vk; + d->distortion_model = distortion_model; + d->ubo_vp_data[0].flip_y = flip_y; d->ubo_vp_data[1].flip_y = flip_y; @@ -182,8 +183,7 @@ comp_distortion_init(struct comp_distortion *d, comp_distortion_update_uniform_buffer_warp(d, c); comp_distortion_init_descriptor_set_layout(d); comp_distortion_init_pipeline_layout(d); - comp_distortion_init_pipeline(d, render_pass, pipeline_cache, - distortion_model); + comp_distortion_init_pipeline(d, render_pass, pipeline_cache); comp_distortion_init_descriptor_sets(d, descriptor_pool); } @@ -207,8 +207,7 @@ comp_distortion_destroy(struct comp_distortion *d) static void comp_distortion_init_pipeline(struct comp_distortion *d, VkRenderPass render_pass, - VkPipelineCache pipeline_cache, - enum xrt_distortion_model distortion_model) + VkPipelineCache pipeline_cache) { struct vk_bundle *vk = d->vk; VkResult ret; @@ -276,12 +275,10 @@ comp_distortion_init_pipeline(struct comp_distortion *d, .pDynamicStates = dynamic_states, }; - - const uint32_t *fragment_shader_code; size_t fragment_shader_size; - switch (distortion_model) { + switch (d->distortion_model) { case XRT_DISTORTION_MODEL_NONE: fragment_shader_code = shaders_none_frag; fragment_shader_size = sizeof(shaders_none_frag); @@ -541,31 +538,54 @@ static void comp_distortion_update_uniform_buffer_warp(struct comp_distortion *d, struct comp_compositor *c) { - /* - * Pano vision fragment shader - */ - // clang-format off - d->ubo_pano.hmd_warp_param[0] = c->xdev->distortion.pano.distortion_k[0]; - d->ubo_pano.hmd_warp_param[1] = c->xdev->distortion.pano.distortion_k[1]; - d->ubo_pano.hmd_warp_param[2] = c->xdev->distortion.pano.distortion_k[2]; - d->ubo_pano.hmd_warp_param[3] = c->xdev->distortion.pano.distortion_k[3]; - d->ubo_pano.aberr[0] = c->xdev->distortion.pano.aberration_k[0]; - d->ubo_pano.aberr[1] = c->xdev->distortion.pano.aberration_k[1]; - d->ubo_pano.aberr[2] = c->xdev->distortion.pano.aberration_k[2]; - d->ubo_pano.aberr[3] = c->xdev->distortion.pano.aberration_k[3]; - d->ubo_pano.lens_center[0][0] = c->xdev->views[0].lens_center.x_meters; - d->ubo_pano.lens_center[0][1] = c->xdev->views[0].lens_center.y_meters; - d->ubo_pano.lens_center[1][0] = c->xdev->views[1].lens_center.x_meters; - d->ubo_pano.lens_center[1][1] = c->xdev->views[1].lens_center.y_meters; - d->ubo_pano.viewport_scale[0] = c->xdev->views[0].display.w_meters; - d->ubo_pano.viewport_scale[1] = c->xdev->views[0].display.h_meters; - d->ubo_pano.warp_scale = c->xdev->distortion.pano.warp_scale; + switch (d->distortion_model) { + case XRT_DISTORTION_MODEL_VIVE: + /* + * VIVE fragment shader + */ + d->ubo_vive.aspect_x_over_y = c->xdev->distortion.vive.aspect_x_over_y; + d->ubo_vive.grow_for_undistort = c->xdev->distortion.vive.grow_for_undistort; - memcpy(d->ubo_handle.mapped, &d->ubo_pano, sizeof(d->ubo_pano)); + for (uint32_t i = 0; i < 2; i++) + d->ubo_vive.undistort_r2_cutoff[i] = c->xdev->distortion.vive.undistort_r2_cutoff[i]; + + for (uint32_t i = 0; i < 2; i++) + for (uint32_t j = 0; j < 2; j++) + d->ubo_vive.center[i][j] = c->xdev->distortion.vive.center[i][j]; + + for (uint32_t i = 0; i < 2; i++) + for (uint32_t j = 0; j < 3; j++) + for (uint32_t k = 0; k < 3; k++) + d->ubo_vive.coefficients[i][j][k] = c->xdev->distortion.vive.coefficients[i][j][k]; + + memcpy(d->ubo_handle.mapped, &d->ubo_vive, sizeof(d->ubo_vive)); + break; + case XRT_DISTORTION_MODEL_PANOTOOLS: + default: + /* + * Pano vision fragment shader + */ + d->ubo_pano.hmd_warp_param[0] = c->xdev->distortion.pano.distortion_k[0]; + d->ubo_pano.hmd_warp_param[1] = c->xdev->distortion.pano.distortion_k[1]; + d->ubo_pano.hmd_warp_param[2] = c->xdev->distortion.pano.distortion_k[2]; + d->ubo_pano.hmd_warp_param[3] = c->xdev->distortion.pano.distortion_k[3]; + d->ubo_pano.aberr[0] = c->xdev->distortion.pano.aberration_k[0]; + d->ubo_pano.aberr[1] = c->xdev->distortion.pano.aberration_k[1]; + d->ubo_pano.aberr[2] = c->xdev->distortion.pano.aberration_k[2]; + d->ubo_pano.aberr[3] = c->xdev->distortion.pano.aberration_k[3]; + d->ubo_pano.lens_center[0][0] = c->xdev->views[0].lens_center.x_meters; + d->ubo_pano.lens_center[0][1] = c->xdev->views[0].lens_center.y_meters; + d->ubo_pano.lens_center[1][0] = c->xdev->views[1].lens_center.x_meters; + d->ubo_pano.lens_center[1][1] = c->xdev->views[1].lens_center.y_meters; + d->ubo_pano.viewport_scale[0] = c->xdev->views[0].display.w_meters; + d->ubo_pano.viewport_scale[1] = c->xdev->views[0].display.h_meters; + d->ubo_pano.warp_scale = c->xdev->distortion.pano.warp_scale; + + memcpy(d->ubo_handle.mapped, &d->ubo_pano, sizeof(d->ubo_pano)); + } // clang-format on - /* * Common vertex shader stuff. */ @@ -683,9 +703,19 @@ comp_distortion_init_uniform_buffer(struct comp_distortion *d, memory_property_flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; memory_property_flags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - // Warp UBO in deferred fragment shader + // distortion ubo + VkDeviceSize ubo_size; + + switch (d->distortion_model) { + case XRT_DISTORTION_MODEL_PANOTOOLS: + ubo_size = sizeof(d->ubo_pano); + break; + case XRT_DISTORTION_MODEL_VIVE: ubo_size = sizeof(d->ubo_vive); break; + default: ubo_size = sizeof(d->ubo_pano); + } + ret = _create_buffer(vk, usage_flags, memory_property_flags, - &d->ubo_handle, sizeof(d->ubo_pano), NULL); + &d->ubo_handle, ubo_size, NULL); if (ret != VK_SUCCESS) { VK_DEBUG(vk, "Failed to create warp ubo buffer!"); } diff --git a/src/xrt/compositor/main/comp_distortion.h b/src/xrt/compositor/main/comp_distortion.h index 7955eada6..b78176a91 100644 --- a/src/xrt/compositor/main/comp_distortion.h +++ b/src/xrt/compositor/main/comp_distortion.h @@ -56,6 +56,8 @@ struct comp_distortion struct comp_uniform_buffer ubo_handle; struct comp_uniform_buffer ubo_viewport_handles[2]; + enum xrt_distortion_model distortion_model; + struct { float hmd_warp_param[4]; @@ -65,6 +67,15 @@ struct comp_distortion float warp_scale; } ubo_pano; + struct + { + float coefficients[2][3][4]; + float center[2][4]; + float undistort_r2_cutoff[4]; + float aspect_x_over_y; + float grow_for_undistort; + } ubo_vive; + struct { struct xrt_matrix_2x2 rot; diff --git a/src/xrt/compositor/shaders/vive.frag b/src/xrt/compositor/shaders/vive.frag index 012e2b947..cce47cf06 100644 --- a/src/xrt/compositor/shaders/vive.frag +++ b/src/xrt/compositor/shaders/vive.frag @@ -5,40 +5,17 @@ // Author: Lubosz Sarnecki #version 450 -// TODO: Don't use hard coded config -float aspect_x_over_y = 0.8999999761581421; -float grow_for_undistort = 0.6000000238418579; - -vec2 undistort_r2_cutoff = vec2(1.11622154712677, 1.101870775222778); - -vec2 center[2] = vec2[]( - vec2(0.08946027017045266, -0.009002181016260827), - vec2(-0.08933516629552526, -0.006014565287238661) -); - -vec3 coeffs[2][3] = { - // left - { - // green - vec3(-0.188236068524731, -0.221086205321053, -0.2537849057915209), - // blue - vec3(-0.07316590815739493, -0.02332400789561968, 0.02469959434698275), - // red - vec3(-0.02223805567703767, -0.04931309279533211, -0.07862881939243466), - }, - // right - { - // green - vec3(-0.1906209981894497, -0.2248896677207884, -0.2721364516782803), - // blue - vec3(-0.07346071902951497, -0.02189527566250131, 0.0581378652359256), - // red - vec3(-0.01755850332081247, -0.04517245633373419, -0.0928909347763) - } -}; - layout (binding = 0) uniform sampler2D texSampler; +layout (binding = 1, std140) uniform UBO +{ + vec4 coeffs[2][3]; + vec4 center[2]; + vec4 undistort_r2_cutoff; + float aspect_x_over_y; + float grow_for_undistort; +} ubo; + layout (location = 0) in vec2 inUV; layout (location = 1) flat in int inViewIndex; @@ -49,34 +26,34 @@ void main() { const int i = inViewIndex; - const vec2 factor = 0.5 / (1.0 + grow_for_undistort) - * vec2(1.0, aspect_x_over_y); + const vec2 factor = 0.5 / (1.0 + ubo.grow_for_undistort) + * vec2(1.0, ubo.aspect_x_over_y); vec2 texCoord = 2.0 * inUV - vec2(1.0); - texCoord.y /= aspect_x_over_y; - texCoord -= center[i]; + texCoord.y /= ubo.aspect_x_over_y; + texCoord -= ubo.center[i].xy; float r2 = dot(texCoord, texCoord); - vec3 d_inv = ((r2 * coeffs[i][2] + coeffs[i][1]) - * r2 + coeffs[i][0]) + vec3 d_inv = ((r2 * ubo.coeffs[i][2].xyz + ubo.coeffs[i][1].xyz) + * r2 + ubo.coeffs[i][0].xyz) * r2 + vec3(1.0); const vec3 d = 1.0 / d_inv; const vec2 offset = vec2(0.5); - vec2 tcR = offset + (texCoord * d.r + center[i]) * factor; - vec2 tcG = offset + (texCoord * d.g + center[i]) * factor; - vec2 tcB = offset + (texCoord * d.b + center[i]) * factor; + vec2 tcR = offset + (texCoord * d.r + ubo.center[i].xy) * factor; + vec2 tcG = offset + (texCoord * d.g + ubo.center[i].xy) * factor; + vec2 tcB = offset + (texCoord * d.b + ubo.center[i].xy) * factor; vec3 color = vec3( texture(texSampler, tcR).r, texture(texSampler, tcG).g, texture(texSampler, tcB).b); - if (r2 > undistort_r2_cutoff[i]) { + if (r2 > ubo.undistort_r2_cutoff[i]) { color *= 0.125; }