// sample: samples a single path up to a maximum depth private Vector3 Sample(Ray ray, int depth, int x, int y) { // find nearest ray/scene intersection Scene.Intersect(ray); if (ray.objIdx == -1) { // no scene primitive encountered; skybox return(1.0f * scene.SampleSkydome(ray.D)); } // calculate intersection point Vector3 I = ray.O + ray.t * ray.D; // get material at intersection point Material material = scene.GetMaterial(ray.objIdx, I); if (material.emissive) { // hit light return(material.diffuse); } // terminate if path is too long if (depth >= MAXDEPTH) { return(Vector3.Zero); } // handle material interaction float r0 = RTTools.RandomFloat(); Vector3 R = Vector3.Zero; if (r0 < material.refr) { // dielectric: refract or reflect RTTools.Refraction(ray.inside, ray.D, ray.N, ref R); Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f); extensionRay.inside = (Vector3.Dot(ray.N, R) < 0); return(material.diffuse * Sample(extensionRay, depth + 1, x, y)); } else if ((r0 < (material.refl + material.refr)) && (depth < MAXDEPTH)) { // pure specular reflection R = Vector3.Reflect(ray.D, ray.N); Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f); return(material.diffuse * Sample(extensionRay, depth + 1, x, y)); } else { // diffuse reflection if (x == 500 && y == 400) { //Console.WriteLine("test"); //return new Vector3(255,255,255); } R = RTTools.DiffuseReflection(RTTools.GetRNG(), ray.N); Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f); return(Vector3.Dot(R, ray.N) * material.diffuse * Sample(extensionRay, depth + 1, x, y)); } }
public void Update() { // construct a look-at matrix E = Vector3.Normalize(target - pos); up = Vector3.UnitY; right = Vector3.Cross(up, E); float[] rightxs = { right.X, right.X, right.X, right.X }; float[] rightys = { right.Y, right.Y, right.Y, right.Y }; float[] rightzs = { right.Z, right.Z, right.Z, right.Z }; rightx4 = new Vector <float>(rightxs); righty4 = new Vector <float>(rightys); rightz4 = new Vector <float>(rightzs); up = Vector3.Cross(E, right); float[] upxs = { up.X, up.X, up.X, up.X }; float[] upys = { up.Y, up.Y, up.Y, up.Y }; float[] upzs = { up.Z, up.Z, up.Z, up.Z }; upx4 = new Vector <float>(upxs); upy4 = new Vector <float>(upys); upz4 = new Vector <float>(upzs); // calculate focal distance Ray ray = new Ray(pos, E, 1e34f); Scene.Intersect(ray); focalDistance = Math.Min(20, ray.t); // calculate virtual screen corners Vector3 C = pos + focalDistance * E; p1 = C - 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up; p2 = C + 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up; p3 = C - 0.5f * focalDistance * aspectRatio * right - 0.5f * focalDistance * up; float[] p1sX = { p1.X, p1.X, p1.X, p1.X }; float[] p2sX = { p2.X, p2.X, p2.X, p2.X }; float[] p3sX = { p3.X, p3.X, p3.X, p3.X }; float[] p1sY = { p1.Y, p1.Y, p1.Y, p1.Y }; float[] p2sY = { p2.Y, p2.Y, p2.Y, p2.Y }; float[] p3sY = { p3.Y, p3.Y, p3.Y, p3.Y }; float[] p1sZ = { p1.Z, p1.Z, p1.Z, p1.Z }; float[] p2sZ = { p2.Z, p2.Z, p2.Z, p2.Z }; float[] p3sZ = { p3.Z, p3.Z, p3.Z, p3.Z }; p1x4 = new Vector <float>(p1sX); p1y4 = new Vector <float>(p1sY); p1z4 = new Vector <float>(p1sZ); p2x4 = new Vector <float>(p2sX); p2y4 = new Vector <float>(p2sY); p2z4 = new Vector <float>(p2sZ); p3x4 = new Vector <float>(p3sX); p3y4 = new Vector <float>(p3sY); p3z4 = new Vector <float>(p3sZ); }
public void Update() { // construct a look-at matrix E = Vector3.Normalize(target - pos); up = Vector3.UnitY; right = Vector3.Cross(up, E); up = Vector3.Cross(E, right); // calculate focal distance Ray ray = new Ray(pos, E, 1e34f); Scene.Intersect(ray); focalDistance = Math.Min(20, ray.t); // calculate virtual screen corners Vector3 C = pos + focalDistance * E; p1 = C - 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up; p2 = C + 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up; p3 = C - 0.5f * focalDistance * aspectRatio * right - 0.5f * focalDistance * up; }