protected IConstantBuffer GetModelViewTransformBuffer(SceneNode root, ICameraNode cam) { Matrix4 invCamWorldTrans = cam != null ? (cam.GetInverseWorldTransform(root) ?? Matrix4.Identity) : Matrix4.Identity; Dictionary <ICameraNode, ConstantBuffer <ModelViewTrans> > camToBufferMap = null; if (!_modelViewTransformBuffers.ContainsKey(root)) { camToBufferMap = new Dictionary <ICameraNode, ConstantBuffer <ModelViewTrans> >(); _modelViewTransformBuffers[root] = camToBufferMap; } else { camToBufferMap = _modelViewTransformBuffers[root]; } ConstantBuffer <ModelViewTrans> cbuffer = null; if (!camToBufferMap.ContainsKey(cam)) { cbuffer = new ConstantBuffer <ModelViewTrans>(); camToBufferMap.Add(cam, cbuffer); } else { cbuffer = camToBufferMap[cam]; } ModelViewTrans mvt = new ModelViewTrans(); mvt.ModelViewMatrix = invCamWorldTrans * (this.GetWorldTransform(root) ?? Matrix4.Identity); if (cbuffer.Value.ModelViewMatrix != mvt.ModelViewMatrix) { mvt.NormalMatrix = mvt.ModelViewMatrix.NormalMatrix; cbuffer.Value = mvt; } return(cbuffer); }
public Image Render(ICameraNode camera, int sample, int max_depth) { bvh = new BVH(new List <IVisualNode>(visual_nodes)); if (sample < 1) { sample = 1; } Image image = new Image(camera.View.Width, camera.View.Height); Vector2 half_size = new Vector2(camera.View.Width / 2.0f, camera.View.Height / 2.0f); for (int y = 0; y < camera.View.Height; ++y) { for (int x = 0; x < camera.View.Width; ++x) { Vector2 uv = new Vector2((x - half_size.X) / half_size.X, (half_size.Y - y) / half_size.Y); Vector3 color = Vector3.Zero; for (int n = 0; n < sample; ++n) { Vector2 delta = new Vector2(MathHelper.RandomFloat() / camera.View.Width, MathHelper.RandomFloat() / camera.View.Height); Vector2 new_uv = uv + delta; Ray ray = camera.GetRay(new_uv.X, new_uv.Y); color += Color(ray, 0, max_depth); } color /= sample; image[x, y] = color; } } return(image); }
static void Main(string[] args) { ISceneGraph scene_graph = SceneGraphFactory.Create(); ITexture checker_texture = new CheckerTexture(new ConstantTexture(new Vector3(0.2f, 0.3f, 0.1f)), new ConstantTexture(new Vector3(0.9f, 0.9f, 0.9f))); SphereNode sphere = scene_graph.AddShape(Shape.Sphere) as SphereNode; sphere.Translation = new Vector3(0.0f, -1000.0f, 0.0f); sphere.Material = new LambertianMaterial(checker_texture); sphere.Radius = 1000.0f; sphere = scene_graph.AddShape(Shape.Sphere) as SphereNode; sphere.Translation = new Vector3(0.0f, 1.0f, 0.0f); sphere.Material = new DielectricMaterial(1.5f); sphere.Radius = 1.0f; sphere = scene_graph.AddShape(Shape.Sphere) as SphereNode; sphere.Translation = new Vector3(0.0f, 3.0f, 0.0f); sphere.Material = new DiffuseLightMaterial(new ConstantTexture(new Vector3(3.0f, 3.0f, 3.0f))); sphere.Radius = 1.0f; sphere = scene_graph.AddShape(Shape.Sphere) as SphereNode; sphere.Translation = new Vector3(-4.0f, 1.0f, 0.0f); sphere.Material = new LambertianMaterial(new ConstantTexture(new Vector3(0.4f, 0.2f, 0.1f))); sphere.Radius = 1.0f; sphere = scene_graph.AddShape(Shape.Sphere) as SphereNode; sphere.Translation = new Vector3(4.0f, 1.0f, 0.0f); sphere.Material = new MetalMaterial(new ConstantTexture(new Vector3(0.7f, 0.6f, 0.5f)), 0.0f); sphere.Radius = 1.0f; for (int z = -10; z <= 10; ++z) { for (int x = -10; x <= 10; ++x) { float choose_material = MathHelper.RandomFloat(); Vector3 translation = new Vector3(x + 0.9f * MathHelper.RandomFloat(), 0.2f, z + 0.9f * MathHelper.RandomFloat()); if (Vector3.Distance(translation, new Vector3(4.0f, 0.2f, 0.0f)) > 0.9f) { SphereNode ball = scene_graph.AddShape(Shape.Sphere) as SphereNode; ball.Translation = translation; ball.Radius = 0.2f; if (choose_material < 0.8f) { ball.Material = new LambertianMaterial(new ConstantTexture(new Vector3(MathHelper.RandomFloat() * MathHelper.RandomFloat(), MathHelper.RandomFloat() * MathHelper.RandomFloat(), MathHelper.RandomFloat() * MathHelper.RandomFloat()))); } else if (choose_material < 0.95f) { ball.Material = new MetalMaterial(new ConstantTexture(new Vector3(1.0f + MathHelper.RandomFloat(), 1.0f + MathHelper.RandomFloat(), 1.0f + MathHelper.RandomFloat()) * 0.5f), 0.5f * MathHelper.RandomFloat()); } else { ball.Material = new DielectricMaterial(1.5f); } } } } ICameraNode camera = scene_graph.AddCamera(); camera.View.Width = 1200; camera.View.Height = 800; camera.SetProjection(20.0f); camera.Translation = new Vector3(13.0f, 2.0f, 3.0f); camera.Rotation = MathHelper.LookAt(camera.Translation, new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f)); Image image = scene_graph.Render(camera, 50, 50); PPMImageSaver saver = new PPMImageSaver(); string path = args.Length > 0 ? args[0] : "output.ppm"; saver.Save(image, path); }