PBRT reading: Fourth chapter of the volume and the intersection of Accelerated section 4.1-4.3 __primitive

Source: Internet
Author: User
The 4th chapter is the acceleration of the body element and the intersection

The class described in the previous chapter focuses on how to express the geometrical properties of 3D objects. Although the shape class is a convenient abstraction for geometric operations like intersection and bounding boxes, it does not include enough information to describe an object in a scene. For example, we have to add material information and form together to explain the appearance of the body. To achieve these goals, this chapter describes the primitive class and its several implementations.

The form used directly for rendering is expressed in geometricprimitive class. This class combines a shape with a description of the nature of its appearance. The aim is to clearly separate the geometric parts of the PBRT from the rendering part, which are encapsulated in the material class, see chap. 10th.

Some scenes contain many copies of the same individual element in different locations. Support for associated copies (instancing) can greatly reduce the need for memory in scenarios, because each copy only holds a pointer to the body and a transform. To do this, PBRT provides a instanceprimitive class. Each Instanceprimitive object has a separate transformation to place it in the scene, but it can share the same individual element with other Instanceprimitive objects.

This chapter also describes the aggregate base class, which represents a container (container) that can contain many primitive. PBRT uses this class to implement an accelerated structure--a data structure that reduces the complexity of N-object and light intersection tests in a scene. Most rays intersect only a few bodies. If an accelerated structure can exclude a group of bodies at one time, this will have a substantial performance boost compared to what must be tested for each body. These accelerated structures reuse the primitive interface (the acceleration structure is a subclass of the aggregate, and aggregate is also a primitive subclass), and the benefit is that PBRT can support the hybrid acceleration method, which means that one type of acceleration structure can contain other types of acceleration structures 。

This chapter describes two accelerated structures: the GRIDACCEL structure, which is based on a homogeneous grid covering the scene, and the other is Kdtreeaccel, which is based on adaptive recursive spatial partitioning (adaptive recursive spatial subdivision).

4.1 Primitive interface and geometrical BODY element

Abstract base class primitive is a bridge between the PBRT geometry processing subsystem and the coloring subsystem. It inherits the Referencecounted base class, automatically records the number of object references, and releases the memory occupied by the object when the last reference is detached from the scope. Other classes containing primitive should not hold primitive pointers, but should store reference<primitive&gt, so that the correct number of references can be guaranteed. Except for this, the function of the,reference<primitive> class is no different from the pointer to the primitive.

<primitive declarations> =
Class Coredll Primitive:public referencecounted {
Public
<primitive interface>
};

Because the primitive class links geometric operations to coloring operations, its interface also includes functions related to both. It has 5 geometric routines that are similar to functions in the shape class. The first is Primitive::worldbound (), which returns the BODY element in the world space of the bounding box. The bounding box has many uses, one of the most important uses is to put the primitive into the accelerated structure process.

<primitive interface> =
Virtual Bbox worldbound () const = 0;

Like the shape class, all primitive can determine whether the intersection of light and body element can be directly obtained, and if not, it can be subdivided into one or more new primitive. Similar to shape, primitive has a function primitive::canintersect (), which determines whether its body can directly find the intersection point.

One difference with the shape interface is that the primitive function returns a intersection structure rather than a differentialgeometry structure. In addition to the local geometric information of intersections, these intersection structures include other information such as material properties.

Another difference is that Shape::intersect () returns only the distance of the parameter along the light to the intersection, and Primitive::intersect () changes the RAY::MAXT value of the light. The advantage of this is that the geometry routines described in the previous chapter do not necessarily care about how the other parts of the system use this parameter distance.

<primitive interface> + =
virtual bool Canintersect () const;
virtual bool Intersect (const Ray &r, intersection *in) const = 0;
virtual bool Intersect (const Ray &r) const = 0;
virtual void Refine (vector<reference<primitive>> &refined) const;

The intersection structure contains information about the intersection of light and mass, including the differential geometry information on the surface of the point, the pointer to the primitive, and the transformation of a world space into an object space.

<primitive declaration> + =
struct Coredll Intersection {
<intersection Public methods>
Differentialgeometry DG;
const primitive *primitive;
Transform Worldtoobject;
};

Sometimes we need to continuously refine a BODY element until the returned new body can be asked to be delivered. Primitive::fullyrefine () is doing the work. It's very simple to implement. It maintains a primitive queue (Todo queue) to be refined, and then constantly takes out primitive from the queue, invoking Primitive::refine (). The primitive::refine that are returned by the () are added to the output queue, while the non-intersection of the body element is taken to the TODO queue, so that it is processed until the TODO queue is empty.

