mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-06 20:24:23 +08:00
95 lines
2.4 KiB
GLSL
95 lines
2.4 KiB
GLSL
#ifdef PYMOL_WEBGL_IOS
|
|
#extension GL_EXT_frag_depth : require
|
|
#endif
|
|
|
|
#include webgl_header.fs
|
|
|
|
// Sphere impostor fragment shader
|
|
|
|
varying vec4 COLOR;
|
|
varying vec3 sphere_center;
|
|
varying float radius2;
|
|
varying vec3 point;
|
|
|
|
varying vec2 bgTextureLookup;
|
|
|
|
uniform bool lighting_enabled;
|
|
uniform mat4 g_ProjectionMatrix;
|
|
uniform float g_Fog_end;
|
|
uniform float g_Fog_scale;
|
|
|
|
#include anaglyph_header.fs
|
|
#include compute_fog_color.fs
|
|
#include compute_color_for_light.fs
|
|
|
|
void main(void)
|
|
{
|
|
#ifdef ortho
|
|
vec3 ray_origin = point;
|
|
vec3 ray_direction = vec3(0., 0., -1.);
|
|
vec3 sphere_direction = ray_origin - sphere_center;
|
|
#else
|
|
vec3 ray_origin = vec3(0., 0., 0.);
|
|
vec3 ray_direction = normalize(point);
|
|
vec3 sphere_direction = sphere_center;
|
|
#endif
|
|
|
|
// Calculate sphere-ray intersection
|
|
float b = dot(sphere_direction, ray_direction);
|
|
|
|
float position = b * b + radius2 - dot(sphere_direction, sphere_direction);
|
|
|
|
// Check if the ray missed the sphere
|
|
if (position < 0.0)
|
|
discard;
|
|
|
|
// Calculate nearest point of intersection
|
|
float nearest = b - sqrt(position);
|
|
|
|
// Calculate intersection point on the sphere surface. The ray
|
|
// origin is at the quad (center point), so we need to project
|
|
// back towards the user to get the front face.
|
|
vec3 ipoint = nearest * ray_direction + ray_origin;
|
|
|
|
// Calculate normal at the intersection point
|
|
vec3 normal = normalize(ipoint - sphere_center);
|
|
|
|
// Calculate depth in clipping space
|
|
vec2 clipZW = ipoint.z * g_ProjectionMatrix[2].zw +
|
|
g_ProjectionMatrix[3].zw;
|
|
|
|
float depth = 0.5 + 0.5 * clipZW.x / clipZW.y;
|
|
|
|
// this is a workaround necessary for Mac
|
|
// otherwise the modified fragment won't clip properly
|
|
|
|
/*
|
|
float isDiscarded = step(.5, step(depth, 0.) + step(1.-depth, 0.));
|
|
if (isDiscarded > 0.0)
|
|
discard;
|
|
*/
|
|
if (depth <= 0.0 || depth >= 1.0)
|
|
discard;
|
|
|
|
gl_FragDepth = depth;
|
|
|
|
if (!isPicking){
|
|
if (lighting_enabled){
|
|
vec4 color = ApplyColorEffects(COLOR, depth);
|
|
color = ApplyLighting(color, normal);
|
|
float fogv = (g_Fog_end + ipoint.z) * g_Fog_scale;
|
|
gl_FragColor = ApplyFog(color, fogv);
|
|
} else {
|
|
gl_FragColor = COLOR;
|
|
}
|
|
PostLightingEffects(depth);
|
|
} else {
|
|
if (COLOR.a == 0.0) {
|
|
// cPickableThrough
|
|
discard;
|
|
}
|
|
gl_FragColor = COLOR;
|
|
}
|
|
|
|
}
|