/// <summary> /// Creates bounced vector (directing from intersection) from given input vector (direction towards intersection) /// </summary> /// <param name="p">Input vector</param> /// <returns>bounced vector</returns> private Vector bounceVector(Intersection p) { Vector smer = p.ray.direction; smer.Normalize(); Vector n = new Vector(p.normal); n.Normalize(); Vector en = 2 * Vector.CrossProduct(smer, n); Vector v = Vector.CrossProduct(en, n) + smer; return(v); }
public static Matrix ViewTransform(Point from, Point to, Vector up) { var forward = (to - from).Normalize(); var upn = up.Normalize(); var left = forward.Cross(upn); var true_up = left.Cross(forward); var orientation = new Matrix(new double[, ] { { left.x, left.y, left.z, 0 }, { true_up.x, true_up.y, true_up.z, 0 }, { -forward.x, -forward.y, -forward.z, 0 }, { 0, 0, 0, 1 } }); return(orientation * Transformation.Translation(-from.x, -from.y, -from.z)); }
public static Matrix ViewTransform(Point from, Point to, Vector up) { var forward = to.Subtract(from).Normalize().ToPoint(); var upN = up.Normalize(); var left = forward.Cross(upN); var trueUp = left.Cross(forward); var orientation = new Matrix(new double[, ] { { left.X, left.Y, left.Z, 0 }, { trueUp.X, trueUp.Y, trueUp.Z, 0 }, { -forward.X, -forward.Y, -forward.Z, 0 }, { 0.0, 0.0, 0.0, 1.0 } }); return(orientation.Multiply(Matrix.Translation(-from.X, -from.Y, -from.Z))); }
static public Vector CalculateSurfaceNormal(Vertex[] v) { Vector rtn = new Vector(); for (int i = 0; i < v.Length; i++) { Vector current = v[i].m_pos; Vector next = v[(i + 1) % v.Length].m_pos; rtn.m_x = rtn.m_x + ((current.m_y - next.m_y) * (current.m_z + next.m_z)); rtn.m_y = rtn.m_y + ((current.m_z - next.m_z) * (current.m_x + next.m_x)); rtn.m_z = rtn.m_z + ((current.m_x - next.m_x) * (current.m_y + next.m_y)); //rtn.PrintVector(); } rtn = rtn.Normalize(); return(rtn); //return rtn; }
/// <summary> /// some helper functions to calculate the refraction rays /// </summary> /// <param name="P"></param> /// <param name="N"></param> /// <param name="V"></param> /// <param name="refraction"></param> /// <returns></returns> private Ray GetRefractionRay(Vector P, Vector N, Vector V, double refraction) { //V = V * -1; //double n = -0.55; // refraction constant for now //if (n < 0 || n > 1) return new Ray(P, V); // no refraction double c1 = N.Dot(V); double c2 = 1 - refraction * refraction * (1 - c1 * c1); if (c2 < 0) { c2 = Math.Sqrt(c2); } Vector T = (N * (refraction * c1 - c2) - V * refraction) * -1; T.Normalize(); return(new Ray(P, T)); // no refraction }
static Color GetNaturalColor(ISceneObject thing, Vector pos, Vector norm, Vector rd, Scene scene) { Color ret = Color.Black; foreach (Light light in scene.Lights) { Vector ldis = light.Pos - pos; Vector livec = ldis.Normalize(); double neatIsect = TestRay(new Ray { Refraction = 1, Start = pos, Dir = livec }, scene); bool isInShadow = !((neatIsect > ldis.GetLength()) || (neatIsect == 0)); if (!isInShadow) { double illum = livec.DotProduct(norm); Color lcolor = illum > 0 ? illum * light.Color : Color.Black; double specular = rd.Normalize().DotProduct(livec); Color scolor = specular > 0 ? Math.Pow(specular, thing.Surface.Roughness) * light.Color : Color.Black; var power = 4 / ldis.DotProduct(ldis); ret += power * (thing.Surface.Diffuse(pos) * lcolor + thing.Surface.Specular(pos) * scolor); } } return(ret); }
/// <summary> /// Render and create window with set pixels /// </summary> /// <returns>Rendered window</returns> public RenderWindow Render() { RenderWindow window = new RenderWindow(s.width, s.height); Point cameraPosition = GetCamera().location; float h = (float)(2 * Math.Tan((Math.PI / 180) * (GetCamera().fovy / 2))); float w = (h * width) / (height); Point S = cameraPosition + GetCamera().direction; //Get position of point S Point origin = S + (((0.5 * h) * GetCamera().up) + ((-0.5 * w) * GetCamera().right)); // Find 0,0 on canvas float dx = w / width; float dy = h / height; //for (int i = 0; i < height; i++) Parallel.For(0, height, i => //Cycle { if (ct.IsCancellationRequested) { return; } for (int j = 0; j < width; j++) //Cycle { if (ct.IsCancellationRequested) { return; } Intersection p; Color c; Point pixel = origin + j * dx * GetCamera().right - i * (dy * GetCamera().up); //Position of rendered pixel Vector direction = new Vector(pixel.X - cameraPosition.X, pixel.Y - cameraPosition.Y, pixel.Z - cameraPosition.Z); //Actual direction direction.Normalize(); Ray ray = new Ray(cameraPosition, direction); //Make ray p = null; for (int k = 0; k < renderedObjects.Count; k++) //For each object check if there is intersection { s.intersectionCalculationCount++; var intersection = renderedObjects[k].GetIntersection(ray); if (intersection != null) { intersection.indexOfCrossedObj = k; } if (p == null) { if (intersection != null && intersection.t >= 0.001) { p = intersection; } } else if (intersection != null) { if (p.t > intersection.t && intersection.t >= 0.001) { p = intersection; } } } if (p != null) { ray.p = p; ray.rayIntensity = 1; c = getColor(ray, 1); //Get color of given pixel } else { c = s.backgroundColor; } window.SetPixel(i, j, c); //Set color of given pixel } }); //} if (ct.IsCancellationRequested) { return(null); } return(window); }