| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! Factor port of the raytracer benchmark from | 
					
						
							|  |  |  | ! http://www.ffconsultancy.com/free/ray_tracer/languages.html | 
					
						
							| 
									
										
										
										
											2009-09-27 16:11:21 -04:00
										 |  |  | USING: arrays accessors specialized-arrays io | 
					
						
							|  |  |  | io.files io.files.temp io.encodings.binary kernel math | 
					
						
							|  |  |  | math.constants math.functions math.vectors math.parser make | 
					
						
							|  |  |  | sequences sequences.private words hints ;
 | 
					
						
							|  |  |  | FROM: alien.c-types => double ;
 | 
					
						
							| 
									
										
										
										
											2009-09-09 23:33:34 -04:00
										 |  |  | SPECIALIZED-ARRAY: double | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | IN: benchmark.raytracer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! parameters | 
					
						
							| 
									
										
										
										
											2009-02-23 22:40:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Normalized { -1 -3 2 }. | 
					
						
							|  |  |  | CONSTANT: light | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |     double-array{ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         -0.2672612419124244
 | 
					
						
							|  |  |  |         -0.8017837257372732
 | 
					
						
							|  |  |  |         0.5345224838248488
 | 
					
						
							| 
									
										
										
										
											2009-02-23 22:40:17 -05:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-22 20:08:45 -05:00
										 |  |  | CONSTANT: oversampling 4
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-22 20:08:45 -05:00
										 |  |  | CONSTANT: levels 3
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-22 20:08:45 -05:00
										 |  |  | CONSTANT: size 200
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 03:24:32 -04:00
										 |  |  | : delta ( -- n ) epsilon sqrt ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  | TUPLE: ray { orig double-array read-only } { dir double-array read-only } ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | C: <ray> ray | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  | TUPLE: hit { normal double-array read-only } { lambda float read-only } ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | C: <hit> hit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: intersect-scene ( hit ray scene -- hit )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  | TUPLE: sphere { center double-array read-only } { radius float read-only } ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | C: <sphere> sphere | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sphere-v ( sphere ray -- v )
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |     [ center>> ] [ orig>> ] bi* v- ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : sphere-b ( v ray -- b )
 | 
					
						
							|  |  |  |     dir>> v. ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : sphere-d ( sphere b v -- d )
 | 
					
						
							|  |  |  |     [ radius>> sq ] [ sq ] [ norm-sq ] tri* - + ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : -+ ( x y -- x-y x+y )
 | 
					
						
							|  |  |  |     [ - ] [ + ] 2bi ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : sphere-t ( b d -- t )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     -+ dup 0.0 <
 | 
					
						
							| 
									
										
										
										
											2009-04-13 20:48:08 -04:00
										 |  |  |     [ 2drop 1/0. ] [ [ [ 0.0 > ] keep ] dip ? ] if ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : sphere-b&v ( sphere ray -- b v )
 | 
					
						
							|  |  |  |     [ sphere-v ] [ nip ] 2bi
 | 
					
						
							|  |  |  |     [ sphere-b ] [ drop ] 2bi ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  | : ray-sphere ( sphere ray -- t )
 | 
					
						
							|  |  |  |     [ drop ] [ sphere-b&v ] 2bi
 | 
					
						
							|  |  |  |     [ drop ] [ sphere-d ] 3bi
 | 
					
						
							|  |  |  |     dup 0.0 < [ 3drop 1/0. ] [ sqrt sphere-t nip ] if ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : if-ray-sphere ( hit ray sphere quot -- hit )
 | 
					
						
							|  |  |  |     #! quot: hit ray sphere l -- hit | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |         [ ] [ swap ray-sphere nip ] [ 2drop lambda>> ] 3tri
 | 
					
						
							|  |  |  |         [ drop ] [ < ] 2bi
 | 
					
						
							|  |  |  |     ] dip [ 3drop ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sphere-n ( ray sphere l -- n )
 | 
					
						
							|  |  |  |     [ [ orig>> ] [ dir>> ] bi ] [ center>> ] [ ] tri*
 | 
					
						
							|  |  |  |     swap [ v*n ] dip v- v+ ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: sphere intersect-scene ( hit ray sphere -- hit )
 | 
					
						
							|  |  |  |     [ [ sphere-n normalize ] keep <hit> nip ] if-ray-sphere ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  | HINTS: M\ sphere intersect-scene { hit ray sphere } ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  | TUPLE: group < sphere { objs array read-only } ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : <group> ( objs bound -- group )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     [ center>> ] [ radius>> ] bi rot group boa ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : make-group ( bound quot -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     swap [ { } make ] dip <group> ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: group intersect-scene ( hit ray group -- hit )
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |     [ drop objs>> [ intersect-scene ] with each ] if-ray-sphere ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-09 04:07:33 -04:00
										 |  |  | HINTS: M\ group intersect-scene { hit ray group } ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-22 20:08:45 -05:00
										 |  |  | CONSTANT: initial-hit T{ hit f double-array{ 0.0 0.0 0.0 } 1/0. } | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : initial-intersect ( ray scene -- hit )
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |     [ initial-hit ] 2dip intersect-scene ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ray-o ( ray hit -- o )
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |     [ [ orig>> ] [ normal>> delta v*n ] bi* ] | 
					
						
							|  |  |  |     [ [ dir>> ] [ lambda>> ] bi* v*n ] | 
					
						
							|  |  |  |     2bi v+ v+ ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : sray-intersect ( ray scene hit -- ray )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     swap [ ray-o light vneg <ray> ] dip initial-intersect ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  | : ray-g ( hit -- g ) normal>> light v. ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : cast-ray ( ray scene -- g )
 | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |     2dup initial-intersect dup lambda>> 1/0. = [ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         3drop 0.0
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							| 
									
										
										
										
											2008-09-13 03:37:16 -04:00
										 |  |  |         [ sray-intersect lambda>> 1/0. = ] keep swap
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |         [ ray-g neg ] [ drop 0.0 ] if
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : create-center ( c r d -- c2 )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     [ 3.0 12.0 sqrt / * ] dip n*v v+ ; inline
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | DEFER: create ( level c r -- scene )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : create-step ( level c r d -- scene )
 | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |     over [ create-center ] dip 2.0 / [ 1 - ] 2dip create ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : create-offsets ( quot -- )
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |         double-array{ -1.0 1.0 -1.0 } | 
					
						
							|  |  |  |         double-array{ 1.0 1.0 -1.0 } | 
					
						
							|  |  |  |         double-array{ -1.0 1.0 1.0 } | 
					
						
							|  |  |  |         double-array{ 1.0 1.0 1.0 } | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     } swap each ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : create-bound ( c r -- sphere ) 3.0 * <sphere> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : create-group ( level c r -- scene )
 | 
					
						
							|  |  |  |     2dup create-bound [ | 
					
						
							|  |  |  |         2dup <sphere> , | 
					
						
							| 
									
										
										
										
											2008-08-27 17:24:04 -04:00
										 |  |  |         [ [ 3dup ] dip create-step , ] create-offsets 3drop
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] make-group ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : create ( level c r -- scene )
 | 
					
						
							|  |  |  |     pick 1 = [ <sphere> nip ] [ create-group ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ss-point ( dx dy -- point )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |     [ oversampling /f ] bi@ 0.0 double-array{ } 3sequence ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ss-grid ( -- ss-grid )
 | 
					
						
							| 
									
										
										
										
											2010-01-14 13:08:22 -05:00
										 |  |  |     oversampling iota [ oversampling iota [ ss-point ] with map ] map ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ray-grid ( point ss-grid -- ray-grid )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |         [ v+ normalize double-array{ 0.0 0.0 -4.0 } swap <ray> ] with map
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     ] with map ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : ray-pixel ( scene point -- n )
 | 
					
						
							| 
									
										
										
										
											2009-08-25 20:33:48 -04:00
										 |  |  |     ss-grid ray-grid [ 0.0 ] 2dip
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     [ [ swap cast-ray + ] with each ] with each ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : pixel-grid ( -- grid )
 | 
					
						
							| 
									
										
										
										
											2010-01-14 13:08:22 -05:00
										 |  |  |     size iota reverse [ | 
					
						
							|  |  |  |         size iota [ | 
					
						
							| 
									
										
										
										
											2008-03-29 21:36:58 -04:00
										 |  |  |             [ size 0.5 * - ] bi@ swap size | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |             double-array{ } 3sequence
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |         ] with map
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     ] map ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : pgm-header ( w h -- )
 | 
					
						
							|  |  |  |     "P5\n" % swap # " " % # "\n255\n" % ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : pgm-pixel ( n -- ) 255 * 0.5 + >fixnum , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ray-trace ( scene -- pixels )
 | 
					
						
							| 
									
										
										
										
											2008-01-09 17:36:30 -05:00
										 |  |  |     pixel-grid [ [ ray-pixel ] with map ] with map ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : run ( -- string )
 | 
					
						
							| 
									
										
										
										
											2008-12-03 01:05:54 -05:00
										 |  |  |     levels double-array{ 0.0 -1.0 0.0 } 1.0 create ray-trace [ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |         size size pgm-header | 
					
						
							|  |  |  |         [ [ oversampling sq / pgm-pixel ] each ] each
 | 
					
						
							| 
									
										
										
										
											2008-03-11 22:58:50 -04:00
										 |  |  |     ] B{ } make ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-09 03:14:14 -04:00
										 |  |  | : raytracer-main ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-03-11 22:58:50 -04:00
										 |  |  |     run "raytracer.pnm" temp-file binary set-file-contents ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | MAIN: raytracer-main |