The open source OpenXR runtime
at main 88 lines 2.0 kB view raw
1// Copyright 2023, Collabora Ltd. 2// Author: Jakob Bornecrantz <jakob@collabora.com> 3// SPDX-License-Identifier: BSL-1.0 4 5#version 460 6 7 8// Number of subdivisions. 9layout(constant_id = 0) const uint subdivision_count = 360; 10 11layout (binding = 0, std140) uniform Config 12{ 13 vec4 post_transform; 14 mat4 mvp; 15 float radius; 16 float central_angle; 17 float aspect_ratio; 18 float _pad; 19} ubo; 20 21layout (location = 0) out vec2 out_uv; 22 23out gl_PerVertex 24{ 25 vec4 gl_Position; 26}; 27 28 29vec2 get_uv_for_vertex() 30{ 31 // One edge on either endstop and one between each subdivision. 32 uint edges = subdivision_count + 1; 33 34 // Goes from [0 .. 2^31], two vertices per edge. 35 uint x_u32 = bitfieldExtract(uint(gl_VertexIndex), 1, 31); 36 37 // Goes from [0 .. 1] every other vertex. 38 uint y_u32 = bitfieldExtract(uint(gl_VertexIndex), 0, 1); 39 40 // Starts at zero to get to [0 .. 1], there is two vertices per edge. 41 float x = float(x_u32) / float(edges); 42 43 // Already in [0 .. 1] just transform to float. 44 float y = float(y_u32); 45 46 return vec2(x, y); 47} 48 49vec3 get_position_for_uv(vec2 uv) 50{ 51 float radius = ubo.radius; 52 float angle = ubo.central_angle; 53 float ratio = ubo.aspect_ratio; 54 55 // [0 .. 1] to [-0.5 .. 0.5] 56 float mixed_u = uv.x - 0.5; 57 58 // [-0.5 .. 0.5] to [-angle / 2 .. angle / 2]. 59 float a = mixed_u * angle; 60 61 // [0 .. 1] to [0.5 .. -0.5] notice fliped sign to be in OpenXR space. 62 float mixed_v = 0.5 - uv.y; 63 64 // This the total height acording to the spec. 65 float total_height = (angle * radius) / ratio; 66 67 // Calculate the position. 68 float x = sin(a) * radius; // At angle zero at x = 0. 69 float y = total_height * mixed_v; 70 float z = -cos(a) * radius; // At angle zero at z = -1. 71 72 return vec3(x, y, z); 73} 74 75void main() 76{ 77 // We now get a unmodified UV position. 78 vec2 raw_uv = get_uv_for_vertex(); 79 80 // Get the position for the raw UV. 81 vec3 position = get_position_for_uv(raw_uv); 82 83 // To deal with OpenGL flip and sub image view. 84 vec2 uv = fma(raw_uv, ubo.post_transform.zw, ubo.post_transform.xy); 85 86 gl_Position = ubo.mvp * vec4(position, 1.0); 87 out_uv = uv; 88}