lygia
/sdf
/coneSDF
)generate the SDF of a cone
Use:
<float> coneSDF( in <vec3> pos, in <vec3> c )
#ifndef FNC_CONESDF
#define FNC_CONESDF
float coneSDF( in vec3 p, in vec3 c ) {
vec2 q = vec2( length(p.xz), p.y );
float d1 = -q.y-c.z;
float d2 = max( dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
// vertical
float coneSDF( in vec3 p, in vec2 c, float h ) {
vec2 q = h*vec2(c.x,-c.y)/c.y;
vec2 w = vec2( length(p.xz), p.y );
vec2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );
vec2 b = w - q*vec2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );
float k = sign( q.y );
float d = min(dot( a, a ),dot(b, b));
float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );
return sqrt(d)*sign(s);
}
// Round
float coneSDF( in vec3 p, in float r1, float r2, float h ) {
vec2 q = vec2( length(p.xz), p.y );
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(q,vec2(-b,a));
if( k < 0.0 ) return length(q) - r1;
if( k > a*h ) return length(q-vec2(0.0,h)) - r2;
return dot(q, vec2(a,b) ) - r1;
}
#endif
Use:
<float> coneSDF( in <float3> pos, in <float3> c )
#ifndef FNC_CONESDF
#define FNC_CONESDF
float coneSDF( in float3 p, in float3 c ) {
float2 q = float2( length(p.xz), p.y );
float d1 = -q.y-c.z;
float d2 = max( dot(q,c.xy), q.y);
return length(max(float2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
// vertical
float coneSDF( in float3 p, in float2 c, float h ) {
float2 q = h*float2(c.x,-c.y)/c.y;
float2 w = float2( length(p.xz), p.y );
float2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );
float2 b = w - q*float2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );
float k = sign( q.y );
float d = min(dot( a, a ),dot(b, b));
float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );
return sqrt(d)*sign(s);
}
// Round
float coneSDF( in float3 p, in float r1, float r2, float h ) {
float2 q = float2( length(p.xz), p.y );
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(q,float2(-b,a));
if( k < 0.0 ) return length(q) - r1;
if( k > a*h ) return length(q-float2(0.0,h)) - r2;
return dot(q, float2(a,b) ) - r1;
}
#endif
Use:
<float> coneSDF( <float3> pos, <float3> c )
#ifndef FNC_CONESDF
#define FNC_CONESDF
float coneSDF( float3 p, float3 c ) {
float2 q = float2( length(p.xz), p.y );
float d1 = -q.y-c.z;
float d2 = max( dot(q,c.xy), q.y);
return length(max(float2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
// vertical
float coneSDF( float3 p, float2 c, float h ) {
float2 q = h*float2(c.x,-c.y)/c.y;
float2 w = float2( length(p.xz), p.y );
float2 a = w - q*clamp( dot(w,q)/dot(q,q), 0.0, 1.0 );
float2 b = w - q*float2( clamp( w.x/q.x, 0.0, 1.0 ), 1.0 );
float k = sign( q.y );
float d = min(dot( a, a ),dot(b, b));
float s = max( k*(w.x*q.y-w.y*q.x),k*(w.y-q.y) );
return sqrt(d)*sign(s);
}
// Round
float coneSDF( float3 p, float r1, float r2, float h ) {
float2 q = float2( length(p.xz), p.y );
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(q,float2(-b,a));
if( k < 0.0 ) return length(q) - r1;
if( k > a*h ) return length(q-float2(0.0,h)) - r2;
return dot(q, float2(a,b) ) - r1;
}
#endif
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository