#include "math.h"
float
DE(vector pos; float power; int iters; float bail; float phi_off; float theta_off)
{
float dr = 1.0;
float theta, phi, r_pow;
float sin_theta, cos_theta, sin_phi, cos_phi;
for (int i = 0; i < iters; ++i)
{
if (r > bail)
break;
theta =
acos(z.y/r) + theta_off;
phi =
atan2(z.z, z.x) + phi_off;
r_pow =
pow(r, power-1.0);
dr = r_pow*power*dr + 1.0;
theta *= power;
phi *= power;
z = r_pow * set(sin_theta*cos_phi,
cos_theta,
sin_theta*sin_phi);
z += pos;
}
}
vector
estimateNormal(vector pos; float power; int iters; float bail; float phi; float theta)
{
float n = DE(pos, power, iters, bail, phi, theta);
float dx = DE(pos + set(eps, 0, 0), power, iters, bail, phi, theta);
float dy = DE(pos + set(0, eps, 0), power, iters, bail, phi, theta);
float dz = DE(pos + set(0, 0, eps), power, iters, bail, phi, theta);
vector grad = set(dx, dy, dz) -
n;
}
int
intersectSphere(vector ray_org; vector ray_dir;
float radius; export
float dist)
{
int hit = 0;
float b = 2*
dot(ray_org, ray_dir);
float c = length2(ray_org) - radius*radius;
if (d > 0)
{
float dist0 = 0.5f * (-b - d);
float dist1 = 0.5f * (-b + d);
if (dist0 > 0 && dist0 < dist1)
{
hit = 1;
}
else if (dist1 > 0)
{
hit = 1;
}
}
return hit;
}
cvex
main(
vector ray_org = 0;
vector ray_dir = 0;
int iters = 6;
int max_steps = 100;
float power = 8;
float bailout = 15;
float phi = 0.0f;
float theta = 0.0f;
export vector Ng = 0;
export vector uvw = 0;
export int prim_id = 0;
export int hit = 0;
export vector displayColor = { 0, 0, 0 };
)
{
vector pos = ray_org/
size;
hit = intersectSphere(pos, ray_dir, 2.0f, t);
pos += t * ray_dir;
float steps = 0;
float xsign = -
sign(pos.x);
float ysign = -
sign(pos.y);
float zsign = -
sign(pos.z);
distance = 0;
if (hit)
{
hit = 1;
for (steps = 0; steps < max_steps; ++steps)
{
t = DE(pos, power, iters, bailout, phi, theta);
pos += t * ray_dir;
if (t < eps)
{
break;
}
if (xsign*pos.x < -2 ||
ysign*pos.y < -2 ||
zsign*pos.z < -2)
{
hit = 0;
break;
}
}
}
if (hit)
{
Ng = estimateNormal(pos, power, iters, bailout, phi, theta);
uvw.x =
fit(steps, 0, max_steps, 0, 1);
displayColor = set(uvw.x);
}
}