Tomando de IQ (Iñigo Quilez) un raytracer muy simple… 4K
la interseccion de un esfera.
bool intSphere( in vec4 sp, in vec3 ro, in vec3 rd, in float tm, out float t )
{
bool r = false;
vec3 d = ro - sp.xyz;
float b = dot(rd,d);
float c = dot(d,d) - sp.w*sp.w;
t = b*b-c;
if( t > 0.0 )
{
t = -b-sqrt(t);
r = (t > 0.0) && (t < tm);
}
return r;
}
A ver…defino palabra, comento los parametros, borro los tipos de datos
:intSphere |( in vec4 sp, in vec3 ro, in vec3 rd, in float tm, out float t )
bool r = false;
vec3 d = ro - sp.xyz;
float b = dot(rd,d);
float c = dot(d,d) - sp.w*sp.w;
t = b*b-c;
if( t > 0.0 )
{
t = -b-sqrt(t);
r = (t > 0.0) && (t < tm);
}
return r
;
Elegir una buena forma para los parametros, quitar el booleano, para una decision no hay nada mejor que un numero, los booleanos dicen poco, solo si o no.
rehacer los IF. cambiar el orden, ordenar las condiciones de corte por cantidad de calculos, las menores primero.
|( in vec4 sp, in vec3 ro, in vec3 rd, in float tm, out float t )
:intSphere | sp ro rd tm -- sp ro rd tm t
vec3 d = ro - sp.xyz;
float b = dot(rd,d);
float c = dot(d,d) - sp.w*sp.w;
t = b*b-c;
-? ( drop 0 ; ) | revisar..
-b-sqrt(t)
over >=? ( drop 0 ; )
;
Factorizo los parameros, que lo calcule otro… convertir a postfijo, quitar cosas.
| solo logica y calculo
:intSphere | tm b c -- tm b c t d
over dup * over - | tm b c t =b*b-c;
| -? ( drop 0 ; ) que lo corte otro (homero rule)
pick2 neg over distfast - | tm b c t d=-b-sqrt(t)
|over >=? ( drop 0 ; ) | mm Hr tambien
;
puff, ahora hay que agregarle todo lo que le saque, conviene elegir un nombre feo, para cambiarlo despues, cuando entendamos que estamos haciendo
:calculabc | sp ro rd tm -- sp ro rd tm b c
vec3 d = ro - sp.xyz
float b = dot(rd,d)
float c = dot(d,d) - sp.w*sp.w
;
mmmmmm lo dejo para otro post…