sphere.vs (pymol-v2.1.0.tar.bz2) | : | sphere.vs (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
#include webgl_header.vs | ||||
// Sphere impostor vertex shader | // Sphere impostor vertex shader | |||
uniform bool lighting_enabled; | ||||
uniform float sphere_size_scale; | uniform float sphere_size_scale; | |||
uniform float horizontal_adjustment; | ||||
uniform float vertical_adjustment; | ||||
attribute vec4 a_vertex_radius; | attribute vec4 a_vertex_radius; | |||
attribute vec4 a_Color; | attribute vec4 a_Color; | |||
attribute float a_rightUpFlags; | attribute float a_rightUpFlags; | |||
varying vec4 COLOR; | varying vec4 COLOR; | |||
varying vec3 sphere_center; | varying vec3 sphere_center; | |||
varying float radius2; | varying float radius2; | |||
varying vec3 point; | varying vec3 point; | |||
varying vec2 bgTextureLookup; | 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) | void main(void) | |||
{ | { | |||
// Get billboard attributes | // Get billboard attributes | |||
float radius = a_vertex_radius.w * sphere_size_scale; | 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 right = -1. + 2.*mod(a_rightUpFlags, 2.); | |||
float up = -1. + 2.*floor(mod(a_rightUpFlags/2., 2.)); | float up = -1. + 2.*floor(mod(a_rightUpFlags/2., 2.)); | |||
vec4 a_Vertex = vec4(a_vertex_radius.xyz, 1.); | vec4 tmppos = g_ModelViewMatrix * vec4(a_vertex_radius.xyz, 1.); | |||
COLOR = a_Color; | COLOR = a_Color; | |||
radius2 = radius * radius; // compute squared radius | radius2 = radius * radius; // compute squared radius | |||
vec3 right_vector = vec3(gl_ModelViewMatrix[0][0], | // uni-radius corner offset | |||
gl_ModelViewMatrix[1][0], gl_ModelViewMatrix[2][0]); | vec2 corner_offset = vec2(right, up); | |||
vec3 up_vector = vec3(gl_ModelViewMatrix[0][1], | ||||
gl_ModelViewMatrix[1][1], gl_ModelViewMatrix[2][1]); | ||||
// We need to project the vertex out to the edge of the square, which | ||||
// is the following distance: | ||||
// float corner_distance = sqrt(2.0 * radius2); | ||||
// but since we need to normalize the corner vector computed below | ||||
// which has length sqrt(2.0), we can simply use radius as corner distance | ||||
// to compute vertex position of screen-oriented quad. | ||||
// Compute corner vector | ||||
vec3 corner_direction = (vertical_adjustment*up) * up_vector + (horizontal_ | ||||
adjustment*right) * right_vector; | ||||
// Calculate vertex of screen-oriented quad (billboard) | ||||
vec4 vertex = vec4(a_Vertex.xyz + radius * corner_direction, 1.); | ||||
// Calculate vertex position in modelview space | #ifndef ortho | |||
vec4 eye_space_pos = gl_ModelViewMatrix * vertex; | // 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 | // Compute sphere position in modelview space | |||
vec4 tmppos = gl_ModelViewMatrix * a_Vertex; | ||||
sphere_center = tmppos.xyz / tmppos.w; | sphere_center = tmppos.xyz / tmppos.w; | |||
// Compute ray direction and origin point | // Compute ray direction and origin point | |||
point = eye_space_pos.xyz / eye_space_pos.w; | point = eye_space_pos.xyz / eye_space_pos.w; | |||
#ifndef PYMOL_WEBGL_IOS | ||||
// Pass the transformed vertex for clipping plane calculations | // Pass the transformed vertex for clipping plane calculations | |||
gl_ClipVertex = eye_space_pos; | gl_ClipVertex = eye_space_pos; | |||
#endif | ||||
// Pass transformed vertex | // Pass transformed vertex | |||
gl_Position = gl_ModelViewProjectionMatrix * vertex; | gl_Position = g_ProjectionMatrix * eye_space_pos; | |||
bgTextureLookup = (gl_Position.xy/gl_Position.w) / 2.0 + 0.5; | bgTextureLookup = (gl_Position.xy/gl_Position.w) / 2.0 + 0.5; | |||
} | } | |||
End of changes. 12 change blocks. | ||||
28 lines changed or deleted | 45 lines changed or added |