Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
108 lines
3.1 KiB
GLSL
108 lines
3.1 KiB
GLSL
|
|
uniform mat4 ViewMatrix;
|
|
uniform mat4 ProjectionMatrix;
|
|
uniform vec2 viewportSize;
|
|
uniform float lineThickness = 2.0;
|
|
|
|
/* ---- Instantiated Attrs ---- */
|
|
in vec2 pos0;
|
|
in vec2 pos1;
|
|
|
|
/* ---- Per instance Attrs ---- */
|
|
in mat4 InstanceModelMatrix;
|
|
in vec4 outlineColorSize;
|
|
|
|
flat out vec4 finalColor;
|
|
|
|
/* project to screen space */
|
|
vec2 proj(vec4 pos)
|
|
{
|
|
return (0.5 * (pos.xy / pos.w) + 0.5) * viewportSize;
|
|
}
|
|
|
|
vec2 compute_dir(vec2 v0, vec2 v1, vec2 c)
|
|
{
|
|
vec2 dir = normalize(v1 - v0);
|
|
dir = vec2(dir.y, -dir.x);
|
|
/* The model matrix can be scaled negativly.
|
|
* Use projected sphere center to determine
|
|
* the outline direction. */
|
|
vec2 cv = c - v0;
|
|
dir = (dot(dir, cv) > 0.0) ? -dir : dir;
|
|
return dir;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
mat4 model_view_matrix = ViewMatrix * InstanceModelMatrix;
|
|
mat4 sphereMatrix = inverse(model_view_matrix);
|
|
|
|
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
|
|
|
|
/* This is the local space camera ray (not normalize).
|
|
* In perspective mode it's also the viewspace position
|
|
* of the sphere center. */
|
|
vec3 cam_ray = (is_persp) ? model_view_matrix[3].xyz : vec3(0.0, 0.0, -1.0);
|
|
cam_ray = mat3(sphereMatrix) * cam_ray;
|
|
|
|
/* Sphere center distance from the camera (persp) in local space. */
|
|
float cam_dist = length(cam_ray);
|
|
|
|
/* Compute view aligned orthonormal space. */
|
|
vec3 z_axis = cam_ray / cam_dist;
|
|
vec3 x_axis = normalize(cross(sphereMatrix[1].xyz, z_axis));
|
|
vec3 y_axis = cross(z_axis, x_axis);
|
|
float z_ofs = 0.0;
|
|
|
|
if (is_persp) {
|
|
/* For perspective, the projected sphere radius
|
|
* can be bigger than the center disc. Compute the
|
|
* max angular size and compensate by sliding the disc
|
|
* towards the camera and scale it accordingly. */
|
|
const float half_pi = 3.1415926 * 0.5;
|
|
const float rad = 0.05;
|
|
/* Let be (in local space):
|
|
* V the view vector origin.
|
|
* O the sphere origin.
|
|
* T the point on the target circle.
|
|
* We compute the angle between (OV) and (OT). */
|
|
float a = half_pi - asin(rad / cam_dist);
|
|
float cos_b = cos(a);
|
|
float sin_b = sqrt(clamp(1.0 - cos_b * cos_b, 0.0, 1.0));
|
|
|
|
x_axis *= sin_b;
|
|
y_axis *= sin_b;
|
|
z_ofs = -rad * cos_b;
|
|
}
|
|
|
|
/* Camera oriented position (but still in local space) */
|
|
vec3 cam_pos0 = x_axis * pos0.x + y_axis * pos0.y + z_axis * z_ofs;
|
|
vec3 cam_pos1 = x_axis * pos1.x + y_axis * pos1.y + z_axis * z_ofs;
|
|
|
|
vec4 V = model_view_matrix * vec4(cam_pos0, 1.0);
|
|
vec4 p0 = ProjectionMatrix * V;
|
|
vec4 p1 = ProjectionMatrix * (model_view_matrix * vec4(cam_pos1, 1.0));
|
|
vec4 c = ProjectionMatrix * vec4(model_view_matrix[3].xyz, 1.0);
|
|
|
|
vec2 ssc = proj(c);
|
|
vec2 ss0 = proj(p0);
|
|
vec2 ss1 = proj(p1);
|
|
vec2 edge_dir = compute_dir(ss0, ss1, ssc);
|
|
|
|
bool outer = ((gl_VertexID & 1) == 1);
|
|
|
|
vec2 t = outlineColorSize.w * (lineThickness / viewportSize);
|
|
t *= (is_persp) ? abs(V.z) : 1.0;
|
|
t = (outer) ? t : vec2(0.0);
|
|
|
|
gl_Position = p0;
|
|
gl_Position.xy += t * edge_dir;
|
|
|
|
finalColor = vec4(outlineColorSize.rgb, 1.0);
|
|
|
|
#ifdef USE_WORLD_CLIP_PLANES
|
|
vec4 worldPosition = InstanceModelMatrix * vec4(cam_pos0, 1.0);
|
|
world_clip_planes_calc_clip_distance(worldPosition.xyz);
|
|
#endif
|
|
}
|