|
 |
"Bald Eagle" <cre### [at] netscape net> wrote:
> Post something. It doesn't matter what it is.
> Really. Just post it. Here.
>
I'm modifying a compiler I wrote that was for an assignment in my compilers
college course many years ago. I've expanded the grammar to be a fully usable
language rather than a "toy" language. So, of course, I just had to create a
raytracer for it. Here's the source code written in my language:
{
/* Integer loop + shading vars */
i_x = 0; i_y = 0;
i_shade = 0;
i_check = 0;
i_mod2 = 0;
/* Camera origin */
f_sx = 0.0; f_sy = 0.1; f_sz = 5.5;
/* Light direction (will normalize) */
#f_lx = -2.0; f_ly = 3.0; f_lz = -1.0;
f_lx = -2.0; f_ly = 3.0; f_lz = 2.0;
/* Ray direction */
f_dx = 0.0; f_dy = 0.0; f_dz = 0.0;
/* 2nd Sphere position */
f_sp_x = 1.75; f_sp_y = 0.0; f_sp_z = -2.0;
/* Sphere radiuses */
f_sp1_r = 1.2; f_sp2_r = 0.6;
/* Sphere intersection */
f_b = 0.0; f_c = 0.0; f_disc = 0.0; f_t = 0.0;
/* plane height */
f_ply = -1.6;
/* Normals and points */
f_nx = 0.0; f_ny = 0.0; f_nz = 0.0;
f_px = 0.0; f_py = 0.0; f_pz = 0.0;
/* Helpers */
f_len = 0.0; f_dot = 0.0; f_spec = 0.0; f_tmp = 0.0;
f_fx = 0.0; f_fz = 0.0;
/* Shadow ray vars */
f_sdx = 0.0; f_sdy = 0.0; f_sdz = 0.0;
f_tb = 0.0; f_tc = 0.0; f_tdisc = 0.0; f_tshadow = 0.0;
/* Normalize light direction once */
f_len = sqrt(f_lx*f_lx + f_ly*f_ly + f_lz*f_lz);
f_lx = f_lx / f_len; f_ly = f_ly / f_len; f_lz = f_lz / f_len;
f_aspect = 1.0;
print "P6\n640 480\n255\n";
/* Image loop */
for i_y = -240 to 239 do
{
for i_x = -320 to 319 do
{
/* Ray direction from camera through pixel */
f_dx = float(i_x) / 490.0;
f_dy = -float(i_y) * f_aspect / 490.0;
f_dz = -1.0;
/* Normalize ray direction */
f_len = sqrt(f_dx*f_dx + f_dy*f_dy + f_dz*f_dz);
f_dx = f_dx / f_len;
f_dy = f_dy / f_len;
f_dz = f_dz / f_len;
/* Sphere intersection: center at (0,0,0), radius 1.2 */
f_tx = f_sx;
f_ty = f_sy;
f_tz = f_sz;
f_b = 2.0 * (f_dx*f_tx + f_dy*f_ty + f_dz*f_tz);
f_c = f_tx*f_tx + f_ty*f_ty + f_tz*f_tz - f_sp1_r;
f_disc = f_b*f_b - 4.0*f_c;
if f_disc >= 0.0 then
{
/* Hit sphere: nearest t */
f_t = (-f_b - sqrt(f_disc)) / 2.0;
if f_t <= 0.0 then
{
/* Behind camera: treat as no sphere hit, fall through */
f_disc = -1.0;
}
else
{
f_obj_red = 0.9;
f_obj_green = 0.9;
f_obj_blue = 0.0;
}
}
/* Sphere intersection: center at (f_sp_x,f_sp_y,f_sp_z), radius .6 */
f_tx2 = f_sx - f_sp_x;
f_ty2 = f_sy - f_sp_y;
f_tz2 = f_sz - f_sp_z;
f_b = 2.0 * (f_dx*f_tx2 + f_dy*f_ty2 + f_dz*f_tz2);
f_c = f_tx2*f_tx2 + f_ty2*f_ty2 + f_tz2*f_tz2 - f_sp2_r;
f_disc2 = f_b*f_b - 4.0*f_c;
if f_disc2 >= 0.0 then
{
/* Hit sphere: nearest t */
f_t2 = (-f_b - sqrt(f_disc2)) / 2.0;
if f_t2 > 0.0 then
{
b_sp1=(f_disc<0.0); #(f_t<0.0); /* boolean */
b_sp2=(f_t2<f_t); /* boolean */
if b_sp1+b_sp2 then /* boolean + = or */
{
f_obj_red = 0.0;
f_obj_green = 0.9;
f_obj_blue = 0.0;
f_disc = f_disc2;
f_t = f_t2;
f_tx = f_tx2;
f_ty = f_ty2;
f_tz = f_tz2;
}
}
}
if f_disc < 0.0 then
{
/* No sphere hit: try ground plane y = -1.6 */
if f_dy == 0.0 then
{
/* Ray parallel to plane: background */
printc 0;
printc 90;
printc 130;
}
else
{
f_t = (f_ply - f_sy) / f_dy;
if f_t <= 0.0 then
{
/* Plane behind camera */
printc 0;
printc 90;
printc 130;
}
else
{
/* Hit point on plane */
f_px = f_sx + f_dx*f_t;
f_py = f_ply;
f_pz = f_sz + f_dz*f_t;
/* Checkerboard: floor(px), floor(pz) using int */
f_fx = float(int(f_px));
if f_px < 0.0 then f_fx = f_fx - 1.0;
f_fz = float(int(f_pz));
if f_pz < 0.0 then f_fz = f_fz - 1.0;
i_check = (int(f_fx + f_fz)) % 2;
if (i_check == 0) then { f_red=0.75; f_green=0.0; f_blue=0.0; }
else { f_red=0.75; f_green=0.75; f_blue=0.75; }
/* Shadow from sphere onto plane:
cast ray from plane point toward light,
check if it hits sphere before light. */
f_sdx = f_lx;
f_sdy = f_ly;
f_sdz = f_lz;
/* Sphere intersection from plane point:
ray: P + t*L, sphere at origin, radius 1 */
f_tb = 2.0 * (f_sdx*f_px + f_sdy*f_py + f_sdz*f_pz);
f_tc = f_px*f_px + f_py*f_py + f_pz*f_pz - f_sp1_r;
f_tdisc = f_tb*f_tb - 4.0*f_tc;
if f_tdisc > 0.0 then
{
f_tshadow = (-f_tb - sqrt(f_tdisc)) / 2.0;
if f_tshadow > 0.0 then
{
/* In shadow: darken */
f_red = f_red * 0.5;
f_green = f_green * 0.5;
f_blue = f_blue * 0.5;
}
}
f_tx = f_px - f_sp_x;
f_ty = f_py - f_sp_y;
f_tz = f_pz - f_sp_z;
f_tb = 2.0 * (f_sdx*f_tx + f_sdy*f_ty + f_sdz*f_tz);
f_tc = f_tx*f_tx + f_ty*f_ty + f_tz*f_tz - f_sp2_r;
f_tdisc = f_tb*f_tb - 4.0*f_tc;
if f_tdisc > 0.0 then
{
f_tshadow = (-f_tb - sqrt(f_tdisc)) / 2.0;
if f_tshadow > 0.0 then
{
/* In shadow: darken */
f_red = f_red * 0.5;
f_green = f_green * 0.5;
f_blue = f_blue * 0.5;
}
}
i_red=int(f_red * 255.0);
i_green=int(f_green * 255.0);
i_blue=int(f_blue * 255.0);
if i_red < 0 then i_red = 0;
if i_red > 255 then i_red = 255;
if i_green < 0 then i_green = 0;
if i_green > 255 then i_green = 255;
if i_blue < 0 then i_blue = 0;
if i_blue > 255 then i_blue = 255;
printc i_red;
printc i_green;
printc i_blue;
}
}
}
else
{
/* Sphere shading */
/* Hit point */
f_px = f_tx + f_dx*f_t;
f_py = f_ty + f_dy*f_t;
f_pz = f_tz + f_dz*f_t;
/* Normal at sphere */
f_nx = f_px;
f_ny = f_py;
f_nz = f_pz;
f_len = sqrt(f_nx*f_nx + f_ny*f_ny + f_nz*f_nz);
f_nx = f_nx / f_len;
f_ny = f_ny / f_len;
f_nz = f_nz / f_len;
/* Diffuse term */
f_dot = f_nx*f_lx + f_ny*f_ly + f_nz*f_lz;
if f_dot < 0.0 then f_dot = 0.0;
/* Specular: reflection of light around normal, dotted with view dir (-ray)
*/
f_tmp = 2.0 * f_dot;
f_fx = f_tmp*f_nx - f_lx;
f_fz = f_tmp*f_nz - f_lz;
f_len = f_tmp*f_ny - f_ly; /* reuse f_len as ry */
/* view dir is -ray: (-dx, -dy, -dz) */
f_spec = f_fx*(-f_dx) + f_len*(-f_dy) + f_fz*(-f_dz);
if f_spec < 0.0 then f_spec = 0.0;
f_spec = f_spec * f_spec;
/* Combine diffuse + specular + small ambient */
f_dot = 0.12 + .6*f_dot + 0.3*f_spec;
if f_dot < 0.0 then f_dot = 0.0;
if f_dot > 1.0 then f_dot = 1.0;
i_red = int(f_obj_red * f_dot * 255.0);
i_green = int(f_obj_green * f_dot * 255.0);
i_blue = int(f_obj_blue * f_dot * 255.0);
if i_red < 0 then i_red = 0;
if i_red > 255 then i_red = 255;
if i_green < 0 then i_green = 0;
if i_green > 255 then i_green = 255;
if i_blue < 0 then i_blue = 0;
if i_blue > 255 then i_blue = 255;
printc i_red;
printc i_green;
printc i_blue;
}
}
}
}
There are no specific variable type declarations. The type is based on the
first letter of the variable (i for integer, f for floating point, s for string,
and b for boolean).
# are line comments and /* */ are comment blocks. The resulting compiled
x86/x64 program (either Windows or Linux) outputs a PPM (netpbm) image file.
The code is not that great because I haven't fully implemented functions (so no
recursion), and there's no pointers, no structs, and no arrays. Here's the
resulting image:
Post a reply to this message
Attachments:
Download 'rayout.png' (18 KB)
Preview of image 'rayout.png'

|
 |