1. 程式人生 > >PBRT_V2 總結記錄 <21> CameraSample 和 Sample

PBRT_V2 總結記錄 <21> CameraSample 和 Sample

CameraSample 類

struct CameraSample {
	float imageX, imageY;
	float lensU, lensV;
	float time;
};

類的作用:

(這個類代表的就是取樣點,傳入取樣點給Camera ,會根據取樣點生成 Ray,傳入取樣點給 Integrators,會執行光照計算

CameraSample 代表的只是 生成射線的取樣點)

The Sample structure is used by Samplers to store a single sample. After one or more Samples is initialized by a call to the Sampler’s GetMoreSamples() method, the Sampler RendererTask::Run() method passes each of the Samples to the camera and integrators, which read values from it to construct the camera ray and perform lighting calculations

Sample inherits from the CameraSample structure; the CameraSample represents just the sample values that are needed for generating camera rays. This separation allows us to just pass a CameraSample to the Camera::GenerateRay() method, not exposing all of the details of the rest of the Sample structure to Cameras.

Sample 類


struct Sample : public CameraSample {
	// Sample Public Methods
	Sample(Sampler *sampler, SurfaceIntegrator *surf, VolumeIntegrator *vol,
		const Scene *scene);

	uint32_t Add1D(uint32_t num) {
		n1D.push_back(num);
		return n1D.size() - 1;
	}

	uint32_t Add2D(uint32_t num) {
		n2D.push_back(num);
		return n2D.size() - 1;
	}

	~Sample() {
		if (oneD != NULL) {
			FreeAligned(oneD[0]);
			FreeAligned(oneD);
		}
	}

	Sample *Duplicate(int count) const;

	vector<uint32_t> n1D, n2D;
	
	float **oneD, **twoD;
private:
	
	void AllocateSampleMemory();
	Sample() { oneD = twoD = NULL; }
};

類的作用:

(不同的integrators,需要的取樣點的資料可能不一樣,有些integrators需要的取樣點的資料不止CameraSample 裡面包含的,取樣點裡面還需要其他的資料,所以,integrators 有一個機會去 請求額外的取樣資料,請求的資訊會儲存到 Sample 裡,當Sample 傳入到 Sampler 中,Sampler就會根據請求資料,去生成對應的取樣資料)

(Sample 和 CameraSample 的區別就是,Sample 裡面還會儲存一些另外的)

Depending on the details of the light transport algorithm being used, different integrators may have different sampling needs beyond the camera sample values. For example, the WhittedIntegrator doesn’t do any random sampling, so it doesn’t need any additional sample values beyond the ones to generate the camera ray. The DirectLighting

Integrator uses values from the Sampler to randomly choose a light source to sample illumination from, as well as to randomly choose positions on area light sources. Therefore,the integrators are given an opportunity to request additional sample values in various quantities(不同數量). Information about these requirements is stored in the Sample object. When it is later passed to the particular Sampler implementation, it is the Sampler’s responsibility to generate all of the requested types of samples.

1. 建構函式

Sample::Sample(Sampler *sampler, SurfaceIntegrator *surf,
               VolumeIntegrator *vol, const Scene *scene) {

	// 
    if (surf) surf->RequestSamples(sampler, this, scene);
    if (vol)  vol->RequestSamples(sampler, this, scene);
    AllocateSampleMemory();
}

作用:

(Sample 建構函式 呼叫 Integrator:RequestSamples 方法去,  看看這個Integrator 需要有什麼樣的 取樣點資料,Integrators 可以請求多組 1D和2D 資料, 例如,一個場景有兩個Area Light, Integrator 追蹤 4條Ray 到第一個光源,追蹤8條Ray到第二個光源,那麼Integrator需要請求 2組 2D資料,一組有4個取樣資料,另一組有8個取樣資料,另外一個例子,如果Integrator 想要在多個光源中隨機選擇一個光源,那麼就需要請求 1組1D 資料,這組資料只有一個取樣資料,用來確定到底選擇那一個光源

Integrator:RequestSamples 方法中,呼叫 Sample:AddID 和 Sample:Add2D 來請求 資料 )

The Sample constructor calls the Integrator::RequestSamples() methods of the surface and volume integrators to find out what samples they will need. The integrators can ask for multiple one-dimensional and/or two-dimensional sampling patterns, each with an arbitrary number of entries. For example, in a scene with two area light sources, where the integrator traces four shadow rays to the first source and eight to the second, the integrator would ask for two 2D sample patterns for each image sample, with four and eight samples each. A 2D pattern is required because two dimensions are needed to parameterize the surface of a light. Similarly, if the integrator wanted to randomly select a single light source out of(由於) many, it could request a 1D sample with a single value for this purpose and use its float value to randomly choose a light.

The integrators’ implementations of the Integrator::RequestSamples() method in turn call the Sample::Add1D() and Sample::Add2D() methods, which request another sample sequence with a given number of sample values. After they are done calling these methods, the Sample constructor can continue, allocating storage for the requested sample values.

2.  uint32_t Add1D(uint32_t num) 和 uint32_t Add2D(uint32_t num)

作用:

(呼叫 Add1D(uint32_t num) 一次, 就是請求一組1D取樣資料, 這組資料有num個)

The implementations of the Sample::Add1D() and Sample::Add2D() methods record the number of samples asked for in an array and return an index that the integrator can later use to access the desired sample values in the Sample.

3. 

 vector<uint32_t> n1D, n2D; float **oneD, **twoD;

void Sample::AllocateSampleMemory()