1#include webgl_header.vs 2 3// Sphere impostor vertex shader 4 5uniform float sphere_size_scale; 6 7attribute vec4 a_vertex_radius; 8attribute vec4 a_Color; 9attribute float a_rightUpFlags; 10 11varying vec4 COLOR; 12varying vec3 sphere_center; 13varying float radius2; 14varying vec3 point; 15varying vec2 bgTextureLookup; 16 17/* 18 * horizontial and vertical adjustment of outer tangent hitting the 19 * impostor quad, in model view space. 20 */ 21vec2 outer_tangent_adjustment(vec3 center, float radius_sq) { 22 vec2 xy_dist = vec2(length(center.xz), length(center.yz)); 23 24 // without clamping, this caused flickering (divide-by-zero) 25 vec2 cos_a = clamp(center.z / xy_dist, -1., 1.); 26 vec2 cos_b = xy_dist / sqrt(radius_sq + (xy_dist * xy_dist)); 27 28 // numerically more stable version of: 29 // vec2 tan_ab_sq = pow(tan(acos(cos_b) + acos(cos_a)), 2); 30 vec2 cos_ab = (cos_a * cos_b + sqrt( 31 (1. - cos_a * cos_a) * 32 (1. - cos_b * cos_b))); 33 vec2 cos_ab_sq = cos_ab * cos_ab; 34 vec2 tan_ab_sq = (1. - cos_ab_sq) / cos_ab_sq; 35 36 vec2 adjustment = sqrt(tan_ab_sq + 1.); 37 38 // max out (empirical) to avoid exploding (can happen for spheres outside of the viewport) 39 return min(adjustment, 10.); 40} 41 42void main(void) 43{ 44 // Get billboard attributes 45 float radius = a_vertex_radius.w * sphere_size_scale; 46 47 // support uniform scaling 48 radius /= length(g_NormalMatrix[0]); 49 50 float right = -1. + 2.*mod(a_rightUpFlags, 2.); 51 float up = -1. + 2.*floor(mod(a_rightUpFlags/2., 2.)); 52 vec4 tmppos = g_ModelViewMatrix * vec4(a_vertex_radius.xyz, 1.); 53 54 COLOR = a_Color; 55 radius2 = radius * radius; // compute squared radius 56 57 // uni-radius corner offset 58 vec2 corner_offset = vec2(right, up); 59 60#ifndef ortho 61 // horizontial and vertical adjustment due to projection 62 corner_offset *= outer_tangent_adjustment(tmppos.xyz, radius2); 63#endif 64 65 // corner vertex 66 vec4 eye_space_pos = tmppos; 67 eye_space_pos.xy += radius * corner_offset; 68 69 // Compute sphere position in modelview space 70 sphere_center = tmppos.xyz / tmppos.w; 71 72 // Compute ray direction and origin point 73 point = eye_space_pos.xyz / eye_space_pos.w; 74 75#ifndef PYMOL_WEBGL_IOS 76 // Pass the transformed vertex for clipping plane calculations 77 gl_ClipVertex = eye_space_pos; 78#endif 79 80 // Pass transformed vertex 81 gl_Position = g_ProjectionMatrix * eye_space_pos; 82 bgTextureLookup = (gl_Position.xy/gl_Position.w) / 2.0 + 0.5; 83} 84 85