rayhunter (version 1.3.4)
More sample images in rayhunter gallery.
rayhunter is a command-line program that takes a 3D model (like a VRML, X3D or Collada file) and renders an image that would be visible from given camera looking at given scene. Two ray-tracing algorithms may be used: deterministic (classic Whitted-style ray-tracer) and Monte Carlo path tracing.
You can take a look at the gallery of images rendered using rayhunter as a demonstration of rayhunter's capabilities.
(64 bit, x86_64)
(32 bit, works on 64-bit too)
Mac OS X
If you like this software, please consider donating.
No installation is required. Just download and unpack these archives wherever you want, and run the program inside. The documentation (this web page) is also included inside (look in the documentation/ subdirectory) for offline viewing.
This is free/open-source software. Developers can download sources of this program.
Basic syntax to call rayhunter is
rayhunter classic <recursion-depth> <image-width> <image-height> <input-filename> <output-filename>
rayhunter path <recursion-depth> <non-primary-samples-count> <image-width> <image-height> <input-filename> <output-filename>
First option, classic or path, says which ray-tracing algorithm to use.
This is normal Whitted-style deterministic ray-tracer. All normal VRML lights are handled (point, spot, directional, including the headlight). No area lights, so no soft shadows. Algorithm sends one primary ray for each pixel. Ray-tracing is recursive, where the ray casts on some surface we check rays to light sources and eventually we recursively check refracted ray (when Material has transparency > 0) and reflected ray (when Material has mirror > 0). Wikipedia has a nice article about ray-tracing that describes Whitted-style ray-tracing.
This is path tracer. Every surface with non-zero emissiveColor is a light emitter. For each pixel many random paths are checked and final pixel color is the average color from all paths.
Actually rayhunter for every pixel checks <primary-samples-count> of primary rays, and then each primary ray that hits something splits into <non-primary-samples-count>. So in total we check <primary-samples-count> * <non-primary-samples-count> paths. This is a sensible optimization, because usually there is no need to take many <primary-samples-count>, since all primary rays hit more-or-less the same thing, since they have very similar direction.
<non-primary-samples-count> is set using the 3rd required command-line option, and <primary-samples-count> is set using optional option --primary-samples-count (by default it's 1).
This is interpreted differently by different ray-tracing algorithms:
- For classic ray-tracer this is maximum allowed
recursion depth. If you will give here too small value,
then some optical effects will not be visible.
For normal scenes (without too complex mirror and transparent
surfaces' setting) values 2 or 3 are appropriate.
0 means that each object will have only his own color. 1 means that light rays can light the surface, and ray may be once reflected or refracted. Greater values allow rays to be reflected and/or refracted more times along the way.
- For path tracer this is minimal path length.
I.e. Russian-roulette will not be used to decide
about the termination until the path will reach this length.
(Of course, some paths may still be shorter than this
minimal length, because the ray will not hit anything in the scene.)
E.g. if you will set this to 3, and Russian-roulette parameter
(see --r-roul-continue option) will be 0.5
(the default value), then 1/2 of all paths will have length 3,
1/4 of all paths will have length 4,
1/8 of all paths will have length 5 etc.
Russian-roulette makes sure that the result is unbiased, i.e. the expected value is the correct result (i.e. the perfect beautiful realistic image). However, Russian-roulette introduces also a large variance, visible as a noise on the image.
That's where forcing some minimal path length helps. Sensible values for this are 1 or 2. Of course, the greater the better, but it will also slow down the rendering. 0 means that Russian-roulette will always be used to decide about path termination (expect a lot of noise on the image!).
- For classic ray-tracer this is maximum allowed recursion depth. If you will give here too small value, then some optical effects will not be visible. For normal scenes (without too complex mirror and transparent surfaces' setting) values 2 or 3 are appropriate.
Only for path tracer. Together with <primary-samples-count>, this specifies how many paths will be checked at each pixel. Various scenes may require different numbers here to look nice — you can start with 10, then 100, then even 1000. But beware — this value directly affects rendering speed.
Width and height of resulting image.
3d model filename.
Anything that my code can read (see view3dscene docs) is accepted here. VRML / X3D are the best formats, we also read Collada and 3DS lights, for all other formats: only the headlight will shine over the scene.
- (single dash) as a filename means stdin.
Filename where to write final image. Image format will be automatically derived from filename extension, known image formats and extensions are
- rgbe (or pic)
- jpg (or jpeg)
If you will use --write-partial-image features (see below), then partial images will be also written to this file. Moreover, if you will use --first-row features (see below), then initial image contents will be read from this file.
Notes about RGBE format: This format was developed by Greg Ward, and is used e.g. by Radiance. Colors in RGBE images are written with a very good precision, while not wasting a lot of disk space. Good precision means that you may be able to expose in the image some details that were not initially visible for the human eye, e.g. by brightening some areas. Also color components are not clamped to [0; 1] range — each component can be any large number. This means that even if resulting image is too bright, and some areas look just like white stains, you can always correct the image by darkening it or applying gamma correction etc.
Options below may be placed anywhere at command-line (before, between or after required options listed above).
Only for classic ray-tracer :
Implemented light model is as close as possible to the light model outlined in VRML 97 specification. Some modifications were needed because I have recursive ray-tracing (while VRML 97 specifies only local light model). Also VRML 1.0 models require different treating in some cases (e.g. SpotLight focus is specified using a different way and ambientIntensity is not available in standard VRML 1.0).
We handle all VRML light nodes — DirectionalLight, SpotLight and PointLight. Also the headlight is used, configurable by NavigationInfo.headlight and KambiNavigationInfo.headlightNode.
For <recursion-depth> equal zero we use only diffuse material color. According to VRML 97 light model, emission color would be more correct but in 99% of real cases emission color is just black so the whole rendered image would be black. That's why I decided to use diffuse color instead of emission. Everyone understands that setting <recursion-depth> to zero is only for testing purposes anyway.
Mostly for classic ray-tracer :
Use mirror field of Material node to create mirrors.
Only for path tracer :
We don't use point and directional lights, so VRML DirectionalLight, SpotLight and PointLight nodes are completely ignored. Only the surface lights are used. Every object with a non-black emissiveColor is a light source.
Implemented BRDF is Phong's BRDF. See fields describing physical properties (Phong's BRDF) for Materialnode.
Some things not handled (yet): textures, interpolating normal vectors (i.e. we're of course calculating pixel color at every surface point separately, but our surfaces are flat with regards to normal vectors).
This concerns actually most 3d engines, including ray-tracer algorithms inside rayhunter and real-time OpenGL rendering inside view3dscene: 3d model's geometry must be correct. Which means that:
No T-Intersections allowed. Otherwise you may see cracks.
If two faces cross each other, the intersection may be a line, not a plane. I.e. they shouldn't be coplanar in such case. Otherwise they will fight which one is nearer than the other and which one casts the shadow over the other.
Actually rayhunter should be able to handle such bad case of coplanar surfaces (i.e. result will look OK as long as surfaces have the same material), but there is never 100% warranty for such things (because it involves floating-point errors).
The obvious advantage is that you can use rayhunter in batch mode,from scripts etc.
rayhunter can produce images in RGBE format.
- You can use options --first-row and --write-partial-rows to be able to kill rayhunter process at any time and then later resume rendering from last point. You can also use the same options to render various parts of the image simultaneously on multiple systems. These advantages may be crucial if you want to do some serious rendering using path tracer, since they may take a lot of time.
Options --r-roul-continue, --direct-illum-samples-count, --primary-samples-count that allow you to better control path tracing are not available in view3dscene.
- rayhunter may work a little faster since it doesn't display the image while rendering. Although using --write-partial-rows you can force rayhunter to write partial result from time to time.