PBRT_V2 总结记录 <8> Primitive 和 Intersection

Primitive 类

class Primitive : public ReferenceCounted {
public:
	// Primitive Interface
	Primitive() : primitiveId(nextprimitiveId++) { }
	virtual ~Primitive();
	virtual BBox WorldBound() const = 0;
	virtual bool CanIntersect() const;
	virtual bool Intersect(const Ray &r, Intersection *in) const = 0;
	virtual bool IntersectP(const Ray &r) const = 0;
	virtual void Refine(vector<Reference<Primitive> > &refined) const;
	void FullyRefine(vector<Reference<Primitive> > &refined) const;
	virtual const AreaLight *GetAreaLight() const = 0;
	
	virtual BSDF *GetBSDF(const DifferentialGeometry &dg,
		const Transform &ObjectToWorld, MemoryArena &arena) const = 0;

	virtual BSSRDF *GetBSSRDF(const DifferentialGeometry &dg,
		const Transform &ObjectToWorld, MemoryArena &arena) const = 0;

	// Primitive Public Data
	const uint32_t primitiveId;
protected:
	// Primitive Protected Data
	static uint32_t nextprimitiveId;
};

类的作用:

(Shape不能表示Scene上的一个物体,因为Shape只有几何的信息,一个物体往往需要的还有是外观的信息(材质,所以 出现了Primitive ,既 包含了几何信息,又包含了材质信息))

Although the Shape class provides a convenient abstraction for
geometric operations such as intersection and bounding, it doesn’t contain enough information
to fully describe an object in a scene. For example, it is necessary to bind material
properties to each shape in order to specify its appearance.
To accomplish these goals,
this chapter introduces the Primitive class and provides a number of implementations.

1. 几何接口

virtual bool CanIntersect() const;
virtual bool Intersect(const Ray &r, Intersection *in) const = 0;
virtual bool IntersectP(const Ray &r) const = 0;
virtual void Refine(vector<Reference<Primitive> > &refined) const;

这些接口 直接 关联 shape的对应的接口

2. 相交

扫描二维码关注公众号,回复: 3463991 查看本文章

virtual bool Intersect(const Ray &r, Intersection *in) const = 0;

注意:(Primitive 和Shape很相似,但是对应 Intersect方法 有点不同,最主要的区别是,Primitive->Intersect 返回的是Intersection 结构,而不是 DifferentialGeometry ,Intersection 保存了更加多的信息,而不只是几何信息,例如还有一些材质的信息)

One difference from the Shape interface is that the Primitive intersection methods return
Intersection structures rather than DifferentialGeometry. These Intersection
structures hold more information about the intersection than just the local geometric
information, such as information about the material properties at the hit point.

Another difference is that Shape::Intersect() returns the parametric distance along the
ray to the intersection in a float * output variable, while Primitive::Intersect() is
responsible for updating Ray::maxt with this value if an intersection is found.

3. Intersection 结构

// Intersection Declarations
struct Intersection {
	// Intersection Public Methods
	Intersection() {
		primitive = NULL;
		shapeId = primitiveId = 0;
		rayEpsilon = 0.f;
	}

	
	BSDF *GetBSDF(const RayDifferential &ray, MemoryArena &arena) const;
	
	BSSRDF *GetBSSRDF(const RayDifferential &ray, MemoryArena &arena) const;
	Spectrum Le(const Vector &wo) const;

	// Intersection Public Data
	DifferentialGeometry dg;
	const Primitive *primitive;
	Transform WorldToObject, ObjectToWorld;
	uint32_t shapeId, primitiveId;
	float rayEpsilon;
};

类的作用:

(Intersection 结构 保存了 一个 相交点的 DifferentialGeometry,相交物体Primitive指针,和一些变换矩阵)

The Intersection structure holds information about a ray–primitive intersection, including
information about the differential geometry of the point on the surface, a pointer
to the Primitive that the ray hit, and its world-to-object-space transformation.

4. 细分

void Primitive::FullyRefine(vector<Reference<Primitive> > &refined) const

void Primitive::FullyRefine(vector<Reference<Primitive> > &refined) const {
	vector<Reference<Primitive> > todo;
	todo.push_back(const_cast<Primitive *>(this));
	while (todo.size()) {
		// Refine last primitive in todo list
		Reference<Primitive> prim = todo.back();
		todo.pop_back();
		if (prim->CanIntersect())
			refined.push_back(prim);
		else
			prim->Refine(todo);
	}
}

作用:

(细分一个Primitive,直到所有的 Primitive 都是 intersectable,并返回 vector<Reference<Primitive> > &refined 保存所有的intersectable Primitive, )

It may be necessary to repeatedly refine a primitive until all of the primitives it has returned
are themselves intersectable. The Primitive::FullyRefine() utility method handles
this task. Its implementation is straightforward. It maintains(维护) a queue of primitives
to be refined (called todo in the following code) and invokes the Primitive::Refine()
method repeatedly on entries in that queue. Intersectable Primitives returned by
Primitive::Refine() are placed in the refined array, while nonintersectable ones are
placed back on the todo list by the Refine() routine.

5. virtual const AreaLight *GetAreaLight() const = 0;

作用:(如果 Primitive 可以作为 一个Area Light,就直接返回 Area Light, 不是的话,就直接返回NULL)

Primitive::GetAreaLight(), returns a pointer to the
AreaLight that describes the primitive’s emission distribution, if the primitive is itself a
light source. If the primitive is not emissive, this method should return NULL.

6. 

(下面的两个方法,主要就是返回 某一个相交点的材质的 光散射 属性)

The other two methods return representations of the light-scattering properties of the
material at the given point on the surface.

6. 1

virtual BSDF *GetBSDF(const DifferentialGeometry &dg, const Transform &ObjectToWorld, MemoryArena &arena) const = 0;

作用:

returns a BSDF object (introduced in Section 9.1) that describes local light-scattering properties at the
intersection point.

6.2
virtual BSSRDF *GetBSSRDF(const DifferentialGeometry &dg,
const Transform &ObjectToWorld, MemoryArena &arena) const = 0;

作用:

Primitive::GetBSSRDF(), returns a BSSRDF, which describes subsurface
scattering inside the primitive—light that enters the surface at points far from where
it exits.While subsurface light transport has little effect on the appearance of objects like
metal, cloth, or plastic, it is the dominant(显著) light-scattering mechanism for biological(生物) materials
like skin, thick liquids like milk, etc.

猜你喜欢

转载自blog.csdn.net/aa20274270/article/details/82940800