<primitive interface> + =
void Fullyrefine (vector<reference<primitive>> &refined) const;
<primitive Method definitions> =
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>
}
}

<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);

In addition to the geometric operation function, primitive has two functions related to the properties of the material. The first is Primitive::getarealight (), which returns a pointer to the Arealight, and the Arealight class is used to describe the emitted light distribution of the BODY element (if it is the light source).

Another function is PRIMITIVE::GETBSDF (), which returns a BSDF pointer (see sect. 10.1). BSDF is used to describe the material properties of light scattering of points on the surface. The parameter of the function is the differential geometry information at the intersection, and the transformation of a world space to the object space. This transformation will be used in the Instanceprimitive class that follows.

<primitive interface> + =
Virtual const Arealight *getarealight () const = 0;
Virtual BSDF *getbsdf (const differentialgeometry &AMP;DG, const Transform &worldtoobject)
const = 0;

4.1.1 Geometrical BODY element (geometric primitives)

The Geometricprimitive class is used to represent a single form (such as a ball) in a scene. PBRT creates a Geometricprimitive object for each form in the scene description file provided by the user.

<primitive declarations> + =
Class Geometricprimitive:public Primitive {
Public
<geometricprimitive Public methods>
Private
<geometricprimitive Private data>
}

Each geometricprimitive holds a reference to the shape and a reference to the material. In addition, because the BODY element in the PBRT can be a surface light source, it also has a pointer to a arealight that describes the luminescence characteristic (set to null if the body is not luminous).

<geometricprimitive Private data> =
Reference<shape> Shape;
Reference<material> Material;
Arealight *arealight;

Geometricprimitive constructors Initialize these variables, no concrete implementations are listed here.
<geometricprimitive Public methods> =
Geometricprimitive (const reference<shape> &s,
Const Reference<material> &m,
Arealight *a);

Most functions related to geometric processing in the primitive interface are just calls to the corresponding functions in shape. For example, Geometricprimitive::intersect () calls Shape::intersect () to do the actual geometric intersection, and then initializes a intersection object with the resulting intersection. Also, it will update the members of the Ray::maxt to the distance of the node parameters returned. The main advantage of keeping the nearest intersection parameter distance in Ray::maxt is that if you find that the body is in a given range of light (MINT,MAXT), you do not have to do any further test.

< Geometricprimitive Method definitions> =
BOOL Geometricprimitive::intersect (const Ray &r, intersection *isect) const {
float Thit;
if (!shape->intersect (R, &thit, &AMP;ISECT-&GT;DG))
return false;
Isect->primitive = this;
Isect->worldtoobject = shape->worldtoobject;
R.maxt = Thit;
return true;
}

We no longer put the implementation of the Geometricprimitive Worldbound (), INTERSECTP (), Canintersect (), Refine () function here, they simply call the corresponding function in the shape class. Similarly, getarealight () simply returns the Geometricprimitive::arealight member variable.

Finally, the GETBSDF () function calls the function in shape to obtain the coloring information and computes the BSDF value using the function in material.

< Geometricprimitive method Definitions> + =
BSDF * GEOMETRICPRIMITIVE::GETBSDF (const differentialgeometry &AMP;DG,
Const Transform &worldtoobject) Const {
Differentialgeometry DGs;
Shape->getshadinggeometry (Worldtoobject.getinverse (), DG, &dgs);
Return MATERIAL-&GT;GETBSDF (DG, DGS);

4.1.2 Object associated Copy (object instancing)

An object-associated copy is a classic technique: a BODY element can be transformed into multiple locations in a scene. For example, a concert hall model consists of thousands of identical seats, and if all the seats are represented by the geometry of the same seat, then the scene description file can be greatly compressed. The ecological scene in Fig. 4.1 has 4000 different types of plants, and there are only 61 plant models. Because the associated copy is used, although the entire scene has 19.5 triangles, memory only saves 1.1 triangles. The PBRT uses approximately 300MB of memory during rendering.

The object associated copy is handled by the Instanceprimitve class. It has a reference to the shared primitive, an instance to the transformation of the World Space (Instance-to-world-space), which is used to place it in the scene. If you want to copy multiple primitive at once, put them in an aggregation (Aggregate) object, so you need to save only one primitive object.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.