Example #1
0
  /**
   * Computes the colour of the pixel at (x,y) where each coordinate is defined to be in the range
   * (-0.5, +0.5).
   *
   * @param x The x-coordinate, between -0.5 and +0.5.
   * @param y The y-coordinate, between -0.5 and +0.5.
   * @return The colour at the given pixel.
   */
  private Colour getPixelColour(double x, double y) {
    Colour c = Colour.pool.borrow().reset(Colour.TRANSPARENT);

    Vector3 ray = Vector3.pool.borrow().reset(x, -y, 1.0);
    ray.normalize();

    Vector3 intersection = raytrace(ray);
    if (intersection != null) {
      // we intersected with the planet. Now we need to work out the colour at this point
      // on the planet.
      Colour t = queryTexture(intersection);
      double intensity = lightSphere(intersection);
      c.reset(1.0, t.r * intensity, t.g * intensity, t.b * intensity);
      Colour.pool.release(t);

      if (mAtmospheres != null) {
        Vector3 surfaceNormal = Vector3.pool.borrow().reset(intersection);
        surfaceNormal.subtract(mPlanetOrigin);
        surfaceNormal.normalize();

        Vector3 sunDirection = Vector3.pool.borrow().reset(mSunOrigin);
        sunDirection.subtract(intersection);
        sunDirection.normalize();

        final int numAtmospheres = mAtmospheres.size();
        for (int i = 0; i < numAtmospheres; i++) {
          final Atmosphere atmosphere = mAtmospheres.get(i);
          Colour atmosphereColour =
              atmosphere.getInnerPixelColour(
                  x + 0.5, y + 0.5, intersection, surfaceNormal, sunDirection);
          Colour.blend(c, atmosphereColour);
          Colour.pool.release(atmosphereColour);
        }

        Vector3.pool.release(surfaceNormal);
        Vector3.pool.release(sunDirection);
      }
    } else if (mAtmospheres != null) {
      // if we're rendering an atmosphere, we need to work out the distance of this ray
      // to the planet's surface
      double u = Vector3.dot(mPlanetOrigin, ray);
      Vector3 closest = Vector3.pool.borrow().reset(ray);
      closest.scale(u);

      double distance = (Vector3.distanceBetween(closest, mPlanetOrigin) - mPlanetRadius);

      Vector3 surfaceNormal = Vector3.pool.borrow().reset(closest);
      surfaceNormal.subtract(mPlanetOrigin);
      surfaceNormal.normalize();

      Vector3 sunDirection = Vector3.pool.borrow().reset(mSunOrigin);
      sunDirection.subtract(closest);
      sunDirection.normalize();

      final int numAtmospheres = mAtmospheres.size();
      for (int i = 0; i < numAtmospheres; i++) {
        final Atmosphere atmosphere = mAtmospheres.get(i);
        Colour atmosphereColour =
            atmosphere.getOuterPixelColour(x + 0.5, y + 0.5, surfaceNormal, distance, sunDirection);
        Colour.blend(c, atmosphereColour);
        Colour.pool.release(atmosphereColour);
      }

      Vector3.pool.release(closest);
      Vector3.pool.release(surfaceNormal);
      Vector3.pool.release(sunDirection);
    }

    Vector3.pool.release(ray);
    Vector3.pool.release(intersection);
    return c;
  }