static void Main(string[] args) { //-------------------------------------------------------------------------------- // Build the scene //-------------------------------------------------------------------------------- double t_init = Time.getTime(); Camera camera = new Camera() { width = 600, height = 400, subsamples = 1, fov_y = 40, pos = new vect3d(0, .75, 3) }; var occluder = new GroupList(); var plane = new Plane(new vect3d(0, 0, 0), new vect3d(1, 0, 0), new vect3d(1, 0, -1), new ShadowShader()); //var plane = new Plane(new vect3d(0, 0, 0), new vect3d(1, 0, 0), new vect3d(1, 0, -1), new TextureShader("../../../../resources/images/wall_512_3_05_sml2.jpg")); plane.x *= .3; plane.y *= .3; occluder.add(plane); //occluder.add(new Sphere(new vect3d(0,.5,0), .5, new ShadowShader())); //occluder.add(new Sphere(new vect3d(0, .5, 0), .5, new TextureSphereShader("../../../../resources/images/earthmap1k.jpg"))); GroupList obj = load_obj("../../../../resources/models/armadilloman2.obj", new ShadowShader()); occluder.add(new GroupTree(obj.list, obj.shader)); var scene = new Scene() { occluder = occluder }; scene.lights.Add(new Light() { color = new vect3d(1, 1, 1) * 60, pos = new vect3d(-4, 8, 8) }); scene.lights.Add(new Light() { color = new vect3d(1, 1, 1) * 40, pos = new vect3d(1, 15, 10) }); //-------------------------------------------------------------------------------- // Render the scene //-------------------------------------------------------------------------------- double t_start = Time.getTime(); System.Console.WriteLine("Time taken to create scene = {0}s", (t_start - t_init) / 1000); Bitmap bmp = camera.create_image(scene); double t_end = Time.getTime(); System.Console.WriteLine("Time taken to render = {0}s", (t_end - t_start) / 1000); //-------------------------------------------------------------------------------- // Write the image to disk //-------------------------------------------------------------------------------- bmp.Save("output.png"); }
public Bitmap create_image(Scene scene) { Bitmap bmp = new Bitmap(width, height); // get the orientation of the camera matrix4d rotmat = orient.getMatrix(); vect3d rt = new vect3d(rotmat.m[0], rotmat.m[1], rotmat.m[2]); vect3d up = new vect3d(rotmat.m[4], rotmat.m[5], rotmat.m[6]); vect3d fwd = new vect3d(rotmat.m[8], rotmat.m[9], rotmat.m[10]); // convert the orientation to a 3D screen double aspect = (double)width / (double)height; double h = Math.Tan(fov_y * Math.PI / 360.0); up *= -h * 2; rt *= aspect * h * 2; fwd *= -1; // 2D screen conversions vect3d dx = rt / width; vect3d dy = up / height; vect3d corner = fwd - rt * .5 - up * .5; // expose each pixel Ray r = new Ray(); r.scene = scene; double subsample_res = 1.0 / subsamples; for (int j = 0; j < bmp.Height; j++) { for (int i = 0; i < bmp.Width; i++) { vect3d color = new vect3d(0, 0, 0); for (int jj = 0; jj < subsamples; jj++) { for (int ii = 0; ii < subsamples; ii++) { // set ray properties r.pos = this.pos; r.hit_dist = Double.MaxValue; r.color = new vect3d(0, 0, 0); r.hit_object = null; r.dir = corner + dx * (i + (ii+.5/*Rand.rand.NextDouble()*/) * subsample_res) + dy * (j + (jj+.5/*Rand.rand.NextDouble()*/) * subsample_res); r.dir.normalize(); // trace the ray scene.trace(r); if (r.hit_object != null) { r.hit_object.shader.colorize(r); color += r.color; } } } color *= subsample_res * subsample_res; // gamma correct the color double brightness = color.length(); color /= Math.Sqrt(brightness); // store the color int red = clamp(color.x); int green = clamp(color.y); int blue = clamp(color.z); bmp.SetPixel(i, j, Color.FromArgb(255, red, green, blue)); } } return bmp; }