CGII/framework/shader/cgv_gl/glsl/sphere_base.glgs
2018-05-17 16:01:02 +02:00

53 lines
2.1 KiB
Text

#version 150 compatibility
out SphereData {
vec2 q_tilde;
float inv_e;
vec3 nml_e_eye;
vec3 nml_v_eye;
vec2 zw_e_clip;
vec2 zw_v_clip;
vec3 v_eye;
} Vout;
void generate_vertex(in vec3 center, in float radius, in vec2 t, in vec3 m_tilde, in vec3 x_tilde, in vec3 y_tilde, in vec3 e_tilde)
{
Vout.q_tilde = t;
// compute the corner point in homogeneous object coordinates
vec3 V_tilde = m_tilde + t.x*x_tilde + t.y*y_tilde;
vec4 V = vec4(radius*V_tilde + center, 1.0);
// compute vector from eye to vertex in eye space
Vout.v_eye = (gl_ModelViewMatrix*V).xyz;
gl_Position = gl_ModelViewProjectionMatrix * V;
// compute components to compute normal in eye space
Vout.nml_v_eye = gl_NormalMatrix*(V_tilde - e_tilde);
Vout.zw_v_clip = gl_Position.zw - Vout.zw_e_clip;
EmitVertex();
}
void cover_sphere_with_quad(in vec3 center, in float radius)
{
float inv_R = 1.0 / radius;
// determine eye point in parameter space
vec3 e_tilde = inv_R*(gl_ModelViewMatrixInverse[3].xyz - center);
// compute helper
float inv_e_square = 1.0 / dot(e_tilde, e_tilde);
Vout.inv_e = sqrt(inv_e_square);
// determine silhoutte center in parameter space
vec3 m_tilde = inv_e_square*e_tilde;
// determine radius of silhouette in parameter space
float r = sqrt(1.0 - inv_e_square);
// compute vector x of length r orthogonal to e in parameter space
vec3 x_tilde = r*normalize(cross(gl_ModelViewMatrixInverse[1].xyz, e_tilde));
// compute vector y of length r orthogonal to x and e in parameter space
vec3 y_tilde = r*normalize(cross(e_tilde, x_tilde));
// compute components to compute normal in eye space
Vout.nml_e_eye = gl_NormalMatrix*(e_tilde);
// constant part of depth value
Vout.zw_e_clip = (gl_ModelViewProjectionMatrix * gl_ModelViewMatrixInverse[3]).zw;
generate_vertex(center, radius, vec2(-1.0, -1.0), m_tilde, x_tilde, y_tilde, e_tilde);
generate_vertex(center, radius, vec2( 1.0, -1.0), m_tilde, x_tilde, y_tilde, e_tilde);
generate_vertex(center, radius, vec2(-1.0, 1.0), m_tilde, x_tilde, y_tilde, e_tilde);
generate_vertex(center, radius, vec2( 1.0, 1.0), m_tilde, x_tilde, y_tilde, e_tilde);
EndPrimitive();
}