private MyColor traceRay(MyRay ray, int recursionLevel) { // MyColor color = MyColor.BLACK; MyColor color = new MyColor(0, 0, 0); float maxDist = Float.POSITIVE_INFINITY; if (recursionLevel > 10) { System.out.println("recursion limit reached"); return color; } // check each object for intersections // --> get the one with shortest distance MyShape currentShape = null; for (MyShape shape : objects) { CalcTuple resultTuple = shape.rayIntersect(ray); float hitDist = resultTuple.getClosestIntersection(); if (hitDist > zViewPlane - viewer.getZ() && maxDist > hitDist) { maxDist = hitDist; currentShape = shape; } } MyPoint3D intersection; MyPoint3D normal; // set pixel in buffer if (maxDist < Float.POSITIVE_INFINITY) { // we got an intersection // -> check for light source // shoot from intersection point in points surface normal direction intersection = ray.getOrigin().add(ray.getDirection().mul(maxDist)); normal = currentShape.getNormal(intersection); // --------- REFLECTED LIGHT ------------ // float specularLight = getReflection(ray,intersection,normal,currentShape); // Rref = Rin - 2*N(Rin*N) MyPoint3D reflectedDir = ray.getDirection().sub(normal.mul(2).mul(ray.getDirection().dotProduct(normal))); // shoot reflected ray MyRay reflectedRay = shootRay(intersection, reflectedDir); MyColor reflectedColor = traceRay(reflectedRay, recursionLevel + 1); color = color.add( new MyColor( (int) (reflectedColor.getRed() * currentShape.getMaterial().getSpecularC()), (int) (reflectedColor.getGreen() * currentShape.getMaterial().getSpecularC()), (int) (reflectedColor.getBlue() * currentShape.getMaterial().getSpecularC()))); // --------- AMBIENT LIGHT -------------- // get ambient light component float ambientLight = getAmbientComponent(currentShape); color = color.add( new MyColor( (int) (currentShape.getMaterial().getColor().getRed() * ambientLight), (int) (currentShape.getMaterial().getColor().getGreen() * ambientLight), (int) (currentShape.getMaterial().getColor().getBlue() * ambientLight))); // ---- DIFFUSED LIGHT -------- // float diffLight = 0; for (LightSource source : lights) { // check if normal points towards light source if (source.intersects(currentShape.getNormal(intersection))) { // now we shoot a ray from the intersection point and see // if any other object is in our way --> shadowed? MyRay ray2 = shootRay(intersection, source.getOrigin().sub(intersection)); boolean isShadowed = false; for (MyShape shape : objects) { CalcTuple resultTuple = shape.rayIntersect(ray2); if (shape != currentShape) { // check if we got an intersection if (resultTuple.getRoots() > 0) { isShadowed = true; break; } } // check if our own body blocks else { if (resultTuple.getRoots() > 1) { isShadowed = true; break; } } } // in case we are not shadowed -> calculate new light if (!isShadowed) { // get diffused light component // diffLight += getDiffuseComponent(source, normal, intersection, currentShape); // TODO: hier fehlt noch irgendnen specular coeff bestimmt :) // float diff = getDiffuseComponent(source, normal, intersection, currentShape ); MyPoint3D dir = source.getOrigin().sub(intersection); float diff = (float) currentShape.getMaterial().getDiffuseC() * dir.dotProduct(normal) / (float) (Math.sqrt(dir.dotProduct(dir)) * Math.sqrt(normal.dotProduct(normal))); if (diff > 1) { // System.out.println("diff"); diff = 1; } if (diff > 0) { // color = color.add( source.getColor().dim(diff) ); color = color.add(currentShape.getMaterial().getColor().mix(source.getColor()).dim(diff)); } else { // color = color.sub( source.getColor().dim(-diff) ); } } } } } // end if shape hit return color; }
private float getAmbientComponent(MyShape shape) { // TODO: maybe improve return shape.getMaterial().getAmbientC(); }