private double[] IntersectRaySphere(DoublePoint3D cameraPosition, DoublePoint3D viewVector, Sphere sphere) { var oc = cameraPosition - sphere.Center; //vector from camera to sphere center var a = viewVector.ScalMultiply(viewVector); //viewVector length var b = 2 * oc.ScalMultiply(viewVector); var c = oc.ScalMultiply(oc) - sphere.Radius * sphere.Radius; var discriminant = b * b - 4 * a * c; if (discriminant < 0) { return new double[] { Inf, Inf } } ; var root1 = (-b + Math.Sqrt(discriminant)) / (2 * a); var root2 = (-b - Math.Sqrt(discriminant)) / (2 * a); return(new double[] { root1, root2 }); }
private DoublePoint3D ReflectRay(DoublePoint3D fallingVector, DoublePoint3D normalVector) { return(2 * normalVector * normalVector.ScalMultiply(fallingVector) - fallingVector); }
private float ComputeLightning(DoublePoint3D intersectPoint, DoublePoint3D normalVector, DoublePoint3D vector, int specular) { var result = 0f; var interval = new double[] { 0.001, Inf }; foreach (LightSource light in LightSources) { if (light.ToString().Contains("Ambient")) { result += light.Intense; } else { DoublePoint3D lightVector; if (light.ToString().Contains("Point")) { lightVector = (light as PointLight).Coord - intersectPoint; } else { lightVector = (light as DirectLight).Vector; } //Shadows Closest shadow = ClosestIntersection(intersectPoint, lightVector, interval); float transparency = 1; while (shadow.Object != -1) { if ((GraphicalObjects[shadow.Object].Transparency == 0) || (transparency == 0)) { transparency = 0; break; } transparency *= GraphicalObjects[shadow.Object].Transparency; shadow = ClosestIntersection(intersectPoint + shadow.Point * lightVector, lightVector, interval); } if (transparency == 0) { continue; } //Diffusal Illumination var scal = normalVector.ScalMultiply(lightVector); if (scal > 0) { result += (float)(light.Intense * scal / (normalVector.Length() * lightVector.Length())); } //Specular Illumination if (specular != -1) { var refleclectedVector = ReflectRay(lightVector, normalVector); scal = refleclectedVector.ScalMultiply(vector); if (scal > 0) { result += (float)(transparency * (light.Intense * Math.Pow(scal / (refleclectedVector.Length() * vector.Length()), specular))); } } } } return(result); }