// ImageIO Function Definitions std::unique_ptr<RGBSpectrum[]> ReadImage(const std::string &name, Point2i *resolution) { if (name.size() >= 5) { size_t suffixOffset = name.size() - 4; if (!strcmp(name.c_str() + suffixOffset, ".exr") || !strcmp(name.c_str() + suffixOffset, ".EXR")) return std::unique_ptr<RGBSpectrum[]>( ReadImageEXR(name, &resolution->x, &resolution->y)); if (!strcmp(name.c_str() + suffixOffset, ".tga") || !strcmp(name.c_str() + suffixOffset, ".TGA")) return std::unique_ptr<RGBSpectrum[]>( ReadImageTGA(name, &resolution->x, &resolution->y)); if (!strcmp(name.c_str() + suffixOffset, ".pfm") || !strcmp(name.c_str() + suffixOffset, ".PFM")) return std::unique_ptr<RGBSpectrum[]>( ReadImagePFM(name, &resolution->x, &resolution->y)); } Error( "Unable to load image stored in format \"%s\" for filename \"%s\". " "Returning a constant grey image instead.", strrchr(name.c_str(), '.') ? (strrchr(name.c_str(), '.') + 1) : "(unknown)", name.c_str()); RGBSpectrum *ret = new RGBSpectrum[1]; ret[0] = RGBSpectrum(0.5f); resolution->x = resolution->y = 1; return std::unique_ptr<RGBSpectrum[]>(ret); }
RGBSpectrum BlockedRenderer::LightSampling( const Scene::ConstLightIterator &light, const Point2 &lightSample, const Intersection &isect, const Vector &wo, Vector *wi, float *pdf) const { Ray shadowRay; RGBSpectrum Le = (*light)->SampleDirect(lightSample, isect, shadowRay, pdf); *wi = shadowRay.dir; if(Le.IsBlack() || *pdf == 0.f) return RGBSpectrum(0.f); Normal Ns = isect.Ns; float cos = Ns.dot(shadowRay.dir); if(cos <= 0.f) return RGBSpectrum(0.f); bool hit = m_Scene->Occluded(shadowRay); if(hit) return RGBSpectrum(0.f); return Le*isect.bsdf->Eval(isect, wo, shadowRay.dir)*cos / *pdf; }
RGBSpectrum BlockedRenderer::BSDFSampling(const Scene::ConstLightIterator &light, const Point2 &bsdfSample, const Intersection &isect, const Vector &wo, Vector *wi, float *pdf) const { RGBSpectrum w = isect.bsdf->Sample(bsdfSample, isect, wo, wi, pdf); Normal Ns = isect.Ns; float cos = Ns.dot(*wi); if(cos <= 0.f) return RGBSpectrum(0.f); Ray ray(isect.p, *wi, isect.rayEpsilon, std::numeric_limits<float>::infinity(), isect.time); Intersection newIsect; RGBSpectrum L(0.f); if(m_Scene->Intersect(ray, &newIsect)) { // TODO: add area light contribution } else { L += (*light)->EvalDirect(*wi); } return w * L * cos / *pdf; }
static RGBSpectrum *ReadImageTGA(const std::string &name, int *width, int *height) { tga_image img; tga_result result; if ((result = tga_read(&img, name.c_str())) != TGA_NOERR) { Error("Unable to read from TGA file \"%s\" (%s)", name.c_str(), tga_error(result)); return nullptr; } if (tga_is_right_to_left(&img)) tga_flip_horiz(&img); if (!tga_is_top_to_bottom(&img)) tga_flip_vert(&img); if (tga_is_colormapped(&img)) tga_color_unmap(&img); *width = img.width; *height = img.height; // "Unpack" the pixels (origin in the lower left corner). // TGA pixels are in BGRA format. RGBSpectrum *ret = new RGBSpectrum[*width * *height]; RGBSpectrum *dst = ret; for (int y = *height - 1; y >= 0; y--) for (int x = 0; x < *width; x++) { uint8_t *src = tga_find_pixel(&img, x, y); if (tga_is_mono(&img)) *dst++ = RGBSpectrum(*src / 255.f); else { Float c[3]; c[2] = src[0] / 255.f; c[1] = src[1] / 255.f; c[0] = src[2] / 255.f; *dst++ = RGBSpectrum::FromRGB(c); } } tga_free_buffers(&img); Info("Read TGA image %s (%d x %d)", name.c_str(), *width, *height); return ret; }
// ImageIO Function Definitions std::unique_ptr<RGBSpectrum[]> ReadImage(const std::string &name, Point2i *resolution) { if (HasExtension(name, ".exr")) return std::unique_ptr<RGBSpectrum[]>( ReadImageEXR(name, &resolution->x, &resolution->y)); else if (HasExtension(name, ".tga")) return std::unique_ptr<RGBSpectrum[]>( ReadImageTGA(name, &resolution->x, &resolution->y)); else if (HasExtension(name, ".pfm")) return std::unique_ptr<RGBSpectrum[]>( ReadImagePFM(name, &resolution->x, &resolution->y)); Error( "Unable to load image stored in format \"%s\" for filename \"%s\". " "Returning a constant gray image instead.", strrchr(name.c_str(), '.') ? (strrchr(name.c_str(), '.') + 1) : "(unknown)", name.c_str()); RGBSpectrum *ret = new RGBSpectrum[1]; ret[0] = RGBSpectrum(0.5f); resolution->x = resolution->y = 1; return std::unique_ptr<RGBSpectrum[]>(ret); }
static RGBSpectrum *ReadImagePFM(const std::string &filename, int *xres, int *yres) { float *data = nullptr; RGBSpectrum *rgb = nullptr; char buffer[BUFFER_SIZE]; unsigned int nFloats; int nChannels, width, height; float scale; bool fileLittleEndian; FILE *fp = fopen(filename.c_str(), "rb"); if (!fp) goto fail; // read either "Pf" or "PF" if (readWord(fp, buffer, BUFFER_SIZE) == -1) goto fail; if (strcmp(buffer, "Pf") == 0) nChannels = 1; else if (strcmp(buffer, "PF") == 0) nChannels = 3; else goto fail; // read the rest of the header // read width if (readWord(fp, buffer, BUFFER_SIZE) == -1) goto fail; width = atoi(buffer); *xres = width; // read height if (readWord(fp, buffer, BUFFER_SIZE) == -1) goto fail; height = atoi(buffer); *yres = height; // read scale if (readWord(fp, buffer, BUFFER_SIZE) == -1) goto fail; sscanf(buffer, "%f", &scale); // read the data nFloats = nChannels * width * height; data = new float[nFloats]; if (fread(data, sizeof(float), nFloats, fp) != nFloats) goto fail; // apply endian conversian and scale if appropriate fileLittleEndian = (scale < 0.f); if (hostLittleEndian ^ fileLittleEndian) { uint8_t bytes[4]; for (unsigned int i = 0; i < nFloats; ++i) { memcpy(bytes, &data[i], 4); std::swap(bytes[0], bytes[3]); std::swap(bytes[1], bytes[2]); memcpy(&data[i], bytes, 4); } } if (std::abs(scale) != 1.f) for (unsigned int i = 0; i < nFloats; ++i) data[i] *= std::abs(scale); // create RGBs... rgb = new RGBSpectrum[width * height]; if (nChannels == 1) { for (int i = 0; i < width * height; ++i) rgb[i] = RGBSpectrum(data[i]); } else { for (int i = 0; i < width * height; ++i) { Float frgb[3] = {data[3 * i], data[3 * i + 1], data[3 * i + 2]}; rgb[i] = RGBSpectrum::FromRGB(frgb); } } delete[] data; fclose(fp); return rgb; fail: Error("Error reading PFM file \"%s\"", filename.c_str()); fclose(fp); delete[] data; delete[] rgb; return nullptr; }
Spectrum GonioPhotometricLight::Power() const { return 4 * Pi * I * Spectrum(mipmap ? mipmap->Lookup(Point2f(.5f, .5f), .5f) : RGBSpectrum(1.f), SpectrumType::Illuminant); }