示例#1
0
// InfiniteAreaLight Method Definitions
InfiniteAreaLight::InfiniteAreaLight(const Transform &LightToWorld,
                                     const Spectrum &L, int nSamples,
                                     const std::string &texmap)
    : Light((int)LightFlags::Infinite, LightToWorld, MediumInterface(),
            nSamples) {
    // Read texel data from _texmap_ and initialize _Lmap_
    Point2i resolution;
    std::unique_ptr<RGBSpectrum[]> texels(nullptr);
    if (texmap != "") {
        texels = ReadImage(texmap, &resolution);
        if (texels)
            for (int i = 0; i < resolution.x * resolution.y; ++i)
                texels[i] *= L.ToRGBSpectrum();
    }
    if (!texels) {
        resolution.x = resolution.y = 1;
        texels = std::unique_ptr<RGBSpectrum[]>(new RGBSpectrum[1]);
        texels[0] = L.ToRGBSpectrum();
    }
    Lmap.reset(new MIPMap<RGBSpectrum>(resolution, texels.get()));

    // Initialize sampling PDFs for infinite area light

    // Compute scalar-valued image _img_ from environment map
    int width = 2 * Lmap->Width(), height = 2 * Lmap->Height();
    std::unique_ptr<Float[]> img(new Float[width * height]);
    float fwidth = 0.5f / std::min(width, height);
    ParallelFor(
        [&](int64_t v) {
            Float vp = (v + .5f) / (Float)height;
            Float sinTheta = std::sin(Pi * (v + .5f) / height);
            for (int u = 0; u < width; ++u) {
                Float up = (u + .5f) / (Float)width;
                img[u + v * width] = Lmap->Lookup(Point2f(up, vp), fwidth).y();
                img[u + v * width] *= sinTheta;
            }
        },
        height, 32);

    // Compute sampling distributions for rows and columns of image
    distribution.reset(new Distribution2D(img.get(), width, height));
}
示例#2
0
// InfiniteAreaLight Method Definitions
InfiniteAreaLight::InfiniteAreaLight(const Transform &LightToWorld,
                                     const Spectrum &L, int nSamples,
                                     const std::string &texmap)
    : Light(LightFlags::Infinite, LightToWorld, nullptr, nSamples) {
    // Read texel data from _texmap_ and initialize _Lmap_
    Point2i resolution;
    std::unique_ptr<RGBSpectrum[]> texels(nullptr);
    if (texmap != "") {
        texels = ReadImage(texmap, &resolution);
        if (texels)
            for (int i = 0; i < resolution.x * resolution.y; ++i)
                texels[i] *= L.ToRGBSpectrum();
    }
    if (!texels) {
        resolution.x = resolution.y = 1;
        texels = std::unique_ptr<RGBSpectrum[]>(new RGBSpectrum[1]);
        texels[0] = L.ToRGBSpectrum();
    }
    Lmap.reset(new MIPMap<RGBSpectrum>(resolution, texels.get()));

    // Initialize sampling PDFs for infinite area light

    // Compute scalar-valued image _img_ from environment map
    int width = resolution.x, height = resolution.y;
    Float filter = (Float)1. / std::max(width, height);
    std::unique_ptr<Float[]> img(new Float[width * height]);
    for (int v = 0; v < height; ++v) {
        Float vp = (Float)v / (Float)height;
        Float sinTheta = std::sin(Pi * Float(v + .5f) / Float(height));
        for (int u = 0; u < width; ++u) {
            Float up = (Float)u / (Float)width;
            img[u + v * width] = Lmap->Lookup(Point2f(up, vp), filter).y();
            img[u + v * width] *= sinTheta;
        }
    }

    // Compute sampling distributions for rows and columns of image
    distribution.reset(new Distribution2D(img.get(), width, height));
}
示例#3
0
MedianCutEnvironmentLight::MedianCutEnvironmentLight(const Transform &light2world,
    const Spectrum &L, int ns_, const string &texmap)
  : Light(light2world, ns_), impl(new MedCutEnvImpl {nullptr, nullptr, ns_}) {
  int width = 0, height = 0;
  RGBSpectrum *texels = NULL;
  // Read texel data from _texmap_ into _texels_
  if (texmap != "") {
    texels = ReadImage(texmap, &width, &height);
    if (texels)
      for (int i = 0; i < width * height; ++i)
        texels[i] *= L.ToRGBSpectrum();
  }
  if (!texels) {
    width = height = 1;
    texels = new RGBSpectrum[1];
    texels[0] = L.ToRGBSpectrum();
  }
  impl->radianceMap = new MIPMap<RGBSpectrum>(width, height, texels);
  impl->width = width;
  impl->inv_w = 1.0f/(width-1);
  impl->height = height;
  impl->inv_h = 1.0f/(height-1);
  impl->createDistantLight = [this](const RGBSpectrum& s, float cy, float cx) {
    ParamSet p;

    float rgb[3];
    s.ToRGB(rgb);
    p.AddRGBSpectrum("L", rgb, 3);

    const float theta = impl->inv_h*cy * M_PI
              , phi   = impl->inv_w*cx * 2.f * M_PI;
    const float costheta = cosf(theta), sintheta = sinf(theta);
    const float sinphi = sinf(phi), cosphi = cosf(phi);
    const Point wi(-sintheta*cosphi, -sintheta*sinphi, -costheta);
    p.AddPoint(string("to"), &wi, 1);

#if DEBUG >= 1
fprintf(stderr, "rgb (%f,%f,%f)\n", rgb[0], rgb[1], rgb[2]);
#endif

    return CreateDistantLight(this->LightToWorld, p);
  };

  impl->solid_angle = ((2.f * M_PI) / (width - 1)) * (M_PI / (1.f * (height - 1)));

#if DEBUG >= 1
fprintf(stderr, "solid_angle = %f\n", impl->solid_angle);
#endif

  for (int y = 0; y < height; ++y) {
    float sinTheta = sinf(M_PI * float(y + 0.5f)/height);
    for (int x = 0; x < width; ++x)
      texels[y*width + x] *= impl->solid_angle * sinTheta;
  }

  // Initialize energy sum array; the array is shifted for (1,1)
  // i.e. (0,*) and (*,0) are inserted 0-boundaries
  fprintf(stderr, "[+] [%10.2f] Initializing sum array\n", clock()*1.0/CLOCKS_PER_SEC);

#if DEBUG >= 3
for (int y = 0; y < 5; ++y) {
  for (int x = 0; x < 5; ++x) {
    fprintf(stderr, "%.2f ", texels[y*width+x].y());
  }
  fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
#endif

  vector<vector<float>> acc(height+1, vector<float>(width+1));
  for (int y = 0; y < height; ++y)
    for (int x = 0; x < width; ++x)
      acc[y+1][x+1] = acc[y+1][x] + texels[y*width + x].y();

#if DEBUG >= 3
for (int y = 0; y < 5; ++y) {
  for (int x = 0; x < 5; ++x) {
    fprintf(stderr, "%.2f ", acc[y][x]);
  }
  fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
#endif

   for (int x = 1; x <= width; ++x)
    for (int y = 1; y <= height; ++y)
      acc[y][x] += acc[y-1][x];

#if DEBUG >= 3
for (int y = 0; y < 5; ++y) {
  for (int x = 0; x < 5; ++x) {
    fprintf(stderr, "%.2f ", acc[y][x]);
  }
  fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
#endif

 
  // initialize median cut
  printf("[+] [%10.2f] Calculating median cut\n", clock()*1.0/CLOCKS_PER_SEC);
  subdivide(this->impl, 1, texels, acc, 0, 0, width-1, height-1);
  printf("[+] [%10.2f] Done with %d lights\n", clock()*1.0/CLOCKS_PER_SEC, static_cast<int>(impl->ls.size()));

  delete[] texels;

  // Initialize sampling PDFs for environment area light
  // Compute scalar-valued image _img_ from environment map
  float filter = 1.f / max(width, height);
  float *img = new float[width*height];
  for (int v = 0; v < height; ++v) {
    float vp = (float)v / (float)height;
    float sinTheta = sinf(M_PI * float(v+.5f)/float(height));
    for (int u = 0; u < width; ++u) {
      float up = (float)u / (float)width;
      img[u+v*width] = impl->radianceMap->Lookup(up, vp, filter).y();
      img[u+v*width] *= sinTheta;
    }
  }

  // Compute sampling impl->distributions for rows and columns of image
  impl->distribution = new Distribution2D(img, width, height);
  delete[] img;
}