PBRT_V2 总结记录 <9> GeometricPrimitive 和 Aggregate

GeometricPrimitive 类


// GeometricPrimitive Declarations
class GeometricPrimitive : public Primitive {
public:
	// GeometricPrimitive Public Methods
	bool CanIntersect() const;
	void Refine(vector<Reference<Primitive> > &refined) const;
	virtual BBox WorldBound() const;
	virtual bool Intersect(const Ray &r, Intersection *isect) const;
	virtual bool IntersectP(const Ray &r) const;
	GeometricPrimitive(const Reference<Shape> &s,
		const Reference<Material> &m, AreaLight *a);
	const AreaLight *GetAreaLight() const;
	BSDF *GetBSDF(const DifferentialGeometry &dg,
		const Transform &ObjectToWorld, MemoryArena &arena) const;
	BSSRDF *GetBSSRDF(const DifferentialGeometry &dg,
		const Transform &ObjectToWorld, MemoryArena &arena) const;
private:
	// GeometricPrimitive Private Data
	Reference<Shape> shape;
	Reference<Material> material;
	AreaLight *areaLight;
};

类的作用:

The GeometricPrimitive class represents a single shape (e.g., a sphere) in the scene. One
GeometricPrimitive is allocated for each shape in the scene description provided by the
user.

Each GeometricPrimitive holds a reference to a Shape and its Material. In addition,
because primitives in pbrt may be area light sources, it stores a pointer to an AreaLight
object that describes its emission characteristics (this pointer is set to NULL if the primitive
does not emit light).

加深理解 Primitive 的 Intersect 和 Shape的Intersect的不同,

Primiitive 与 怎么得到 Intersection 结构体

1. 


bool GeometricPrimitive::Intersect(const Ray &r,
	Intersection *isect) const {
	float thit, rayEpsilon;
	if (!shape->Intersect(r, &thit, &rayEpsilon, &isect->dg))
		return false;
	isect->primitive = this;
	isect->WorldToObject = *shape->WorldToObject;
	isect->ObjectToWorld = *shape->ObjectToWorld;
	isect->shapeId = shape->shapeId;
	isect->primitiveId = primitiveId;
	isect->rayEpsilon = rayEpsilon;
	r.maxt = thit;
	return true;
}

 其实就是用  Intersection 结构体 包含了 很多之后要用到的信息,不止 DifferentialGeometry.

2. 

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


BSDF *GeometricPrimitive::GetBSDF(const DifferentialGeometry &dg,
	const Transform &ObjectToWorld,
	MemoryArena &arena) const {

	DifferentialGeometry dgs;
	shape->GetShadingGeometry(ObjectToWorld, dg, &dgs);

	return material->GetBSDF(dg, dgs, arena);
}

DifferentialGeometry dgs;
    shape->GetShadingGeometry(ObjectToWorld, dg, &dgs); 可以参考 : 

https://blog.csdn.net/aa20274270/article/details/82938841 (PBRT_V2 总结记录 <7> Shape)

Aggregate 类


// Aggregate Declarations
class Aggregate : public Primitive {
public:
	// Aggregate Public Methods
	const AreaLight *GetAreaLight() const;
	BSDF *GetBSDF(const DifferentialGeometry &dg,
		const Transform &, MemoryArena &) const;
	BSSRDF *GetBSSRDF(const DifferentialGeometry &dg,
		const Transform &, MemoryArena &) const;
};

作用:

(例如 BVHAccel,GridAccel, KdTreeAccel 都是 Aggregate 的子类,这些类的目标其实都是一致的,都是为了避免没有必要的Ray Test,能够尽快的找到相交的Primitive进行计算交点,Aggregate 继承 Primitive ,主要目的就是,让PBRT处理这些 Aggregate 好像处理普通的Primitive一样,不需要特别对待,这样就更加方便,

所以,在整体上去看PBRT的时候,不用去关心到底使用了 BVHAccel 还是GridAccel 还是 KdTreeAccel,只要记住,在计算 RayTest 的时候,所有 Primitive 都是 为了 得到 一个 相交点,无论你是使用Aggregate 还是最简单的 GeometricPrimitive )

Acceleration structures are one of the components at the heart of any ray tracer.Without
algorithms to reduce the number of unnecessary ray intersection tests, tracing a single ray
through a scene would take time linear in the number of primitives in the scene, since the

ray would need to be tested against each primitive in turn to find the closest intersection.
However, doing so is extremely wasteful in most scenes, since the ray passes nowhere near
the vast majority of primitives. The goal of acceleration structures is to allow the quick,
simultaneous rejection of groups of primitives and also to order the search process so that
nearby intersections are likely to be found first and farther away ones can potentially be
ignored.

The Aggregate class provides an interface for grouping multiple Primitive objects together.
Because Aggregates themselves implement the Primitive interface, no special
support is required elsewhere in pbrt for intersection acceleration. Integrators can be
written as if there was just a single Primitive in the scene, checking for intersections
without needing to be concerned about how they’re actually found.
Furthermore, by
implementing acceleration in this way, it is easy to experiment with new acceleration
techniques by simply adding a new Aggregate primitive to pbrt.

猜你喜欢

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