From 9738b4fe93ffd6d7071abf5e6f0c307a5924cad0 Mon Sep 17 00:00:00 2001 From: Lubosz Sarnecki Date: Fri, 9 Oct 2020 16:33:13 +0200 Subject: [PATCH] c/shaders: Add equirect shader. --- src/xrt/compositor/CMakeLists.txt | 2 + src/xrt/compositor/main/comp_compositor.h | 4 ++ src/xrt/compositor/main/comp_shaders.c | 13 +++++ src/xrt/compositor/shaders/equirect.frag | 68 +++++++++++++++++++++++ src/xrt/compositor/shaders/equirect.vert | 39 +++++++++++++ src/xrt/compositor/shaders/meson.build | 4 +- 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/xrt/compositor/shaders/equirect.frag create mode 100644 src/xrt/compositor/shaders/equirect.vert diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt index 7ad36844b..23159cd14 100644 --- a/src/xrt/compositor/CMakeLists.txt +++ b/src/xrt/compositor/CMakeLists.txt @@ -6,6 +6,8 @@ spirv_shaders(SHADER_HEADERS shaders/mesh.vert shaders/layer.frag shaders/layer.vert + shaders/equirect.vert + shaders/equirect.frag ) set(CLIENT_SOURCE_FILES) diff --git a/src/xrt/compositor/main/comp_compositor.h b/src/xrt/compositor/main/comp_compositor.h index 07aeebd6a..9448704be 100644 --- a/src/xrt/compositor/main/comp_compositor.h +++ b/src/xrt/compositor/main/comp_compositor.h @@ -138,6 +138,10 @@ struct comp_shaders { VkShaderModule mesh_vert; VkShaderModule mesh_frag; + + VkShaderModule equirect_vert; + VkShaderModule equirect_frag; + VkShaderModule layer_vert; VkShaderModule layer_frag; }; diff --git a/src/xrt/compositor/main/comp_shaders.c b/src/xrt/compositor/main/comp_shaders.c index 2ba27241b..16461e79f 100644 --- a/src/xrt/compositor/main/comp_shaders.c +++ b/src/xrt/compositor/main/comp_shaders.c @@ -22,6 +22,8 @@ #include "shaders/layer.frag.h" #include "shaders/layer.vert.h" +#include "shaders/equirect.frag.h" +#include "shaders/equirect.vert.h" #include "shaders/mesh.frag.h" #include "shaders/mesh.vert.h" @@ -87,6 +89,15 @@ comp_shaders_load(struct vk_bundle *vk, struct comp_shaders *s) sizeof(shaders_mesh_frag), // size &s->mesh_frag)); // out + C(shader_load(vk, // vk_bundle + shaders_equirect_vert, // data + sizeof(shaders_equirect_vert), // size + &s->equirect_vert)); // out + C(shader_load(vk, // vk_bundle + shaders_equirect_frag, // data + sizeof(shaders_equirect_frag), // size + &s->equirect_frag)); // out + C(shader_load(vk, // vk_bundle shaders_layer_vert, // data sizeof(shaders_layer_vert), // size @@ -112,6 +123,8 @@ comp_shaders_close(struct vk_bundle *vk, struct comp_shaders *s) { D(mesh_vert); D(mesh_frag); + D(equirect_vert); + D(equirect_frag); D(layer_vert); D(layer_frag); diff --git a/src/xrt/compositor/shaders/equirect.frag b/src/xrt/compositor/shaders/equirect.frag new file mode 100644 index 000000000..7f7bcce49 --- /dev/null +++ b/src/xrt/compositor/shaders/equirect.frag @@ -0,0 +1,68 @@ +// Copyright 2020 Collabora Ltd. +// Author: Lubosz Sarnecki +// SPDX-License-Identifier: BSL-1.0 + +#version 460 + +layout (location = 0) in vec2 uv; + +layout (binding = 0, std140) uniform Transformation { + mat4 mvp; + ivec2 offset; + ivec2 extent; + bool flip_y; +} ubo; +layout (binding = 1) uniform sampler2D image; + +layout (location = 0) out vec4 out_color; + +const float PI = 3.1416; + +// #define DEBUG 1 + +void main () +{ + vec2 uv_sub = vec2(ubo.offset) + uv * vec2(ubo.extent); + uv_sub /= textureSize(image, 0); + + vec2 frag_coord = vec2(uv_sub) * 2 - 1; + + vec4 view_dir = normalize(ubo.mvp * vec4(frag_coord.x, -frag_coord.y, 1, 1)); + + float lat = atan(view_dir.x, -view_dir.z) / (2 * PI); + float lon = acos(view_dir.y) / PI; + +#ifdef DEBUG + int lat_int = int(lat * 1000.0); + int lon_int = int(lon * 1000.0); + + if (lat < 0.001 && lat > -0.001) + out_color = vec4(1, 0, 0, 1); + else if (lat_int % 50 == 0) + out_color = vec4(1, 1, 1, 1); + else if (lon_int % 50 == 0) + out_color = vec4(1, 1, 1, 1); + else + out_color = vec4(lat, lon, 0, 1); +#endif + + float chan = equirect.central_horizontal_angle / (PI * 2.0f); + + // Normalize [0, 2π] to [0, 1] + float uhan = chan / 2.0f; + float lhan = -chan / 2.0f; + + // Normalize [-π/2, π/2] to [0, 1] + float uvan = equirect.upper_vertical_angle / PI + 0.5f; + float lvan = equirect.lower_vertical_angle / PI + 0.5f; + + if (lon < uvan && lon > lvan && lat < uhan && lat > lhan) +#ifdef DEBUG + out_color += texture(image, vec2(lat, lon)) / 2.0; +#else + out_color = texture(image, vec2(lat, lon)); + else + out_color = vec4(0, 0, 0, 0); +#endif +} + diff --git a/src/xrt/compositor/shaders/equirect.vert b/src/xrt/compositor/shaders/equirect.vert new file mode 100644 index 000000000..78f57c4fe --- /dev/null +++ b/src/xrt/compositor/shaders/equirect.vert @@ -0,0 +1,39 @@ +// Copyright 2020 Collabora Ltd. +// Author: Lubosz Sarnecki +// SPDX-License-Identifier: BSL-1.0 + +#version 460 + +layout (binding = 0, std140) uniform Transformation { + mat4 mvp; + ivec2 offset; + ivec2 extent; + bool flip_y; +} transformation; + +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 uv; + +layout (location = 0) out vec2 out_uv; + + +out gl_PerVertex { + vec4 gl_Position; +}; + +const mat4 mvp = mat4( + 2, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +); + +void main() { + gl_Position = mvp * vec4 (position, 1.0f); + gl_Position.y = -gl_Position.y; + out_uv = uv; + + if (transformation.flip_y) { + out_uv.y = 1.0 - out_uv.y; + } +} diff --git a/src/xrt/compositor/shaders/meson.build b/src/xrt/compositor/shaders/meson.build index 3ac4704eb..4d20ef34b 100644 --- a/src/xrt/compositor/shaders/meson.build +++ b/src/xrt/compositor/shaders/meson.build @@ -2,7 +2,9 @@ shader_srcs = [ 'mesh.frag', 'mesh.vert', 'layer.vert', - 'layer.frag' + 'layer.frag', + 'equirect.vert', + 'equirect.frag' ] shader_headers = []