Z Ray Tracer

 

About

Z Ray Tracer (ZRT) is a physically based general-purpose ray tracer developed by Hongzhi Wu as an effort to learn the theories and practices of physically based rendering. Z stands for "zhui", a Chinese character which means "trace". Currently I am using it as a test-bed for rendering research (by writing plugins for it).

 

Features

Architecture: Multi-threading, Flexible C-like script language*, Highly customizable Plugins, Instances, Variuous debugging options (partial rendering, debugging shader, etc)
Geometry: Basic Primitives, .OBJ meshes with materials, kd-tree based intersection routines
Textures: Popular texture formats, Mipmap construction, HDR, Environment maps, Normal maps
Shadering Models: Lambertian, Ward, Cook-Torrance, Measured BRDF(MERL Database)
Rendering Techniques: Path tracing, Photon-mapping, Multiple Importance Sampling, Quasi Monte-Carlo

 

Screenshots

Please click on the thumbnails to see the original pictures.

 
Two mirror balls

perfect mirror and global diffuse illumination shader, area light, 4 shadow rays,  mirror reflectance = 0.9.

Mirror bunny and diffuse ball

perfect mirror and global diffuse illumination shader,  area light, 4 shadow rays, mirror reflectance = 0.9.

Silver bunny and orange ball

measured isotropic BRDF global illumination shader, 4 shadow rays, 
BRDFs[2]: silver-metallic-paint, orange-paint
Textured scene

global diffuse illumination shader,  4 shadow rays
Diffuse scene in a lightprobe

global diffuse illumination shader, uffizi light probe, 64 shadow rays
Bronze bunny and a silver ball on a plane with blue- metallic-paint BRDF Tainted screws on a table

screws using measured silver-metallic-paint BRDF modulated with a texture. Note the anisotropicity on the body of the screws due to the small-scale varaitions in geometry

Silver-metallic-paint  ball

measured isotropic BRDF global illumination shader, 64 shadow rays
Fighter

global diffuse illumination shader

Tank

global diffuse illumination shader

         
         

 

R&D Log

07/13/2007    Implemented tone mapping using bilateral filtering [3]. Some of the pictures below are adjusted using tone-mapping.

05/06/2007    Used flex and bison to generate a parser for our own scene description. Now ZRT is a completely data-driven command line tool.

04/29/2007    Added 2d MIP-MAPed textures and cube map.

04/24/2007    Added isotropic BRDF shaders for both analytical(Ward) and measured-data (MERL dataset) models.

04/03/2007    Added support for triangular meshes; Added a BSP tree based intersection accelerator for meshes and a kd tree acceleration structure for the entire scene.

03/27/2007    Summary of previous progress: Established the overall general purpose offline renderer architecture. Features area light, soft shadows, indirect lighting (global illumination) shader and perfect mirror shader.

 

Sample Scene Configuration File

cam = pinhole_camera(vector3(0, 1, 3.25), vector3(0, 1, -3), vector3(0, 1, 0), 0.1, 0.1, 0.1)

 

cam_sampler = super_camera_sampler(cam, subpixel = 2, 0)

 

// init light

lt_scale = 0.5

lt = env_light(

  spectrum(lt_scale, lt_scale, lt_scale),

  100000,

  raw_RGB_cube_texture("Data\rnl_cross.raw_cube"),

  transformation(

  )

)

 

// init shaders

sh = global_diffuse_shader()

matr_white = material (

  "diffuse_reflectance" = RGB(0.9, 0.9, 0.9)

)

 

matr_red = material (

  "diffuse_reflectance" = RGB(0.9, 0.1, 0.1)

)

 

matr_green = material (

  "diffuse_reflectance" = RGB(0.1, 0.9, 0.1)

)

 

linkmap = shader_link_map (

  "reflectance" = "diffuse_reflectance",

  "reflectance_mapping" = "mapping",

  "reflectance_texture" = "texture",

  "reflectance_sampler" = "sampler"

)

 

rect  = rectangle_shape(2.0, 2.0)

sphere= sphere_shape(0.25)

plane = kd_tri_mesh_shape("Data\airplane.obj", 0.01, 6)

 

//bottom

obj_bottom = simple_object(rect,

  transformation(

    rotate_x(-PI/2),

    translate(0.0, 0.0, 0.0)

  ),

  matr_white, sh, linkmap)

 

//back

obj_back = simple_object(rect,

  transformation(

    translate(0.0, 1.0, -1.0)

  ),

  matr_white, sh, linkmap)

 

//left

obj_left = simple_object(rect,

  transformation(

    rotate_y(PI/2),

    translate(-1.0, 1.0, 0.0)

  ),

  matr_red, sh, linkmap)

 

//ball1

obj_ball = simple_object(sphere,

  transformation(

    translate(-0.65, 0.25, 0.4)

  ),

  matr_white, sh, linkmap)

 

//plane

obj_plane = simple_object(plane,

  transformation(

    scale(0.8, 0.8, 0.8),

    rotate_x(-PI/2),

    rotate_y(-PI/6),

    translate(-0.1, 0.6, -0.05)

  ),

  matr_white, sh, linkmap)

 

// init scene

s = photon_mapped_scene(num_photons = 1000000, 0, kd_scene_isaccelerator(0.01, 4))

s += (lt,

      obj_back,

      obj_bottom,

      obj_left,

      obj_plane,

      obj_ball)

 

// let's get started...

imaging(s, cam_sampler,

  width = 256, height = 256,

  photon_mapping_option(256,

    num_shadow = 512, //shadow rays

    num_gather = 256, //gather rays

    num_lookup = 8000,

    radius = 0.025,

    gather = 1, // gather for L_i or use photon estimation directly

    trace = 1 // direct raytrace L_d or use photon estimation directly

  ),

  "boxenvp.raw"

)

 

shell("raw2png boxenvp.raw /o boxenvp.png")

 

References

[1] Matt Pharr and Greg Humphreys. Physically based rendering. Morgan Kaufmann Press, 2004

[2] Wojciech Matusik, Hanspeter Pfister, Matt Brand, and Leonard McMillan. A data-driven reflectance model. ACM Trans. Graph. 22(3):759-769, 2003

[3] Fredo Durand and Julie Dorsey. Fast Bilateral Filtering for the Display of High-Dynamic-Range Images. Proceedings of the 29th annual conference on Computer graphics and interactive techniques : 257-266, 2002

 

Back to Cool Stuff

Last Updated  2009-02-05 23:34:05