예제 #1
0
  @Override
  public Spectrum shade(HitRecord hit, Light light) {
    Spectrum spectrum = new Spectrum(0.f, 0.f, 0.f);
    Vector3f hitPoint = hit.getIntersectionPoint();
    Vector3f normal = hit.getNormal();
    normal.normalize();
    Spectrum cl = light.getCl(hitPoint);
    Vector3f L = light.getL(hitPoint);

    Vector3f rayDir = hit.getRayDir();
    rayDir.normalize();

    // Diffuse reflectance term
    float nDotL = normal.dot(L);
    if (nDotL >= 0) {
      spectrum.append(cl.multipliedBy(diffuse).multipliedBy(nDotL));

      // Specular reflectance term
      Vector3f h = new Vector3f(L);
      h.sub(rayDir);
      h.normalize();
      float hDotN = (float) Math.pow(h.dot(normal), shininess);
      spectrum.append(specular.multipliedBy(cl).multipliedBy(hDotN));
    }
    // Ambient reflectance term
    cl = light.getCl(hitPoint);
    Spectrum amb = ambient.multipliedBy(cl);
    spectrum.append(amb);

    spectrum.clampMax(1.f);
    spectrum.clampMin(0.f);

    return spectrum;
  }
    // Display checker board background
    MaterialCell checkerBackgroundHit(Ray r, HitRecord hit) {
      // Find the t value where z = scene.camera.far
      hit.t = -scene.camera.far / r.dir.z;
      if (hit.t < 0) // Only put it on the background, not behind the camera too
      return black;

      hit.hitP = r.pointAtParameter(hit.t);
      hit.normal = new Double3D(0, 0, 1);
      hit.hitP.x = (hit.hitP.x > 0) ? hit.hitP.x : -hit.hitP.x + checkerFreq / 2;
      hit.hitP.y = (hit.hitP.y > 0) ? hit.hitP.y : -hit.hitP.y + checkerFreq / 2;

      if (hit.hitP.x % checkerFreq < checkerFreq / 2) // && p.x < scene.camera.windowRight)
      if (hit.hitP.y % checkerFreq < checkerFreq / 2) // && p.y < scene.camera.windowTop)
        return white;
        else return black;
      else if (hit.hitP.y % checkerFreq < checkerFreq / 2) // && p.y < scene.camera.windowTop)
      return black;
      else return white;
    }
    // All rays we deal with here are in world coordinates.
    // Should take the refractive index of the material it is currently in.
    DoubleColor trace(Ray ray) {
      DoubleColor color = new DoubleColor(0.0, 0.0, 0.0, 1.0);
      HitRecord hit = new HitRecord();

      if (depth > Math.max(DEBUG_recursion, scene.maxRecursiveDepth)) return color;

      double tMin = 0.0001;
      double tMax = 10000000;

      // Spheres only for now
      for (int i = 0; i < numObjects; i++)
        // Did I hit the bounding sphere for an object?
        if (spheres[i].hit(ray, tMin, tMax, 0, hit))
          if (scene.spheresOnly) {
            for (PMesh.SurfCell s = shapes[i].surfHead; s != null; s = s.next)
              for (PMesh.PolyCell poly = s.polyHead; poly != null; poly = poly.next)
                // Triangles only for now
                if (poly.numVerts == 3) {
                  Double3D v[] = new Double3D[3];
                  int j = 0;
                  for (PMesh.VertListCell vert = poly.vert; vert != null; vert = vert.next)
                    v[j++] = shapes[i].vertArray.get(vert.vert).viewPos;
                  // Increment j in the line post access

                  // Check for a hit on this polygon
                  if (Triangle.hit(v[0], v[1], v[2], ray, tMin, tMax, 0, hit)) {
                    tMax = hit.t;

                    hit.normal = poly.viewNorm;
                    hit.matIndex = s.material;
                    hit.index = i;
                  }
                } else
                  System.out.println(
                      "Need to intersect polygon with " + poly.numVerts + " vertices.");
          } else {
            tMax = hit.t;
            hit.matIndex = i; // May cause an error if object 10 and it only has 3 materials.
            hit.index = i;
          }

      if (hit.index >= 0) // If it intersects then multi-sample
      {
        if (!sampled && depth == 0) {
          // Only sample once per ray from the main loop
          sampled = true;

          Double3D dir = ray.dir;
          DoubleColor antiAlias = trace(ray);

          for (int i = 0; i < samples; i++) {
            // Double3D sample = new Double3D(dir.x + imageSamples[i].x, dir.y + imageSamples[i].y,
            // dir.z).getUnit();
            // ray.dir = sample;
            ray.dir.x = dir.x + imageSamples[i].x;
            ray.dir.y = dir.y + imageSamples[i].y;

            antiAlias.plus(trace(ray));
          }
          antiAlias.scale(1.0 / (samples + 1.0));

          color.plus(antiAlias);
        } else if (hit.matIndex < shapes[hit.index].materials.length)
          color = shade(ray, hit, shapes[hit.index].materials[hit.matIndex], false);
        else
          color =
              shade(
                  ray,
                  hit,
                  shapes[hit.index].materials[shapes[hit.index].materials.length - 1],
                  false);
      } else // We hit nothing check for intersection with the far clip plane for checker board
      // pattern.
      if (scene.checkerBackground) color = shade(ray, hit, checkerBackgroundHit(ray, hit), true);

      return color;
    }