Skip to content

Instantly share code, notes, and snippets.

@williammalo
Last active December 5, 2016 17:46
Show Gist options
  • Save williammalo/d2ad1bbbf4fbb7d27f33e8546101a6bf to your computer and use it in GitHub Desktop.
Save williammalo/d2ad1bbbf4fbb7d27f33e8546101a6bf to your computer and use it in GitHub Desktop.
Find Tangents of Two Circles in glsl, useful for calculating soft shadows https://www.shadertoy.com/view/Mtc3R2
//visual basics code from http://www.vb-helper.com/howto_net_circle_circle_tangents.html ported to glsl
vec4 FindCircleCircleIntersections(vec2 p0, float r0, vec2 p1, float r1){
vec2 dd = p1-p0;
float d = length(dd);
float a = (r0 * r0 - r1 * r1 + d * d) / (2.0 * d);
float h = sqrt(r0 * r0 - a * a);
vec2 p = p0 + a * (p1-p0) / d;
return vec4( h , -h, -h, h )*dd.yxyx/d+p.xyxy;
}
vec4 FindTangents(vec2 c, float r,vec2 p){
vec2 d = c - p;
float L = sqrt( dot(d,d) - r * r);
return FindCircleCircleIntersections( c, r, p, L);
}
mat4 _internal_FindCircleCircleTangents(vec2 c1, float r1, vec2 c2, float r2){
vec4 t0 = FindTangents(c2, r2 - r1, c1);
vec4 t2 = FindTangents(c1, r1 + r2, c2);
vec4 v0 = (t0.yxwz - c1.yxyx) * vec4(-1,1,1,-1);
vec4 v1 = (t2.yxwz - c2.yxyx) * vec4(1,-1,-1,1);
v0.xy *= r1 / length(v0.xy);
v0.zw *= r1 / length(v0.zw);
v1.xy *= r2 / length(v1.xy);
v1.zw *= r2 / length(v1.zw);
return mat4(
t0 + v0,
c1.xyxy + v0,
t2 + v1,
c2.xyxy + v1
);
}
mat4 FindCircleCircleTangents(vec3 c1, vec3 c2){
if(c1.z < c2.z){
return _internal_FindCircleCircleTangents(c1.xy,c1.z,c2.xy,c2.z);
}else{
mat4 ret = _internal_FindCircleCircleTangents(c2.xy,c2.z,c1.xy,c1.z);
return mat4( ret[1], ret[0], ret[3], ret[2] );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment