Пример #1
0
  private MyRay shootPixelRay(int x, int y) {
    MyRay out = new MyRay();

    float xPart, yPart;
    xPart = (rightViewPlane - leftViewPlane) / widthPix;
    yPart = (topViewPlane - bottomViewPlane) / heightPix;

    xPart = leftViewPlane + (float) 0.5 * xPart + ((float) x) * xPart;
    yPart = bottomViewPlane + (float) 0.5 * yPart + ((float) y) * yPart;

    // get ray direction and origin: perspective
    // out.setOrigin(viewer);
    // MyPoint3D dir = new MyPoint3D(xPart - viewer.getX(), yPart - viewer.getY(), zViewPlane -
    // viewer.getZ());

    // get ray direction and origin: perpendicular
    out.setOrigin(new MyPoint3D(xPart, yPart, viewer.getZ()));
    MyPoint3D dir = new MyPoint3D(0, 0, 1);

    // normalize
    dir.normalize();
    out.setDirection(dir);
    return out;
  }
Пример #2
0
  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;
  }