レイトレーサー基本のキ

2009-07-16

レイトレーサーを作るシリーズ:

グローバルイルミネーションどころか、レイトレーサーもよくわかってないので、lucille development blog » Blog Archive » Rendering with Proce55ing. のプログラムを参考にProce55ingで作ってみたい。

まずは基本。球と線分の交差判定を調べて色を塗る:

int renderY = 0;
color LineBuf[];

void setup() {
size(256, 256);
LineBuf = new color[width];
}

void draw() {
render_line(LineBuf, width, height, renderY);
copy_line(LineBuf, renderY);
if (++renderY >= height) {
noLoop();
}
}

void copy_line(color[] img, int y) {
loadPixels();
for (int i = 0; i < width; ++i) {
pixels[y * width + i] = img[i];
}
updatePixels();
}

// 線分と球の交差判定
float intersect_line_sphere(vec orig, vec dir, vec sphere_center, float sphere_radius) {
vec c = sphere_center;
vec s = orig;
vec d = dir;
float r = sphere_radius;
vec v = s.sub(c);

float dd = sq(v.dot(d)) - (v.dot(v) - sq(r));
if (dd < 0) {
return -1; // not intersect
} else {
float sqdd = sqrt(dd);
float t1 = -v.dot(d) - sqdd;
return t1; // maybe intersect
}
}

vec eyepos = new vec(0, 0, -1);
vec sphere_center = new vec(0, 0, 0);
float sphere_radius = 0.5;

void render_line(color[] img, int width, int height, int iy) {
float w2 = width / 2;
float h2 = height / 2;
float xofs = w2 - 0.5;
float yofs = h2 - 0.5;
float py = -((iy - yofs) / h2); // flip Y

for (int j=0; j<width; ++j) {
float px = (j - xofs) / w2;
vec raydir = (new vec(px, py, 1)).normal();

float t = intersect_line_sphere(eyepos, raydir, sphere_center, sphere_radius);
if (t >= 0) {
img[j] = color(255, 0, 0);
} else {
img[j] = color(0, 0, 0);
}
}
}