public static Color3 diffuse(Hit h, Shape s, Light bulb) { Color3 diffuse = Black; Vector3 normal = s.calcNormal(h); Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect); double diffuseDot = Vector3.DotProduct(lightDir, normal); if (diffuseDot >= 0) { diffuse = (bulb.Color * s.Material.Diffuse) * diffuseDot; } return(diffuse); }
public static Color3 specular(Ray r, Hit h, Shape s, Light bulb) { Color3 specular = Black; Vector3 normal = s.calcNormal(h); Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect); Vector3 refDir = lightDir - (2 * (Vector3.DotProduct(lightDir, normal) / Math.Pow(normal.Abs(), 2)) * normal); double specularDot = Vector3.DotProduct(r.direction, refDir); if (specularDot >= 0) { specular = (bulb.Color * s.Material.Specular) * Math.Pow(specularDot, s.Material.Ke); } return(specular); }
private static Color3 fireRay(Ray incomingRay, int depth, Shape fromShape) { double closest = Constants.FAR_AWAY; Color3 retColor = Constants.BGCOLOR; int whichObject = 0, hitObject = 0; Hit finalHit = new Hit(); foreach (Shape s in layout.Shapes) { Hit rayHit = s.intersect(incomingRay); whichObject++; if (rayHit.intersect.z == Constants.FAR_AWAY) { continue; } double dist = Point3.distance(layout.Cam.Eye, rayHit.intersect); if (dist < closest && !s.Equals(fromShape)) { closest = dist; hitObject = whichObject; finalHit = rayHit; } } if (hitObject <= 0) { return(Constants.BGCOLOR); } Shape hitShape = layout.Shapes[hitObject - 1]; retColor = Color3.ambient(hitShape); // phongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphong Color3 diffuseColor = Color3.Black, specularColor = Color3.Black; foreach (Light bulb in layout.Lights) { if (spawnShadow(bulb, finalHit, hitShape, fromShape)) { retColor = hitShape.colorShadow(retColor, finalHit, layout.Lights.Count * 3); } else { if (hitShape is Plane) { retColor = hitShape.colorNormal(retColor, incomingRay, finalHit, hitShape, bulb); } else { diffuseColor += Color3.diffuse(finalHit, hitShape, bulb); specularColor += Color3.specular(incomingRay, finalHit, hitShape, bulb); } } } if (hitShape is Sphere) { retColor += diffuseColor * hitShape.Material.Kd; retColor += specularColor * hitShape.Material.Ks; } if (depth < Constants.MAX_DEPTH) { Color3 reflectColor = Color3.Black; if (hitShape.Material.Kr > 0) { Ray reflectRay = new Ray(); reflectRay.start = finalHit.intersect; Vector3 normalVec = hitShape.calcNormal(finalHit); double c = -Vector3.DotProduct(normalVec, incomingRay.direction); reflectRay.direction = -(incomingRay.direction + (2 * normalVec * c)); reflectRay.direction.Normalize(); reflectColor = fireRay(reflectRay, depth + 1, hitShape); retColor += reflectColor * hitShape.Material.Kr; } if (hitShape.Material.Kt > 0) { Ray transRay = new Ray(); double indexRefract; Vector3 normalVec = Vector3.FaceForward(hitShape.calcNormal(finalHit), -incomingRay.direction); if (Vector3.DotProduct(-incomingRay.direction, hitShape.calcNormal(finalHit)) < 0) { indexRefract = Constants.REFRACTION_INDEX_SPHERE / Constants.REFRACTION_INDEX_AIR; } else { indexRefract = Constants.REFRACTION_INDEX_AIR / Constants.REFRACTION_INDEX_SPHERE; } double discrim = 1 + (Math.Pow(indexRefract, 2) * (Math.Pow(Vector3.DotProduct(-incomingRay.direction, normalVec), 2) - 1)); // Total internal reflection! if (discrim < 0) { retColor += reflectColor * hitShape.Material.Kt; } else { discrim = indexRefract * Vector3.DotProduct(-incomingRay.direction, normalVec) - Math.Sqrt(discrim); transRay.direction = (indexRefract * incomingRay.direction) + (discrim * normalVec); transRay.start = finalHit.intersect; Color3 transColor = fireRay(transRay, depth + 1, hitShape); retColor += transColor * hitShape.Material.Kt; } } } return(retColor); }
public static Color3 specular(Ray r, Hit h, Shape s, Light bulb) { Color3 specular = Black; Vector3 normal = s.calcNormal(h); Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect); Vector3 refDir = lightDir - (2 * (Vector3.DotProduct(lightDir, normal) / Math.Pow(normal.Abs(), 2)) * normal); double specularDot = Vector3.DotProduct(r.direction, refDir); if (specularDot >= 0) specular = (bulb.Color * s.Material.Specular) * Math.Pow(specularDot, s.Material.Ke); return specular; }
public static Color3 diffuse(Hit h, Shape s, Light bulb) { Color3 diffuse = Black; Vector3 normal = s.calcNormal(h); Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect); double diffuseDot = Vector3.DotProduct(lightDir, normal); if (diffuseDot >= 0) diffuse = (bulb.Color * s.Material.Diffuse) * diffuseDot; return diffuse; }