/// <summary> /// Get color of floor /// </summary> /// <param name="b">point of interrest</param> /// <returns>color</returns> public override Color GetColor(Point b) { if (M == 0 && N == 0) { return(color); } double x /* = (a.X - b.X) / (c.X - a.X)*/; double y /* = (c.Z - b.Z) / (c.Z - a.Z)*/; Vector pr = new Vector(b.X - d.X, b.Y - d.Y, b.Z - d.Z); x = Vector.DotProduct(p, pr) / Vector.DotProduct(p, p); y = Vector.DotProduct(q, pr) / Vector.DotProduct(q, q); int xx = Convert.ToInt16(((Math.Floor(x * 100 / (100 / M))) + (Math.Floor(y * 100 / (100 / N)))) % 2); //1 or 0 for black and white //xx = Convert.ToInt16((x * M + y * N) % 2); // Makes stripes :] ... Happy accident if (xx == 0) { return(color1); } else { return(color2); } }
/// <summary> /// Initialize intersection object /// </summary> /// <param name="ray">Ray</param> /// <param name="t">Parameter t</param> /// <param name="t2">Parameter t2</param> /// <returns>Intersection object</returns> private Intersection InitializeIntersection(Ray ray, float t, float t2) { Intersection p = new Intersection(); p.color = color; p.t = t; p.t2 = t2; p.pointOfIntersection = new Point(ray.startPoint.X + t * ray.direction.x, ray.startPoint.Y + t * ray.direction.y, ray.startPoint.Z + t * ray.direction.z); p.normal = new Vector((2 * (p.pointOfIntersection.X - x)) / (a * a), (2 * (p.pointOfIntersection.Y - y)) / (b * b), (2 * (p.pointOfIntersection.Z - z)) / (c * c)); if (Vector.DotProduct(ray.direction, p.normal) > 0) { p.normal = (-1) * p.normal; } p.pointOfIntersection2 = new Point(ray.startPoint.X + t2 * ray.direction.x, ray.startPoint.Y + t2 * ray.direction.y, ray.startPoint.Z + t2 * ray.direction.z); p.normalEnd = new Vector((2 * (p.pointOfIntersection2.X - x)) / (a * a), (2 * (p.pointOfIntersection2.Y - y)) / (b * b), (2 * (p.pointOfIntersection2.Z - z)) / (c * c)); if (Vector.DotProduct(ray.direction, p.normalEnd) > 0) { p.normalEnd = (-1) * p.normalEnd; } p.kd = kd; p.ks = ks; p.kt = kt; p.ray = ray; return(p); }
/// <summary> /// Initialize intersection /// </summary> /// <param name="ray">ray</param> /// <param name="t">t</param> /// <param name="t2">t2</param> /// <returns>Intersection object</returns> private Intersection inicializujPrusecik(Ray ray, float t, float t2) { Intersection p = new Intersection(); p.color = color; p.t = t; p.t2 = t2; p.pointOfIntersection = new Point(ray.startPoint.X + t * ray.direction.x, ray.startPoint.Y + t * ray.direction.y, ray.startPoint.Z + t * ray.direction.z); //Vypocte pozici pruseciku p.normal = new Vector(2 * (p.pointOfIntersection.X - xPos), 2 * (p.pointOfIntersection.Y - yPos), 2 * (p.pointOfIntersection.Z - zPos)); if (Vector.DotProduct(ray.direction, p.normal) > 0) { p.normal = (-1) * p.normal; } p.pointOfIntersection2 = new Point(ray.startPoint.X + t2 * ray.direction.x, ray.startPoint.Y + t2 * ray.direction.y, ray.startPoint.Z + t2 * ray.direction.z); p.normalEnd = new Vector(2 * (p.pointOfIntersection2.X - xPos), 2 * (p.pointOfIntersection2.Y - yPos), 2 * (p.pointOfIntersection2.Z - zPos)); if (Vector.DotProduct(ray.direction, p.normalEnd) > 0) { p.normalEnd = (-1) * p.normalEnd; } p.kd = kd; p.ks = ks; p.kt = kt; p.n2 = ktrefraction; p.ray = ray; return(p); }
/// <summary> /// Calculate the constant by which we multiply the color /// </summary> /// <param name="ray2">Ray towards the light</param> /// <param name="normalInIntersection">normal in intersection</param> /// <returns></returns> private static float phong_D(Ray ray2, Vector normalInIntersection) { Vector direction = new Vector(ray2.direction); direction.Normalize(); Vector copyN = new Vector(normalInIntersection); copyN.Normalize(); return(Vector.DotProduct(direction, copyN)); }
public override bool Intersect(Ray r, ref float dist) { //Check if the ray hits the plane //for the ray //f(t) = ro + t * rd // ro is ray orgin // rd is ray direction // where t is marching down the ray dir from the orgin //N(ro + t * rd) + d = 0; float Denom = norm.DotProduct(r.dir); if ((Denom < -Config.Tolerance) || (Denom > Config.Tolerance)) { dist = (-d - norm.DotProduct(r.orgin)) / Denom; return(true); } return(false); }
public override bool Intersect(Ray ray, ref float dist) { //The sphere normal this is used when bouncing. //Vector normal = (ray.orgin - pos).Normalize(); //move everything relitve to the sphere Vector LocalSphereRayOrgin = ray.orgin - pos; float a = ray.dir.DotProduct(ray.dir); float b = 2.0f * ray.dir.DotProduct(LocalSphereRayOrgin); //float c = ray.orgin.DotProduct(LocalSphereRayOrgin) - r * r; float c = LocalSphereRayOrgin.DotProduct(LocalSphereRayOrgin) - r * r; float Denom = 2.0f * a; float RootTerm = (float)Math.Sqrt(b * b - 4.00f * a * c); float d = (b * b - 4.00f * a * c); if (d < Config.MinHitDistance) { return(false); } if (RootTerm > Config.Tolerance) { float tp = (-b + RootTerm) / Denom; float tn = (-b - RootTerm) / Denom; if (tp == 0 || tn == 0) { dist = 0; return(false); } float t = tp; if (tn > Config.MinHitDistance && tn < tp) { t = tn; dist = t; return(true); } else if (tp > Config.MinHitDistance) { dist = t; return(true); } return(false); } return(false); }
/// <summary> /// Find out if there is a intersection, if so return it /// </summary> /// <param name="ray">Ray</param> /// <returns>intersection</returns> public override Intersection GetIntersection(Ray ray) { Intersection pr = new Intersection(); Vector normalOfFloor = normal; float nDir = Vector.DotProduct(normalOfFloor, ray.direction); if (Math.Abs(nDir) < 0.001) { return(null); } else { float nA = ((normalOfFloor.x * ray.startPoint.X) + (normalOfFloor.y * ray.startPoint.Y) + (normalOfFloor.z * ray.startPoint.Z)); float t = -((nA + koefD) / nDir); if (t > 0.001) { Point intersection = new Point(ray.startPoint.X + t * ray.direction.x, ray.startPoint.Y + t * ray.direction.y, ray.startPoint.Z + t * ray.direction.z); Vector b = new Vector(intersection.X - d.X, intersection.Y - d.Y, intersection.Z - d.Z); float L = ((p.x / p.Magnitude() * b.x) + (p.y / p.Magnitude() * b.y) + (p.z / p.Magnitude() * b.z)); float g = ((q.x / q.Magnitude() * b.x) + (q.y / q.Magnitude() * b.y) + (q.z / q.Magnitude() * b.z)); float S = L / p.Magnitude(); float S1 = g / q.Magnitude(); if (S <= 1 && S >= 0 && S1 <= 1 && S1 >= 0) { pr = InitializeIntersection(ray, t, intersection); } else { return(null); } } else { return(null); } } return(pr); }
/// <summary> /// Gets intersection with this object if it exists /// </summary> /// <param name="ray">Ray</param> /// <returns>Intersection if exists, null otherwise</returns> public override Intersection GetIntersection(Ray ray) { Intersection p = null; ray.direction.Normalize(); float t1 = -1; float t2 = -1; float pom = -1; Vector v = new Vector(ray.startPoint.X - xPos, ray.startPoint.Y - yPos, ray.startPoint.Z - zPos); float multVD = 2 * Vector.DotProduct(v, ray.direction); if ((multVD * multVD - 4 * (Vector.DotProduct(v, v) - diameter * diameter) > 0)) { float square = (float)Math.Sqrt(multVD * multVD - 4 * (Vector.DotProduct(v, v) - diameter * diameter)); t1 = (-multVD + square) / 2; t2 = (-multVD - square) / 2; if (t2 > 0 && t1 > 0 && t1 > t2) { pom = t1; t1 = t2; t2 = pom; } if (t1 > 0.001) { p = inicializujPrusecik(ray, t1, t2); } else if (t2 > 0.001) { p = inicializujPrusecik(ray, t2, t1); } else { return(null); } } else { return(null); } return(p); }
public override bool Intersect(Ray r, ref float dist) { Vector norm = SurfaceFunc.CalculateSurfaceNormal(m_pos); norm.m_y = -norm.m_y; float facing = norm.DotProduct(r.orgin); if (facing <= Config.Tolerance && facing >= Config.MinTolerance) { //normal = norm; //closest = quad; dist = (float)SurfaceFunc.Vec3Distance(r.orgin, norm); if (dist < Config.MinHitDistance) { return(false); } return(true); } return(false); }
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> /// Get color of given pixel /// </summary> /// <param name="ray">Ray (that we 'shoot' with)</param> /// <param name="generation">generation</param> /// <returns>Pixel color</returns> private Color getColor(Ray ray, int generation) { Color c = new Color(); Intersection p = ray.p; if (generation < s.maxDepth && ray.rayIntensity > s.minIntensity) { float Id = 0; float Is = 0; c = renderedObjects[p.indexOfCrossedObj].GetColor(p.pointOfIntersection); Ray ray2 = new Ray(p.pointOfIntersection, new Vector(s.light.xPos - (p.pointOfIntersection.X), s.light.yPos - (p.pointOfIntersection.Y), s.light.zPos - (p.pointOfIntersection.Z))); // Paprsek z pruseciku do svetla ray2.direction.Normalize(); Intersection swadowIntersection = null; if (!isShadow(p.indexOfCrossedObj, ray2, renderedObjects, out swadowIntersection)) // If object is not in shadow calculates its shaded color { Id = phong_D(ray2, p.normal); if (Id < Ia) { Id = Ia; } else if (Id > 1) { Id = 1; } } else { Id = Ia * (1 + swadowIntersection.kt); // The more transpanet the object is the more lighter the shadow will be } Vector bounce = bounceVector(p); //Directional vector of the ray that will bounce if (generation == 1) { float koef = Vector.DotProduct(ray2.direction, bounce); if (koef < 0) { koef *= -1; } else { koef = 0; } Is = (float)Math.Pow(koef, power); //Shine part } Color reflected = new Color(0, 0, 0); Ray reflectionRay = new Ray(p.pointOfIntersection, -1 * bounce); reflectionRay.direction.Normalize(); if (p.ks != 0) //Calculation for mirror part { Intersection pr = GetIntersection(reflectionRay); if (pr != null) { reflectionRay.refractionIndex = renderedObjects[pr.indexOfCrossedObj].ktrefraction; reflectionRay.p = pr; reflectionRay.rayIntensity = ray.rayIntensity * p.ks; reflected = getColor(reflectionRay, generation + 1); } else { reflected = s.backgroundColor; } } Color refracted = new Color(0, 0, 0); if (p.kt != 0) //Calculation for refraction. { ray.isIn = p.isIn; p.normal.Normalize(); p.normalEnd.Normalize(); p.n1 = 1; p.n2 = 1f; Vector t; float cos1; float cos2; if (!ray.isIn) //Check if the ray is in objecy { p.n1 = 1; p.n2 = renderedObjects[p.indexOfCrossedObj].ktrefraction; cos1 = -Vector.DotProduct(p.normal, ray.direction); } else { p.n1 = renderedObjects[p.indexOfCrossedObj].ktrefraction; p.n2 = 1; cos1 = -Vector.DotProduct(-1 * p.normal, ray.direction); } cos2 = (float)Math.Sqrt(1 - (p.n1 / p.n2) * (p.n1 / p.n2) * (1 - cos1 * cos1)); t = (p.n1 / p.n2) * ray.direction + ((p.n1 * cos1) / p.n2 - cos2) * (p.normal); Ray refractedRay = new Ray(p.pointOfIntersection, t); refractedRay.direction.Normalize(); refractedRay.p = GetIntersection(refractedRay); if (refractedRay.p != null) { refractedRay.p.normal.Normalize(); refractedRay.p.normalEnd.Normalize(); refractedRay.rayIntensity = ray.rayIntensity * p.kt; refracted = getColor(refractedRay, generation + 1); } else { refracted = s.backgroundColor; } } if (generation == 1) { c = ray.rayIntensity * ((p.kd * Id + Is) * c + p.ks * reflected + p.kt * refracted); // Calculation for first generation } else { c = ray.rayIntensity * ((2f * p.kd * Id) * c + p.ks * reflected + p.kt * refracted); // Calculation for second, third... not accounting the shiny component and lighten the diffuse component 2x } //Normalize the color. if (c.r > 1) { c.r = 1; } if (c.g > 1) { c.g = 1; } if (c.b > 1) { c.b = 1; } if (c.r < 0) { c.r = 0; } if (c.g < 0) { c.g = 0; } if (c.b < 0) { c.b = 0; } } return(c); }
static public Vector Reflect(Vector dir, Vector normal) { Vector bounce = dir - 2.0f * (dir.DotProduct(normal) * normal); return(bounce); }