RTRay A: classic scene 27 March 2002

Thirteen versions of a Win32 raytracer built on the same small “pattern” framework as the other C++ effects of the time. The early versions render flat-shaded spheres with shadows:

RTRay A, version 002: flat-shaded spheres casting shadows on a grey plane

Version 007 brought a “new, optimised image subdivision scheme”. By version 008, the “proper scene”, the spheres reflect each other and the plane:

RTRay A, version 008: reflective spheres over a plane
RTRay A, version 008: a second view of the reflective scene

Version 009 opens with a note:

RTRay v0.09
-----------

2002.08.19 - Picked up after ages

From version 010 the raytracer moved onto the class library of the PolyCSG experiments (see C++ graphics effects), and its Main.cpp carries that whole history:

PolyCSG 001
-----------

. Basic render framework up and running

PolyCSG 002
-----------

  . Added Image class
  . Converted buffer to Image class

> First draft of polygon class

  . Polygon edge rendering (scanline based)
  . Not yet tested

PolyCSG 003
-----------

  . Solid rendering

  . Added scanline class
  . Use scanline class for polygon rendering
  . Moved classes to seperate cpp & h files

  . Pass polygon into buffer to render

PolyCSG 004
-----------

  . Removed Poly.render - have to use Image.drawPolygon
  . Added first CSG option - XOR
  . XORPoly.render used to render

PolyCSG 005
-----------

  . Get poly subclass rendering working ( Image.drawPolygon )
  . Add ANDPoly class
  . Polygon intersection (AND) up and running!

PolyCSG 006
-----------

  . Fix in ANDPoly class ( oka && okb -> oka || okb )
  . Added SUBPoly
  . Added ORPoly

PolyCSG 007
-----------

  2002/08/26 01:00 (while smackdown was on after playing cards at the house - Steve won)

  . Added getVScanline function to all polys
  . Added or,and,sub class declarations to main file
  . Renamed Image.drawPolygon to Image.fillPolygon
  . Renamed Image.drawScanline to Image.fillScanline + made private
  . Added Image.drawPolygon, Image.drawScanline, Image.drawVScanline
  . Removed Poly.render (use Image.fillPolygon instead)

  NOW SUPPORTS RENDERING FILLED AND UNFILLED POLYS

PolyCSG 008
-----------

  ~ Antialiased poly functions
  . Added Image.blendCol
  . Initial AA tests.. need edge gradients stored in scanline points

  . RotatePoly class added
  . Poly.firstPoint, nextPoint & peekPoint added

  POLYGON ROTATION WORKING

  . Added pixel text functions to Image

PolyCSG 009
-----------

  . Added TranslatePoly class
  . Fixed memory leak in Redraw() - was not deleting all Poly's

  > Interesting poly shapes



Motion 001
----------

  . Moved classes to Classes folder


RTRay 010
---------

  . Added more detailed frame rate indicators

And from version 011:

RTRay 011
---------

  . Added new class-based scene definition

Source

RTRay B: first-hit sphere optimisation 24 June 2004

Efforts to reduce the number of sphere first hit tests using sphere on-screen bounding boxes. The library header, rt.h, starts its changelog in August 2003:

Lewpen's Realtime Raytracing library


Changelog
-

2003-08-24
  2151 - Added xc, xs, yc, ys to RT_SCENE to hold per-rotation constants

2003-08-25
  2015 - Added size, w2,w3,w4,wm4 to RT_VIEW

2005-11-12
  Elsewhere, added simple z test before doing full sphere hit

Version 0004 is the reference to measure against:

Simple 4x supersample

First ray only

Spheres only

No shadows

No reflections

29.75 FPS

Tests each sphere

From version 0005, rendering.txt plans the next layer:

Rendering the scene with reflection etc.

Layers
-

Object colour
  Texture colour
  Lighting calculation

Reflection colour added





Should lighting be pre-calculated for scene?
If so, how should it be stored for general objects?






do_4x4_object()





if( same(obj) && same(inshadow) )
{
  fillwithshadow()

  if( same(reflection) && same(reflectioninshadow) )
  {
  }
  else
  {
  }
}
else
{
  subdivide()
}

The versions after that: 0006 keeps sphere counts on each row and column (with two side experiments, 0006a and 0006b, with a curved lens); 0007 finishes the row/column optimisation with a 500 sphere demo; 0008 draws the best in and out graphs; 0009 adds simple lighting, and produced an interesting accidental effect along the way; 0012 adds basic specular lighting; 0013 tries z plane hit testing; 0014 sorts the spheres by z, which “seems to actually slow down hit tests”; 0015 goes back to 0008.

Realtime Raytrace window: a coiled string of coloured spheres
Realtime Raytrace window with the in and out graphs along the edges
Realtime Raytrace window, a second capture
Realtime Raytrace window, a third capture

The notes kept with version 0012, dated 7 August 2005:

Changelog
-

v0012

07/Aug/2005
  Making a constant which defines the size of the superpixels



Realtime rendering system
-

. First-hit optimisation for spheres
. One light source, no shadowing yet apart from dark side of objects
. Can render 500 spheres with 10fps on my 2.2GHz laptop




The optimisation
-

Based on bounding boxes, the first-ray intersection code does not have to check every object at every pixel
It uses the fact that you are doing the interesction tests along a scanline, and then moving to the next scanline down




Further optimisations
-

Spheres can have z-boundaries, so once a sphere intersection test has been successful for a pixel you don't need to check all other spheres,
because some have no way of coming close.

This might get in the way of CSG, which i think is imminently possible.




CSG - A method
-

Get all the entry and exit points of all the spheres at this pixel
Order entry and exit points with the nearest to the viewer first

Have an array of flags, one for each sphere

For each point, starting at the viewer:
  If you are entering a sphere, set that sphere's flag
  If you are leaving a sphere, clear that sphere's flag
  Check against the formula for this CSG
    eg. ( A | B ) & ( C - D )
	If we are already inside A and C and we have just left D the values are:
	  A=1
	  B=0
	  C=1
	  D=0
	So the equation's value is 1
  The first time the result is 1 is where the ray intersects the CSG
  The surface properties of the point are those of the sphere we have just enetered/left

Source