#version 450 // vim: ft=c struct PosNorm { vec4 pos; vec4 norm; }; layout(std430, set = 0, binding = 0) buffer positions_buffer { PosNorm posnrm[]; } pos; layout(push_constant, std430) uniform pc { layout(offset=0) vec4 cam_orig; layout(offset=16) vec4 cam_rot; layout(offset=32) uvec2 screen_res; }; layout (location = 0) out vec4 normal; layout (location = 1) out vec4 pos_pre; const float PI = 3.14159; // Forgive me for I have sinned const float TAU = PI*2.0; void main() { // assign outs normal = pos.posnrm[gl_VertexIndex].norm; pos_pre = pos.posnrm[gl_VertexIndex].pos; // define constants const float zFar = 100.0; const float zNear = 0.1; // assign the transformee gl_Position = pos.posnrm[gl_VertexIndex].pos; mat4 fix_coordinates = mat4( -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 view_orig = mat4( 1.0, 0.0, 0.0, cam_orig.x, 0.0, 1.0, 0.0, cam_orig.y, 0.0, 0.0, 1.0, cam_orig.z, 0.0, 0.0, 0.0, 1.0 ); mat4 view_rot_xz = mat4( cos(cam_rot.y), 0.0, sin(cam_rot.y), 0.0, 0.0, 1.0, 0.0, 0.0, -sin(cam_rot.y), 0.0, cos(cam_rot.y), 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 view_rot_yz = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, cos(cam_rot.x), sin(cam_rot.x), 0.0, 0.0, -sin(cam_rot.x), cos(cam_rot.x), 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 project_aspect = mat4( (float(screen_res.y)/float(screen_res.x)), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 project_znear = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, -zNear, 0.0, 0.0, 0.0, 1.0 ); mat4 project_div = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, tan((70.0/2.0)/360.0*TAU), 0.0 ); mat4 project_normal = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0/zFar, 0.0, 0.0, 0.0, 0.0, 1.0 ); // vulkan has inverted screen coordinates // but we want regular mesh coordinates // gl_Position.xyz *= -1.0 gl_Position *= fix_coordinates; // apply view's origin transformation //gl_Position.xyz += cam_orig.xyz; // gl_Position *= view_orig; // apply view's xz rotation //mat2 xz_rot; //xz_rot[0] = vec2(cos(cam_rot.y), -sin(cam_rot.y)); //xz_rot[1] = vec2(sin(cam_rot.y), cos(cam_rot.y)); //gl_Position.xz *= inverse(xz_rot); gl_Position *= view_rot_xz; // apply view's yz rotation //mat2 yz_rot; //yz_rot[0] = vec2(cos(cam_rot.x), -sin(cam_rot.x)); //yz_rot[1] = vec2(sin(cam_rot.x), cos(cam_rot.x)); //gl_Position.yz *= inverse(yz_rot); gl_Position *= view_rot_yz; // aspect correction //gl_Position.x *= (1080.0/1920.0); gl_Position *= project_aspect; // z near correction //gl_Position.z -= zNear; gl_Position *= project_znear; // division by z // has to be assigned by w so that the hardware performs the division AFTER clipping. //gl_Position.w = (gl_Position.z*sin(140.0/360.0*TAU)); gl_Position *= project_div; // z normalization //gl_Position.z /= zFar; gl_Position *= project_normal; }