85 lines
2.5 KiB
Text
85 lines
2.5 KiB
Text
|
#version 150 compatibility
|
||
|
|
||
|
out EllipsoidData {
|
||
|
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 mat3 T, in mat3 inv_T, in vec2 t, in vec3 m_tilde, in vec3 x_tilde, in vec3 y_tilde, in vec3 e_tilde)
|
||
|
{
|
||
|
// set q coordinates of corner
|
||
|
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(T*V_tilde + center, 1.0);
|
||
|
|
||
|
// compute vector from eye to vertex in eye space
|
||
|
Vout.v_eye = (gl_ModelViewMatrix*V).xyz;
|
||
|
|
||
|
// compute components to compute normal in eye space
|
||
|
Vout.nml_v_eye = gl_NormalMatrix*(inv_T*(V_tilde - e_tilde));
|
||
|
|
||
|
gl_Position = gl_ModelViewProjectionMatrix * V;
|
||
|
Vout.zw_v_clip = gl_Position.zw - Vout.zw_e_clip;
|
||
|
|
||
|
EmitVertex();
|
||
|
}
|
||
|
|
||
|
void cover_ellipsoid_with_quad(in vec3 center, in vec3 enc_T0, in vec3 enc_T1)
|
||
|
{
|
||
|
// decompress the matrix T
|
||
|
mat3 T;
|
||
|
T[0] = enc_T0;
|
||
|
T[1].x = enc_T0.y;
|
||
|
T[1].yz = enc_T1.xy;
|
||
|
T[2].x = enc_T0.z;
|
||
|
T[2].yz = enc_T1.yz;
|
||
|
|
||
|
// invert the matrix T
|
||
|
mat3 inv_T;
|
||
|
float inv_denom = 1.0 / dot(T[0], cross(T[1], T[2]));
|
||
|
inv_T[0] = inv_denom*cross(T[1], T[2]);
|
||
|
inv_T[1] = inv_denom*cross(T[2], T[0]);
|
||
|
inv_T[2] = inv_denom*cross(T[0], T[1]);
|
||
|
|
||
|
// determine eye point in parameter space
|
||
|
vec3 e = gl_ModelViewMatrixInverse[3].xyz;
|
||
|
vec3 e_tilde = inv_T*(e - center);
|
||
|
|
||
|
// compute helper
|
||
|
float inv_e_square = 1.0 / dot(e_tilde, e_tilde);
|
||
|
|
||
|
// 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 = vec3(0, 0, 0);
|
||
|
if (abs(e_tilde[1]) > abs(e_tilde[0]))
|
||
|
x_tilde[0] = 1.0;
|
||
|
else
|
||
|
x_tilde[1] = 1.0;
|
||
|
x_tilde = r*normalize(cross(x_tilde, 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));
|
||
|
|
||
|
Vout.inv_e = sqrt(inv_e_square);
|
||
|
Vout.zw_e_clip = (gl_ModelViewProjectionMatrix * gl_ModelViewMatrixInverse[3]).zw;
|
||
|
Vout.nml_e_eye = gl_NormalMatrix*(inv_T*e_tilde);
|
||
|
|
||
|
generate_vertex(center, T, inv_T, vec2(-1.0, -1.0), m_tilde, x_tilde, y_tilde, e_tilde);
|
||
|
generate_vertex(center, T, inv_T, vec2( 1.0, -1.0), m_tilde, x_tilde, y_tilde, e_tilde);
|
||
|
generate_vertex(center, T, inv_T, vec2(-1.0, 1.0), m_tilde, x_tilde, y_tilde, e_tilde);
|
||
|
generate_vertex(center, T, inv_T, vec2( 1.0, 1.0), m_tilde, x_tilde, y_tilde, e_tilde);
|
||
|
}
|