So ya notice anything different between these two images?
How about now?
Golly! The reason for the “jaggies” is because I only used one ray per pixel. As I step pixel by pixel and row by row (image space), I’m also stepping in world space.
The image space goes from (0,0) to (w,h) and my world space goes from (-0.5,-0.5) to (+0.5, +0.5). In this case w=h=size cuz I wanted to make square images. Udderwize, I’d use an x_inc and a y_inc…
Here is what the main loop looks like:
public RenderedImage traceBall( Settings settings, BufferedImage image ) {
double size = settings.getSize();
double x = -0.5;
double y = -0.5;
double inc = 1 / size;
Pt start = new Pt( -0.5, -0.5, 0 );
Pt stop = new Pt();
for ( int i = 0 ; i < size ; i++, y+= inc ) {
x = -0.5;
start.setY( y );
for ( int j = 0 ; j < size ; j++, x+= inc ) {
start.setX( x );
stop.copy( start );
stop.setZ( -1 );
image.setRGB(
j
, i
, this.traceRay( start, stop, settings ).getRGB()
);
}
}
return image;
}
The traceRay routine will use 1 of three implementations depending on the settings: simple (1 ray, no light), light (1 ray, 1 light) or accumulate(n^2 rays, 1 light).
Accumulate just steps from (x,y) to (x+inc,y+inc) in (inc/n) steps:
public Rgbank accumulate_traceRay( Pt start, Pt stop, Settings settings ) {
Rgbank accum = new Rgbank( 0, 0, 0, 0 );
double size = settings.getSize();
double inc = 1 / size;
double sub_div = settings.getRays();
double sub_inc = inc / sub_div;
double xend = start.getX() + inc;
double yend = start.getY() + inc;
Pt start_sub = new Pt( start );
Pt stop_sub = new Pt( stop );
for ( double y = start.getY() ; y < yend; y+= sub_inc ) {
start_sub.setY( y );
stop_sub.setY( y );
for ( double x = start.getX() ; x < xend ; x+= sub_inc ) {
start_sub.setX( x );
stop_sub.setX( x );
Rgbank color = this.light_traceRay( start_sub, stop_sub, settings );
accum.add( color );
}
}
Rgbank color = new Rgbank( accum );
color.divide( sub_div * sub_div );
return color;
}
And that’s all there is too it! At this point RayBall.java contains the complete listing, but no more spoilers…




