Film 类
class Film {
public:
// Film Interface
Film(int xres, int yres)
: xResolution(xres), yResolution(yres) { }
virtual ~Film();
virtual void AddSample(const CameraSample &sample,
const Spectrum &L) = 0;
virtual void Splat(const CameraSample &sample, const Spectrum &L) = 0;
virtual void GetSampleExtent(int *xstart, int *xend,
int *ystart, int *yend) const = 0;
virtual void GetPixelExtent(int *xstart, int *xend,
int *ystart, int *yend) const = 0;
virtual void UpdateDisplay(int x0, int y0, int x1, int y1, float splatScale = 1.f);
virtual void WriteImage(float splatScale = 1.f) = 0;
// Film Public Data
const int xResolution, yResolution;
};
类的作用:
(Film 类 就是模拟 相机上的 胶片,Film 是 主要是 生成Image)
The type of film or sensor in a camera has a dramatic effect on the way that incident
light is eventually transformed into colors in an image. In pbrt, the Film class models the
sensing device in the simulated camera. After the radiance is found for each camera ray,
a Film implementation determines the sample’s contribution to the nearby pixels and
updates its representation of the image. When the main rendering loop exits, the Film
typically writes the final image to a file on disk.
This section only provides a single Film implementation. It applies the pixel reconstruction
equation to compute final pixel values and writes the image to disk with floatingpoint
color values. For a physically based renderer, creating images in a floating-point
format provides more flexibility in how the output can be used than if a typical image
format with 8-bit unsigned integer values is used; floating-point formats avoid the substantial
loss of information that comes from image quantization to(数字化) 8-bit image formats.
In order to display such images on modern display devices, however, it is necessary to
map these floating-point pixel values to discrete values for display. For example, computer
monitors generally expect the color of each pixel to be described by an RGB color
triple, not an arbitrary spectral power distribution. Spectra described by general basis
function coefficients must therefore be converted to an RGB representation before they
can be displayed. A related problem is that displays have a substantially smaller range of
displayable radiance values than the range present in many real-world scenes. Therefore,
the pixel values must be mapped to the displayable range in a way that causes the final
displayed image to appear as close as possible to the way it would appear on an ideal display device without this limitation
1. 构造函数
Film(int xres, int yres)
: xResolution(xres), yResolution(yres) { }
作用:
The Film constructor must be given the overall resolution of the image in the x and
y directions; these are stored in the public member variables Film::xResolution and
Film::yResolution. The Cameras in Chapter 6 need these values to compute some of the
camera-related transformations, such as the raster-to-camera-space transformations.
2. virtual void AddSample(const CameraSample &sample,
const Spectrum &L) = 0;
作用:
(提供数据给Film,这里是贡献一个Sample 和它的对应的radiance 给 pixel,形成pixel的颜色值,而且 最终的pixel 得颜色值是加权平均它附近的sample的贡献)
There are two methods for providing data to the film. The first is driven by Samples
generated by the Sampler; for each such sample, Film::AddSample() is called. It takes
a sample and corresponding radiance value, applies the reconstruction filter, and and
updates the stored image. The expectation with this method is that the sampling density
around a pixel is not related to the pixel’s final value. (In other words, the final pixel value
is effectively a weighted average of the nearby samples.) Under this assumption, the pixel
filtering equation can be used to compute the final values.
3. virtual void Splat(const CameraSample &sample, const Spectrum &L) = 0;
作用:
(这个方法也是利用sample 去更新 pixel颜色,但是不是加权平均,而是累加,pixel 附近越多 sample,pixel就越亮)
The second method for providing data to the film is Splat(). Splatting similarly updates
pixel values, but rather than computing the final pixel value as a weighted average, splats
are simply summed. Thus, the more splats that are around a given pixel, the brighter
the pixel will be. This method is used by light transport algorithms like the one in the
MetropolisRenderer, where more samples are generated in areas where the image is
brighter. It would also be used by bidrectional light transport algorithms that followed
paths starting from lights and then projected illuminated points onto the film.
4. virtual void GetSampleExtent(int *xstart, int *xend,
int *ystart, int *yend) const = 0;
作用:
(获得Film 的采样点 范围)
The Film is responsible for determining the range of integer pixel values that the Sampler
is responsible for generating samples for. While this range would be from (0, 0) to
(xResolution − 1, yResolution − 1) for a simple film implementation, in general it is
necessary to sample the image plane at locations slightly beyond the edges of the final
image due to the finite extent of pixel reconstruction filters. This range is returned by the
GetSampleExtent() method.
5. virtual void GetPixelExtent(int *xstart, int *xend,
int *ystart, int *yend) const = 0;
作用:
(获得Film 的像素范围)
GetPixelExtent() provides the range of pixels in the actual image.
ImageFilm类
class ImageFilm : public Film {
public:
// ImageFilm Public Methods
ImageFilm(int xres, int yres, Filter *filt, const float crop[4],
const string &filename, bool openWindow);
~ImageFilm() {
delete pixels;
delete filter;
delete[] filterTable;
}
// 基类 : 作用
// 思路 : P408
void AddSample(const CameraSample &sample, const Spectrum &L);
void Splat(const CameraSample &sample, const Spectrum &L);
void GetSampleExtent(int *xstart, int *xend, int *ystart, int *yend)