Intro



If you are an engineer, you might have heard this before:


"Well, first let us consider a spherical cow..."



This is a humorous observation of the way engineers often operate. But the truth is that replacing precise problems that have only approximated, expensive or even unknown solution by approximated problems that do have an exact, cheap or known solution is sometimes a good strategy. And so, in the context of graphics, sometimes you can replace a cow, indeed, by a sphere (for example, if it's not too close to the camera, or if you are in an occlusion pass).

In fact, spheres are useful in too many ways to be ignored. I have written a few articles already on the subject of analytically computing different properties of spheres that are useful for rendering, which are scattered all over this website. Some others I have not documented yet, but this page can be seen as an index to those articles and techniques, and a summary of the resulting formulas. You can find them all also in this Shadertoy playlist:https://www.shadertoy.com/playlist/sfcGWH.

I have used these techniques both in demos and also in production of featured films. For example, I have used a bunch of spheres to shape its occlusion and directional shadows analytically rather than resorting to shadow maps. Also, if you are rendering massive terrains made of hundreds of millions of rocks, bushes and trees, you might want to organize things in bounding spheres and check analytically (without rasterization whatsoever), how many pixels does each bounding sphere take in screen space in to do level of detail decisions. I have used spherical density to do localized color grading, and for fog volumes.

Whether you are using spheres to approximate cows, or you are making a demo or game with spheres for artistic reasons, probably some of the formulas bellow will be of use to you.



Functions


In the code below,pimeans 3.1415927... andepsis a small positive number close to zero.


Sphere Intersection
http://iquilezles.org/blog/?p=2411

floatsphIntersect(vec3ro,vec3rd,vec4sph ) {vec3oc = ro - sph.xyz;floatb =dot( oc, rd );floatc =dot( oc, oc ) - sph.w*sph.w;floath = b*b - c;if( h<0.0)return-1.0; h =sqrt( h );return-b - h; }vec3sphNormal(vec3pos,vec4sph ) {return(pos - sph.xyz)/sph.w; }
Sphere Density
Maths / Article
Example / Code

floatsphDensity(vec3ro,vec3rd,vec4sph,floatdbuffer ) {floatndbuffer = dbuffer/sph.w;vec3rc = (ro - sph.xyz)/sph.w;floatb =dot(rd,rc);floatc =dot(rc,rc) -1.0;floath = b*b - c;if( h<0.0)return0.0; h =sqrt( h );floatt1 = -b - h;floatt2 = -b + h;if( t2<0.0|| t1>ndbuffer )return0.0; t1 =max( t1,0.0); t2 =min( t2, ndbuffer );floati1 = -(c*t1 + b*t1*t1 + t1*t1*t1/3.0);floati2 = -(c*t2 + b*t2*t2 + t2*t2*t2/3.0);return(i2-i1)*(3.0/4.0); }
Sphere Projection
Maths / Article
Example / Code

floatprojectSphere(vec4sph,mat4x4cam,floatfle ) {vec3o = (cam*vec4(sph.xyz,1.0)).xyz;floatr2 = sph.w*sph.w;floatz2 = o.z*o.z;floatl2 =dot(o,o);floatk1 = l2-r2;floatk2 = r2-z2;return-pi*fle*fle*r2*sqrt(abs(k1/k2))/k2; }
Sphere Visibility
Maths / Article
Example / Code

intsphereVisibility(vec4sA,vec4sB,vec3c ) {vec3ac = sA.xyz - c;vec3bc = sB.xyz - c;floatia =1.0/length(ac);floatib =1.0/length(bc);floatk0 =dot(ac,bc)*ia*ib;floatk1 = sA.w*ia;floatk2 = sB.w*ib;floatm1 = k0*k0 + k1*k1 + k2*k2;floatm2 =2.0*k0*k1*k2;if( m1 + m2 -1.0<0.0)return1;elseif( m1 - m2 -1.0<0.0)return2;return3; }
Sphere Ambient Occlusion
Maths / Article
Example / Code

floatsphOcclusion(vec3pos,vec3nor,vec4sph ) {vec3di = sph.xyz - pos;floatl =length(di);floatnl =dot(nor,di/l);floath = l/sph.w;floath2 = h*h;floatk2 =1.0- h2*nl*nl;floatres =max(0.0,nl)/h2;if( k2 >0.0)// approx. for penetration{ res =clamp(0.5*(nl*h+1.0)/h2,0.0,1.0); res =sqrt( res*res*res ); }returnres; }
Sphere Soft Shadow
Maths / Article
Example / Code

floatsphSoftShadow(vec3ro,vec3rd,vec4sph,floatk ) {vec3oc = ro - sph.xyz;floatb =dot( oc, rd );floatc =dot( oc, oc ) - sph.w*sph.w;floath = b*b - c;return(b>0.0)?step(-eps,c):smoothstep(0.0,1.0,h*k/b); }floatsphSoftShadow(vec3ro,vec3rd,vec4sph,floatk ) {vec3oc = ro - sph.xyz;floatr = sph.w*sph.w;floatb =dot( oc, rd );floatc =dot( oc, oc ) - r;floath = b*b - c;floatd = -sph.w +sqrt(max(0.0,r-h));floatt = -b -sqrt(max(0.0,h) );return(t<0.0)?1.0:smoothstep(0.0,1.0,k*d/t); }
Sphere Distance
Example / Code

vec2sphDistances(vec3ro,vec3rd,vec4sph ) {vec3oc = ro - sph.xyz;floatb =dot( oc, rd );floatc =dot( oc, oc ) - sph.w*sph.w;floath = b*b - c;floatd =sqrt(max(0.0,sph.w*sph.w-h)) - sph.w;returnvec2( d, -b-sqrt(max(h,0.0)) ); }
Sphere Motion
Example / Code

vec2sphMotion(vec3ro,vec3rd,vec4sph,vec3ve,out vec3nor ) {floatt = -1.0;floats =0.0; nor =vec3(0.0);vec3rc = ro - sph.xyz;floatA =dot(rc,rd);floatB =dot(rc,rc) - sph.w*sph.w;floatC =dot(ve,ve);floatD =dot(rc,ve);floatE =dot(rd,ve);floataab = A*A - B;floateec = E*E - C;floataed = A*E - D;floatk = aed*aed - eec*aab;if( k>0.0) { k =sqrt(k);floathb = (aed - k)/eec;floatha = (aed + k)/eec;floatta =max(0.0, ha );floattb =min(1.0, hb );if( ta < tb ) { ta =0.5*(ta+tb);floatk1 = A - E*ta;floatk2 = B + C*ta*ta -2.0*D*ta; t = -k1 -sqrt( k1*k1 - k2 ); s =2.0*(tb - ta);vec3pa = ro + rd*t;vec3pb = sph.xyz + ta*ve; nor =normalize( pa - pb ); } }returnvec2(t,s); }
Inigo Quilez :: computer graphics, maths, shaders, fractals, demoscene
1402blog posts, written between 2008 and 2016. These are mostly short observations, funny thoughts and word playing. Some are embarrasingly corny, some more deep. I keep it here mostly a little time capsule for myself, organized by month:



<
April 2016
 
food
2016-04-30
As with many other social problems, I've found that people stop caring about the chemicals and pesticides in our food as soon as _they_ have reached a point in life when they can afford high quality, expensive food for themselves.
speaking of education
2016-04-28
It seems to me that it is a bad idea to give ourselves democracy and not follow it up by giving outselves good, free, public education too. The former cannot function without the later!
formula
2016-04-26
"Formula 1", triple English homonym, because why use different words if you can make things extra confusing.

sexsexful
2016-04-24
i'd rather be sexsexful than successful
bias
2016-04-22
Clearly there's a lot of bias around social expectations of child caring and family roles:

- When I emailed the nurse, she responded asking for "my husband's" medical insurance number, first assuming that wife's don't have one, and second, that since I am the one emailing aboud child matters, I must be the mom. I corrected the nurse.

- When looking at this infant's second hand books I've been given, the family portrayed in it has a father that, and I quote, "helps" in the house. That is, apparently it isn't his duty to run the house, that's his wife's it seems. But he's a great dude becaise he "helps", when he feels like I imagine. I burned the book.

- When browsing for infant's clothing, I find quite a few options with messages such as "Mommy's Love". Dad is not in the picture it seems. I close the website.
14 emails
2016-04-20
Today I woke up to see 14 new emails in my inbox, from myself. Must . Stop . Having . Ideas . At . Night
that's what i do
2016-04-18
i'm one of those few men who close the toilet lid every time after i pee. i know i'm in the minority, and i really don't know why this is so difficult or why it is a thing to begin with
we still don't know how to write code
2016-04-16
Since it seems I'm in lecture mode lately, here goes a not so serious (or maybe yes?) message to Google and their AI / Deep Learning team:

You are showing machines to paint, compose music, talk or synthesize piano from current paintings, music and recordings. Fine I guess (have you asked for permision to the artists you are learning from, though?).

However, tempting as it is, I hope you do not, I repeat, you do NOT, feed the the machines with contemporary source code. Because, you surely must know much of the code out there is really bad. And even the good code is not as good - computer science is a very recent thing and we haven't figured out coding yet. You know this, right? RIGHT?
maturity is optional
2016-04-14
unlike adulthood which is unavoidable, maturity is optional
just drop it
2016-04-12
1.95 pounds is not 1 pound and 9 and a half ounces. It is 1 pound 15.2 ounces. I had to explain this to an adult today.

If you cannot handle your own twisted measurement system, just drop it. Do yourself a favor!
complains
2016-04-10
Without making this sound like an old I'm Self-Made story, I remember that when I moved to the Bay Area I couldn't afford living in San Francisco. So I rented a crappy apartment in a (moderately) dangerous area in the East Bay. I lived without a bed for 4 months, sleeping in the floor. I rode a bike (and still do!) to the grocery store and everywhere, and only moved to an old one bedroom in San Francisco when I saved some money. I was still 31.

Sure I had my free, high quality basque/spanish, education, and my skin color in my favor. But no money, so I couldn't afford dreaming of forming a family or owning a home until I was 40. And that is fine!

So, if you are in your late 20s or early 30s and are enraged because you can't afford owning property, all I can say is, "yep, that's how it is". And I'm not even playing the old entitled-millennials-rant record here, I'm just informing you that things take time. So be patient!
scientists
2016-04-08
scientists are detectives of nature
idiot
2016-04-06
The world is a worse place than it could be due to people like this person who patented the so called "Superformula", see here:https://en.wikipedia.org/wiki/Superformula.

What in idiot. Any technical artists working in games or films, or any professional in the field of computer graphics really, invents hundreds of fomulas like this during their career, to solve specific or general visual challenges. Most don't deserve being documented, and certainly almost none deserve a name, let alone a copyright.

Now, this particular individual was not harmful for I presume he's not particularly smart nor influential. But when people in positions of power share this mindset, they can do real harm.

perks
2016-04-04
i am guessing one nice side effect of having an infant, which can't talk, is that you can always blame her when you fart
#pleasedie
2016-04-02
people who use

#morningcoffee (heart shaped foam)
#dreambig (company door logo)
#soblessed (feet on the sand)
#neverstopexploring (machu picchu)
#justanotherdayatwork (celebrity visiting campus)
#viewfrommyoffice (palm-tree and laptop)
#beyourself (duckface)
< Previous