Raytracing a sphere : more rays per pixel

So ya notice anything different between these two images?

versus

How about now?

versus

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…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: