Acceleration
description
Transcript of Acceleration
![Page 1: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/1.jpg)
Acceleration
Digital Image SynthesisYung-Yu Chuang10/8/2009
with slides by Mario Costa Sousa, Gordon Stoll and Pat Hanrahan
![Page 2: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/2.jpg)
Classes
• Primitive (in core/primitive.*)– GeometricPrimitive– InstancePrimitive– Aggregate
• Two types of accelerators are provided (in accelerators/*.cpp)– GridAccel– KdTreeAccel
![Page 3: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/3.jpg)
Hierarchy
GeometricPrimitive
InstancePrimitive
Aggregate
Material Shape
Primitive
T
![Page 4: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/4.jpg)
Primitive
class Primitive : public ReferenceCounted {
<Primitive interface>
}
class InstancePrimitive : public Primitive {
…
Reference<Primitive> instance;
}
![Page 5: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/5.jpg)
Interface
BBox WorldBound();
bool CanIntersect();
bool Intersect(const Ray &r,
Intersection *in);
bool IntersectP(const Ray &r);
void Refine(vector<Reference<Primitive>>
&refined);
void FullyRefine(vector<Reference<Primitive>>
&refined);
AreaLight *GetAreaLight();
BSDF *GetBSDF(const DifferentialGeometry &dg,
const Transform &WorldToObject);
// update maxt
geometry
material
![Page 6: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/6.jpg)
Intersection
• primitive stores the actual intersecting primitive, hence Primitive->GetAreaLight and GetBSDF can only be called for GeometricPrimitive
struct Intersection {
<Intersection interface>
DifferentialGeometry dg;
const Primitive *primitive;
Transform WorldToObject;
};
More information than DifferentialGeometry; also contains material information
![Page 7: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/7.jpg)
GeometricPrimitive
• represents a single shape• holds a reference to a Shape and its Material, and a pointer to an AreaLight
Reference<Shape> shape;
Reference<Material> material; // BRDF
AreaLight *areaLight; // emittance
• Most operations are forwarded to shape
![Page 8: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/8.jpg)
Object instancing
61 unique plant models, 1.1M triangles, 300MB4000 individual plants, 19.5M triangles
![Page 9: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/9.jpg)
InstancePrimitive
Reference<Primitive> instance;
Transform InstanceToWorld, WorldToInstance;
Ray ray = WorldToInstance(r);
if (!instance->Intersect(ray, isect))
return false;
r.maxt = ray.maxt;
isect->WorldToObject = isect->WorldToObject *WorldToInstance;
![Page 10: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/10.jpg)
Aggregates
• Acceleration is a heart component of a ray tracer because ray/scene intersection accounts for the majority of execution time
• Goal: reduce the number of ray/primitive intersections by quick simultaneous rejection of groups of primitives and the fact that nearby intersections are likely to be found first
• Two main approaches: spatial subdivision, object subdivision
• No clear winner
![Page 11: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/11.jpg)
Acceleration techniques
![Page 12: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/12.jpg)
Bounding volume hierarchy
![Page 13: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/13.jpg)
1) Find bounding box of objects
Bounding volume hierarchy
![Page 14: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/14.jpg)
1) Find bounding box of objects2) Split objects into two groups
Bounding volume hierarchy
![Page 15: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/15.jpg)
1) Find bounding box of objects2) Split objects into two groups3) Recurse
Bounding volume hierarchy
![Page 16: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/16.jpg)
1) Find bounding box of objects2) Split objects into two groups3) Recurse
Bounding volume hierarchy
![Page 17: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/17.jpg)
1) Find bounding box of objects2) Split objects into two groups3) Recurse
Bounding volume hierarchy
![Page 18: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/18.jpg)
1) Find bounding box of objects2) Split objects into two groups3) Recurse
Bounding volume hierarchy
![Page 19: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/19.jpg)
• At midpoint • Sort, and put half of the objects on each side• Use modeling hierarchy
Where to split?
![Page 20: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/20.jpg)
BVH traversal
• If hit parent, then check all children
![Page 21: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/21.jpg)
BVH traversal
• Don't return intersection immediately because the other subvolumes may have a closer intersection
![Page 22: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/22.jpg)
Bounding volume hierarchy
![Page 23: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/23.jpg)
Bounding volume hierarchy
![Page 24: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/24.jpg)
Quadtree (2D)Octree (3D)
Space subdivision approaches
Unifrom grid
![Page 25: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/25.jpg)
KD tree
Space subdivision approaches
BSP tree
![Page 26: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/26.jpg)
Uniform grid
![Page 27: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/27.jpg)
Uniform grid
Preprocess scene1. Find bounding box
![Page 28: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/28.jpg)
Uniform grid
Preprocess scene1. Find bounding box2. Determine grid resolution
![Page 29: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/29.jpg)
Uniform grid
Preprocess scene1. Find bounding box2. Determine grid resolution3. Place object in cell if its
bounding box overlaps the cell
![Page 30: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/30.jpg)
Uniform grid
Preprocess scene1. Find bounding box2. Determine grid resolution3. Place object in cell if its
bounding box overlaps the cell
4. Check that object overlaps cell (expensive!)
![Page 31: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/31.jpg)
Uniform grid traversal
Preprocess sceneTraverse grid
3D line = 3D-DDA (Digital Differential Analyzer)
12
12
xx
yym
bmxy
11 ii xx
myy ii 1 DDA
bmxy ii 11 naive
![Page 33: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/33.jpg)
A
A
Leaf nodes correspond to unique regions in space
K-d tree
![Page 34: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/34.jpg)
A
A
Leaf nodes correspond to unique regions in space
B
K-d tree
![Page 35: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/35.jpg)
A
B
A
B
Leaf nodes correspond to unique regions in space
K-d tree
![Page 36: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/36.jpg)
A
B
A
B
C
K-d tree
![Page 37: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/37.jpg)
A
B
C A
B
C
K-d tree
![Page 38: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/38.jpg)
A
B
C A
B
C
D
K-d tree
![Page 39: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/39.jpg)
A
B
C
D
A
B
C
D
K-d tree
![Page 40: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/40.jpg)
A
B C
D
A
B
C
D
Leaf nodes correspond to unique regions in space
K-d tree
![Page 41: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/41.jpg)
A
B C
D
A
B
C
D
Leaf nodes correspond to unique regions in space
K-d tree traversal
![Page 42: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/42.jpg)
3
4
1
2
56
7
9
8
11
10
BSP tree
![Page 43: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/43.jpg)
3
4
1
2
56
7
1
insideones
outsideones
9
8
11
10
BSP tree
![Page 44: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/44.jpg)
3
4
1
2
56
7
1
234
567891011
9
8
11
10
BSP tree
![Page 45: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/45.jpg)
3
4
1
2
9
8
11
10
56
7
9b
9a
1
5
679a1011a
11a
11b 89b11b
BSP tree
![Page 46: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/46.jpg)
3
4
1
2
9
8
11
10
56
7
9b
11a
2
3
4
1
5
6
7
9a
10
11a
8
9b
11b
9a11b
BSP tree
![Page 47: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/47.jpg)
3
4
1
2
9
8
11
10
56
7
9b
point
11a
2
3
4
1
5
6
7
9a
10
11a
8
9b
11b
9a11b
9a11b
BSP tree traversal
![Page 48: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/48.jpg)
3
4
1
2
9
8
11
10
56
7
9b
point
11a
2
3
4
1
5
6
7
9a
10
11a
8
9b
11b
9a11b
9a11b
BSP tree traversal
![Page 49: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/49.jpg)
1
2
9
8
11
10
56
7
9b
point
11a
2
3
4
1
5
6
7
9a
10
11a
8
9b
11b
9a11b
9a11b
3
4
BSP tree traversal
![Page 50: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/50.jpg)
Ray-Box intersections
• Both GridAccel and KdTreeAccel require it
• Quick rejection, use enter and exit point to traverse the hierarchy
• AABB is the intersection of three slabs
![Page 51: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/51.jpg)
Ray-Box intersections
x=x0 x=x1
x
x
D
Oxt
1
1
1
Dx
xOx 1
1t
![Page 52: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/52.jpg)
Ray-Box intersectionsbool BBox::IntersectP(const Ray &ray, float *hitt0, float *hitt1) { float t0 = ray.mint, t1 = ray.maxt; for (int i = 0; i < 3; ++i) { float invRayDir = 1.f / ray.d[i]; float tNear = (pMin[i] - ray.o[i]) * invRayDir; float tFar = (pMax[i] - ray.o[i]) * invRayDir;
if (tNear > tFar) swap(tNear, tFar); t0 = tNear > t0 ? tNear : t0; t1 = tFar < t1 ? tFar : t1; if (t0 > t1) return false; } if (hitt0) *hitt0 = t0; if (hitt1) *hitt1 = t1; return true;}
segment intersection
intersection is empty
![Page 53: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/53.jpg)
Grid accelerator
• Uniform grid
![Page 54: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/54.jpg)
Teapot in a stadium problem
• Not adaptive to distribution of primitives.• Have to determine the number of voxels.
(problem with too many or too few)
![Page 55: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/55.jpg)
GridAccel
Class GridAccel:public Aggregate {
<GridAccel methods>
u_int nMailboxes;
MailboxPrim *mailboxes;
int NVoxels[3];
BBox bounds;
Vector Width, InvWidth;
Voxel **voxels;
ObjectArena<Voxel> voxelArena;
static int curMailboxId;
}
![Page 56: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/56.jpg)
mailbox
struct MailboxPrim { Reference<Primitive> primitive; Int lastMailboxId;}
![Page 57: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/57.jpg)
GridAccel
GridAccel(vector<Reference<Primitive> > &p,
bool forRefined, bool refineImmediately)
: gridForRefined(forRefined) {
// Initialize with primitives for grid
vector<Reference<Primitive> > prims;
if (refineImmediately)
for (u_int i = 0; i < p.size(); ++i)
p[i]->FullyRefine(prims);
else
prims = p;
![Page 58: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/58.jpg)
GridAccel
// Initialize mailboxes for grid
nMailboxes = prims.size();
mailboxes
= (MailboxPrim*)AllocAligned(
nMailboxes * sizeof(MailboxPrim));
for (u_int i = 0; i < nMailboxes; ++i)
new (&mailboxes[i])MailboxPrim(prims[i]);
![Page 59: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/59.jpg)
Determine number of voxels
• Too many voxels → slow traverse, large memory consumption (bad cache performance)
• Too few voxels → too many primitives in a voxel
• Let the axis with the largest extent have partitions (N:number of primitives)
Vector delta = bounds.pMax - bounds.pMin;
int maxAxis=bounds.MaximumExtent();
float invMaxWidth=1.f/delta[maxAxis];
float cubeRoot=3.f*powf(float(prims.size()),1.f/3.f);
float voxelsPerUnitDist=cubeRoot * invMaxWidth;
33 N
![Page 60: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/60.jpg)
Calculate voxel size and allocate voxelsfor (int axis=0; axis<3; ++axis) { NVoxels[axis]=Round2Int(delta[axis]*voxelsPerUnitDist);
NVoxels[axis]=Clamp(NVoxels[axis], 1, 64);
}
for (int axis=0; axis<3; ++axis) {
Width[axis]=delta[axis]/NVoxels[axis];
InvWidth[axis]=
(Width[axis]==0.f)?0.f:1.f/Width[axis];
}
int nVoxels = NVoxels[0] * NVoxels[1] * NVoxels[2];
voxels=(Voxel **)AllocAligned(nVoxels*sizeof(Voxel *));
memset(voxels, 0, nVoxels * sizeof(Voxel *));
![Page 61: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/61.jpg)
Conversion between voxel and positionint PosToVoxel(const Point &P, int axis) { int v=Float2Int( (P[axis]-bounds.pMin[axis])*InvWidth[axis]); return Clamp(v, 0, NVoxels[axis]-1);}
float VoxelToPos(int p, int axis) const { return bounds.pMin[axis]+p*Width[axis];}Point VoxelToPos(int x, int y, int z) const { return bounds.pMin+ Vector(x*Width[0], y*Width[1], z*Width[2]);}
inline int Offset(int x, int y, int z) { return z*NVoxels[0]*NVoxels[1] + y*NVoxels[0] + x;}
![Page 62: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/62.jpg)
Add primitives into voxels
for (u_int i=0; i<prims.size(); ++i) {
<Find voxel extent of primitive>
<Add primitive to overlapping voxels>
}
![Page 63: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/63.jpg)
<Find voxel extent of primitive>
BBox pb = prims[i]->WorldBound();
int vmin[3], vmax[3];
for (int axis = 0; axis < 3; ++axis) {
vmin[axis] = PosToVoxel(pb.pMin, axis);
vmax[axis] = PosToVoxel(pb.pMax, axis);
}
![Page 64: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/64.jpg)
<Add primitive to overlapping voxels>
for (int z = vmin[2]; z <= vmax[2]; ++z) for (int y = vmin[1]; y <= vmax[1]; ++y)
for (int x = vmin[0]; x <= vmax[0]; ++x) { int offset = Offset(x, y, z);
if (!voxels[offset]) { voxels[offset] = new (voxelArena)Voxel(&mailboxes[i]); } else {
// Add primitive to already-allocated voxel voxels[offset]-
>AddPrimitive(&mailboxes[i]); } }
![Page 65: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/65.jpg)
Voxel structure
struct Voxel {
<Voxel methods>
union {
MailboxPrim *onePrimitive;
MailboxPrim **primitives;
};
u_int allCanIntersect:1;
u_int nPrimitives:31;
}
Packed into 64 bits
![Page 66: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/66.jpg)
AddPrimitivevoid AddPrimitive(MailboxPrim *prim) { if (nPrimitives == 1) {
MailboxPrim **p = new MailboxPrim *[2]; p[0] = onePrimitive; primitives = p; } else if (IsPowerOf2(nPrimitives)) { int nAlloc = 2 * nPrimitives; MailboxPrim **p = new MailboxPrim *[nAlloc]; for (u_int i = 0; i < nPrimitives; ++i) p[i] = primitives[i]; delete[] primitives; primitives = p; } primitives[nPrimitives] = prim; ++nPrimitives;}
![Page 67: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/67.jpg)
GridAccel traversal
bool GridAccel::Intersect(
Ray &ray, Intersection *isect) {
<Check ray against overall grid bounds>
<Get ray mailbox id>
<Set up 3D DDA for ray>
<Walk ray through voxel grid>
}
![Page 68: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/68.jpg)
Check against overall bound
float rayT;
if (bounds.Inside(ray(ray.mint)))
rayT = ray.mint;
else if (!bounds.IntersectP(ray, &rayT))
return false;
Point gridIntersect = ray(rayT);
![Page 69: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/69.jpg)
Set up 3D DDA (Digital Differential Analyzer)• Similar to Bresenhm’s line drawing
algorithm
![Page 70: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/70.jpg)
Set up 3D DDA (Digital Differential Analyzer)
rayT
NextCrossingT[0]
NextCrossingT[1]
Pos
Outvoxel index
Step[0]=1
blue values changes along the traversal
DeltaT[0]
DeltaT: the distance change when voxel changes 1 in that direction
![Page 71: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/71.jpg)
Set up 3D DDAfor (int axis=0; axis<3; ++axis) { Pos[axis]=PosToVoxel(gridIntersect, axis); if (ray.d[axis]>=0) { NextCrossingT[axis] = rayT+
(VoxelToPos(Pos[axis]+1,axis)-gridIntersect[axis]) /ray.d[axis]; DeltaT[axis] = Width[axis] / ray.d[axis]; Step[axis] = 1; Out[axis] = NVoxels[axis]; } else { ... Step[axis] = -1; Out[axis] = -1; }}
1
Dx
Width[0]
![Page 72: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/72.jpg)
Walk through grid
for (;;) {
*voxel=voxels[Offset(Pos[0],Pos[1],Pos[2])];
if (voxel != NULL)
hitSomething |=
voxel->Intersect(ray,isect,rayId);
<Advance to next voxel>
}
return hitSomething;
Do not return; cut tmax insteadReturn when entering a voxel that is beyond the closest found intersection.
![Page 73: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/73.jpg)
Advance to next voxelint bits=((NextCrossingT[0]<NextCrossingT[1])<<2) + ((NextCrossingT[0]<NextCrossingT[2])<<1) + ((NextCrossingT[1]<NextCrossingT[2]));const int cmpToAxis[8] = { 2, 1, 2, 1, 2, 2, 0, 0 }; int stepAxis=cmpToAxis[bits]; if (ray.maxt < NextCrossingT[stepAxis]) break; Pos[stepAxis]+=Step[stepAxis]; if (Pos[stepAxis] == Out[stepAxis]) break; NextCrossingT[stepAxis] += DeltaT[stepAxis];
![Page 74: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/74.jpg)
conditions
x<y
x<z
y<z
0 0 0 x≥y≥z
2
0 0 1 x≥z>y
1
0 1 0 -
0 1 1 z>x≥y
1
1 0 0 y>x≥z
2
1 0 1 -
1 1 0 y≥z>x
0
1 1 1 z>y>x
0
![Page 75: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/75.jpg)
KD-Tree accelerator
• Non-uniform space subdivision (for example, kd-tree and octree) is better than uniform grid if the scene is irregularly distributed.
![Page 76: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/76.jpg)
Spatial hierarchies
A
A
Letters correspond to planes (A)
Point Location by recursive search
![Page 77: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/77.jpg)
Spatial hierarchies
B
A
B
A
Letters correspond to planes (A, B)
Point Location by recursive search
![Page 78: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/78.jpg)
Spatial hierarchies
CB
D
C
D
A
B
A
Letters correspond to planes (A, B, C, D)
Point Location by recursive search
![Page 79: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/79.jpg)
Variations
octreekd-tree bsp-tree
![Page 80: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/80.jpg)
“Hack” kd-tree building
• Split axis– Round-robin; largest extent
• Split location– Middle of extent; median of geometry
(balanced tree)
• Termination– Target # of primitives, limited tree depth
• All of these techniques stink.
![Page 81: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/81.jpg)
Building good kd-trees
• What split do we really want?– Clever Idea: the one that makes ray tracing
cheap– Write down an expression of cost and minimize
it– Greedy cost optimization
• What is the cost of tracing a ray through a cell?
Cost(cell) = C_trav + Prob(hit L) * Cost(L) + Prob(hit R) * Cost(R)
![Page 82: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/82.jpg)
Splitting with cost in mind
![Page 83: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/83.jpg)
Split in the middle
• Makes the L & R probabilities equal• Pays no attention to the L & R costs
To get through this part of empty space, you need to test all triangles on the right.
![Page 84: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/84.jpg)
Split at the median
• Makes the L & R costs equal• Pays no attention to the L & R
probabilities
![Page 85: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/85.jpg)
Cost-optimized split
• Automatically and rapidly isolates complexity
• Produces large chunks of empty space
Since Cost(R) is much higher, make it as small as possible
![Page 86: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/86.jpg)
Building good kd-trees
• Need the probabilities– Turns out to be proportional to surface area
• Need the child cell costs– Simple triangle count works great (very rough
approx.)– Empty cell “boost”
Cost(cell) = C_trav + Prob(hit L) * Cost(L) + Prob(hit R) * Cost(R)
= C_trav + SA(L) * TriCount(L) + SA(R) * TriCount(R)
C_trav is the ratio of the cost to traverse to the cost to intersect
C_trav = 1:80 in pbrt (found by experiments)
![Page 87: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/87.jpg)
Surface area heuristic
aa
Sp
S b
b
Sp
S
2n splits;must coincides with object boundary. Why?
a b
![Page 88: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/88.jpg)
Termination criteria
• When should we stop splitting?– Bad: depth limit, number of triangles– Good: when split does not help any more.
• Threshold of cost improvement– Stretch over multiple levels– For example, if cost does not go down after
three splits in a row, terminate
• Threshold of cell size– Absolute probability SA(node)/SA(scene) small
![Page 89: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/89.jpg)
Basic building algorithm
1. Pick an axis, or optimize across all three2. Build a set of candidate split locations
(cost extrema must be at bbox vertices)3. Sort or bin the triangles4. Sweep to incrementally track L/R counts,
cost5. Output position of minimum cost splitRunning time:
• Characteristics of highly optimized tree– very deep, very small leaves, big empty cells
NNNT
NTNNNT2log)(
)2/(2log)(
![Page 90: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/90.jpg)
Ray traversal algorithm
• Recursive inorder traversal
mint
maxt *t
max *t t
*t
min max*t t t
*t
min*t t
Intersect(L,tmin,tmax) Intersect(R,tmin,tmax)Intersect(L,tmin,t*)Intersect(R,t*,tmax)
a video for kdtree
![Page 91: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/91.jpg)
Tree representation
8-byte (reduced from 16-byte, 20% gain)struct KdAccelNode { ... union { u_int flags; // Both float split; // Interior u_int nPrims; // Leaf }; union { u_int aboveChild; // Interior MailboxPrim *onePrimitive; // Leaf MailboxPrim **primitives; // Leaf };}
interior
n
leaf
![Page 92: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/92.jpg)
Tree representation
Flag: 0,1,2 (interior x, y, z) 3 (leaf)
S E M
flags
1 8 23
2
n
![Page 93: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/93.jpg)
KdTreeAccel construction
• Recursive top-down algorithm• max depth =
If (nPrims <= maxPrims || depth==0) {
<create leaf>
}
)log(3.18 N
![Page 94: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/94.jpg)
Interior node
• Choose split axis position– Medpoint– Medium cut– Area heuristic
• Create leaf if no good splits were found• Classify primitives with respect to split
![Page 95: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/95.jpg)
Choose split axis position
cost of split:
cost of no split:
N
ki kt
1
)(
AB N
kkiA
N
kkiBt atPbtPt
11
)()(
cost of split:
cost of no split:
Nti))(1( AABBeit NpNpbtt
A
B
s
sABp )|(
B CA
assumptions: 1. ti is the same for all primitives
2. ti : tt = 80 : 1 (determined by experiments, main factor for the performance)
![Page 96: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/96.jpg)
Choose split axis position
Start from the axis with maximum extent, sort all edge events and process them in order
A
B
C
a0 b0 a1 b1 c0 c1
![Page 97: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/97.jpg)
Choose split axis position
If there is no split along this axis, try other axes. When all fail, create a leaf.
![Page 98: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/98.jpg)
KdTreeAccel traversal
![Page 99: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/99.jpg)
KdTreeAccel traversal
tmax
tmin
tplane
far near
ToDo stack
![Page 100: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/100.jpg)
KdTreeAccel traversal
tmin
tmax
far near
ToDo stack
![Page 101: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/101.jpg)
KdTreeAccel traversal
tmax
tminToDo stack
tplane
near
far
![Page 102: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/102.jpg)
KdTreeAccel traversal
tminToDo stack
tmax
![Page 103: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/103.jpg)
KdTreeAccel traversal
tminToDo stack
tmax
![Page 104: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/104.jpg)
KdTreeAccel traversal
bool KdTreeAccel::Intersect (const Ray &ray, Intersection *isect) { if (!bounds.IntersectP(ray, &tmin, &tmax)) return false;
KdAccelNode *node=&nodes[0]; while (node!=NULL) { if (ray.maxt<tmin) break; if (!node->IsLeaf()) <Interior> else <Leaf> }}
ToDo stack(max depth)
![Page 105: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/105.jpg)
Leaf node
1. Check whether ray intersects primitive(s) inside the node; update ray’s maxt
2. Grab next node from ToDo queue
![Page 106: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/106.jpg)
1. Determine near and far (by testing which side O is)
2. Determine whether we can skip a node
Interior node
below above
node+1 &(nodes[node->aboveChild])
near far near far
tplane
tplane tplane tmin
tmaxtmin
tmax
![Page 107: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/107.jpg)
Acceleration techniques
![Page 108: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/108.jpg)
Best efficiency scheme
![Page 109: Acceleration](https://reader036.fdocuments.in/reader036/viewer/2022062518/56814bf1550346895db8db06/html5/thumbnails/109.jpg)
References
• J. Goldsmith and J. Salmon, Automatic Creation of Object Hierarchies for Ray Tracing, IEEE CG&A, 1987.
• Brian Smits, Efficiency Issues for Ray Tracing, Journal of Graphics Tools, 1998.
• K. Klimaszewski and T. Sederberg, Faster Ray Tracing Using Adaptive Grids, IEEE CG&A Jan/Feb 1999.
• Whang et. al., Octree-R: An Adaptive Octree for efficient ray tracing, IEEE TVCG 1(4), 1995.
• A. Glassner, Space subdivision for fast ray tracing. IEEE CG&A, 4(10), 1984