85 lines
2.4 KiB
GLSL
85 lines
2.4 KiB
GLSL
#include webgl_header.vs
|
|||
|
|
|
||
|
|
// Sphere impostor vertex shader
|
||
|
|
|
||
|
|
uniform float sphere_size_scale;
|
||
|
|
|
||
|
|
attribute vec4 a_vertex_radius;
|
||
|
|
attribute vec4 a_Color;
|
||
|
|
attribute float a_rightUpFlags;
|
||
|
|
|
||
|
|
varying vec4 COLOR;
|
||
|
|
varying vec3 sphere_center;
|
||
|
|
varying float radius2;
|
||
|
|
varying vec3 point;
|
||
|
|
varying vec2 bgTextureLookup;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* horizontial and vertical adjustment of outer tangent hitting the
|
||
|
|
* impostor quad, in model view space.
|
||
|
|
*/
|
||
|
|
vec2 outer_tangent_adjustment(vec3 center, float radius_sq) {
|
||
|
|
vec2 xy_dist = vec2(length(center.xz), length(center.yz));
|
||
|
|
|
||
|
|
// without clamping, this caused flickering (divide-by-zero)
|
||
|
|
vec2 cos_a = clamp(center.z / xy_dist, -1., 1.);
|
||
|
|
vec2 cos_b = xy_dist / sqrt(radius_sq + (xy_dist * xy_dist));
|
||
|
|
|
||
|
|
// numerically more stable version of:
|
||
|
|
// vec2 tan_ab_sq = pow(tan(acos(cos_b) + acos(cos_a)), 2);
|
||
|
|
vec2 cos_ab = (cos_a * cos_b + sqrt(
|
||
|
|
(1. - cos_a * cos_a) *
|
||
|
|
(1. - cos_b * cos_b)));
|
||
|
|
vec2 cos_ab_sq = cos_ab * cos_ab;
|
||
|
|
vec2 tan_ab_sq = (1. - cos_ab_sq) / cos_ab_sq;
|
||
|
|
|
||
|
|
vec2 adjustment = sqrt(tan_ab_sq + 1.);
|
||
|
|
|
||
|
|
// max out (empirical) to avoid exploding (can happen for spheres outside of the viewport)
|
||
|
|
return min(adjustment, 10.);
|
||
|
|
}
|
||
|
|
|
||
|
|
void main(void)
|
||
|
|
{
|
||
|
|
// Get billboard attributes
|
||
|
|
float radius = a_vertex_radius.w * sphere_size_scale;
|
||
|
|
|
||
|
|
// support uniform scaling
|
||
|
|
radius /= length(g_NormalMatrix[0]);
|
||
|
|
|
||
|
|
float right = -1. + 2.*mod(a_rightUpFlags, 2.);
|
||
|
|
float up = -1. + 2.*floor(mod(a_rightUpFlags/2., 2.));
|
||
|
|
vec4 tmppos = g_ModelViewMatrix * vec4(a_vertex_radius.xyz, 1.);
|
||
|
|
|
||
|
|
COLOR = a_Color;
|
||
|
|
radius2 = radius * radius; // compute squared radius
|
||
|
|
|
||
|
|
// uni-radius corner offset
|
||
|
|
vec2 corner_offset = vec2(right, up);
|
||
|
|
|
||
|
|
#ifndef ortho
|
||
|
|
// horizontial and vertical adjustment due to projection
|
||
|
|
corner_offset *= outer_tangent_adjustment(tmppos.xyz, radius2);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// corner vertex
|
||
|
|
vec4 eye_space_pos = tmppos;
|
||
|
|
eye_space_pos.xy += radius * corner_offset;
|
||
|
|
|
||
|
|
// Compute sphere position in modelview space
|
||
|
|
sphere_center = tmppos.xyz / tmppos.w;
|
||
|
|
|
||
|
|
// Compute ray direction and origin point
|
||
|
|
point = eye_space_pos.xyz / eye_space_pos.w;
|
||
|
|
|
||
|
|
#ifndef PYMOL_WEBGL_IOS
|
||
|
|
// Pass the transformed vertex for clipping plane calculations
|
||
|
|
gl_ClipVertex = eye_space_pos;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// Pass transformed vertex
|
||
|
|
gl_Position = g_ProjectionMatrix * eye_space_pos;
|
||
|
|
bgTextureLookup = (gl_Position.xy/gl_Position.w) / 2.0 + 0.5;
|
||
|
|
}
|
||
|
|
|