Need help with GLSL and Raytrace
I am new to raytrace.and i found some example from shadertoy.
link below
https://www.shadertoy.com/view/ld2Gz3
with a little work,i can run this shader in opengl now.
my question is there is some equation i do not understand.
it is about ray intersect with sphere.
here is the code.
void intersectSphere(const Sphere sphere, const Ray ray, Material material, inout Output o) {
vec3 d = ray.origin - sphere.origin;
float a = dot(ray.direction, ray.direction);
float b = dot(ray.direction, d);
float c = dot(d, d) - sphere.radius * sphere.radius;
float g = b*b - a*c;
if(g > 0.0) {
float dis = (-sqrt(g) - b) / a;
if(dis > 0.0 && dis < o.dis) {
o.dis = dis;
o.origin = ray.origin + ray.direction * dis;
o.normal = (o.origin - sphere.origin) / sphere.radius;
o.material = material;
}
}
}
as i know g should equal to b*b - 4*a*c;
but this code is
g = b*b - a*c;
and dis should equal to (-sqrt(g) - b) / (2*a);
but instead it is
dis = (-sqrt(g) - b) / a;
and this code really works.
why?what's going on here?
I only get the code to float dis = (-sqrt(g) - b) / a; line, though I'd say you'd better off writing your own function and finding intersection yourself, since the programmer of the code had a clear plan of his method in mind and has optimized the code a lot.
Any ways the part of the code I understand goes like this:
[attachment=29284:Untitled.png]
ok lets say the angle between red and yellow line is theta, and the angle between green and yellow line is alpha, and the circle is our sphere.
"vec3 d = ray.origin - sphere.origin;" this line defines the d vector in the picture
" float a = dot(ray.direction, ray.direction);" this is the squared size of the red line
"float b = dot(ray.direction, d);" now b is sqrt(a)*sqrt(d)*cos(theta)
"float c = dot(d, d) - sphere.radius * sphere.radius;" this the squared size of the green line which can be represented as: sqrt(c)=sqrt(d)*cos(alpha)
"float g = b*b - a*c;" here we have: g=a*d*cos(theta)^2-a*d*cos(alpha)^2
"if (g>0.0)" this means:
a*d*cos(theta)^2-a*d*cos(alpha)^2>0 => cos(theta)^2-cos(alpha)^2>0 => cos(theta)>cos(alpha) => theta<alpha
which means the ray intersects with the sphere
"float dis = (-sqrt(g) - b) / a;" now this is what I don't get
if comes a day I understand this part I'll post it here or if you already know, if you don't mind please share with us
I will do shameless self-promotion.
If I recall correctly, they are using ray-sphere algorithm derived not from analitic view, but from geometry view (as it ends up with the code with less instructions in total that is more precise, than naive implementation of analytic-view dervation, note that they are equal).
Now for the self-promotion, check out the article http://www.gamedev.net/page/resources/_/technical/math-and-physics/intersection-math-algorithms-learn-to-derive-r3033
I did the derivation of geometry-view based one in there.