Half Edges and Ray Tracing
Computer Graphics and Imaging
UC Berkeley CS 184/284A
Discussion 07
Worksheet 6 link!
https://tinyurl.com/quarteredge
Have you guys seen subdivision memes
https://youtu.be/ipvwpJusp2Y?si=17m_ZbZzMa2FXM1e
Week 7 Announcements
alarmASSIGNMENT
Homework 2
Deadline
Code / write-up:
Friday (10/08)!
scheduleLOCATION & TIMES
Office Hours / HW Party
@ Cory 531!
Snacks provided so come hangout / lock-in together!
groupsCOLLABORATION
Exam 1
Ed #94 [Exam 1] Logistics
Disc 6 Review!
Review Discussion
1. Cubic Hermite Interpolation
2. Catmull-Rom Interpolation
3. de Casteljau’s algorithm
Half-Edges
Half-Edge Background
Preferred way to represent 3D shapes: Meshes
Many ways to represent meshes:
Downsides: hard to edit, store redundant data, hard to navigate
8
The Half-Edge Data Structure
struct Halfedge {
Halfedge *twin,
Halfedge *next;
Vertex *vertex;
Edge *edge;
Face *face;
}
struct Vertex {
Point pt;
Halfedge *halfedge;
}
struct Edge {
Halfedge *halfedge;
}
struct Face {
Halfedge *halfedge;
}
Key idea: two half edges act as “glue” between mesh elements
Each vertex, edge, and face points to one of its half edges
next
halfedge
next
Face
twin
edge
vertex
The Half-Edge Data Structure
struct Halfedge {
Halfedge *twin,
Halfedge *next;
Vertex *vertex;
Edge *edge;
Face *face;
}
struct Vertex {
Point pt;
Halfedge *halfedge;
}
struct Edge {
Halfedge *halfedge;
}
struct Face {
Halfedge *halfedge;
}
Key idea: two half edges act as “glue” between mesh elements
Each vertex, edge, and face points to one of its half edges
next
halfedge
next
Face
twin
edge
vertex
The Half-Edge Data Structure
struct Halfedge {
Halfedge *twin,
Halfedge *next;
Vertex *vertex;
Edge *edge;
Face *face;
}
struct Vertex {
Point pt;
Halfedge *halfedge;
}
struct Edge {
Halfedge *halfedge;
}
struct Face {
Halfedge *halfedge;
}
Key idea: two half edges act as “glue” between mesh elements
Each vertex, edge, and face points to one of its half edges
next
halfedge
next
Face
twin
edge
vertex
The Half-Edge Data Structure
struct Halfedge {
Halfedge *twin,
Halfedge *next;
Vertex *vertex;
Edge *edge;
Face *face;
}
struct Vertex {
Point pt;
Halfedge *halfedge;
}
struct Edge {
Halfedge *halfedge;
}
struct Face {
Halfedge *halfedge;
}
Key idea: two half edges act as “glue” between mesh elements
Each vertex, edge, and face points to one of its half edges
next
halfedge
next
Face
twin
edge
vertex
The Half-Edge Data Structure & Mesh Traversal
Halfedge *h = f->halfedge;
do {
process(h->vertex);
h = h->next;
} while (h != f->halfedge);
Use twin and next pointers to move around the mesh
You can process vertex, edge, and/or face pointers
Example 1: Process all vertices of a face
next
halfedge
next
Face
Mesh Traversal
halfedge
next
twin
edge
Mesh Traversal
halfedge
next
edge
twin
Mesh Traversal
halfedge
next
twin
edge
Note: We denote e.g. a pointer to an Edge by EdgeIter. So the following initialization is valid, given EdgeIter e:
HalfedgeIter h = e→halfedge();
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
std::vector<EdgeIter> getOppositeEdges(VertexIter v)
{
std::vector<EdgeIter> edges;
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
do {
edges.push_back(h->next()->edge());
h = h->next()->next()->twin();
} while (h != start_h);
return edges;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
void diffuse(VertexIter v, float k)
{
Vector3D L(0, 0, 0);
HalfedgeIter h = v->halfedge();
HalfedgeIter start_h = h;
int n = 0;
do {
VertexIter v_j = h->next()->vertex();
Vector3D dir = v_j->position() - v->position();
L = L + dir;
n++;
h = h->twin()->next()
} while (h != start_h);
v->position() = v->position() + k * L / n;
}
Local Operations
Local Operations - Edge Flip
34
a
b
d
c
Triangles (a, b, c), (b, d, c) become (a, d, c), (a, b, d):
flip
Local Operations - Edge Flip
35
a
b
d
c
c
a
b
d
Triangles (a, b, c), (b, d, c) become (a, d, c), (a, b, d):
flip
Local Operations - Edge Split
36
a
b
d
c
Insert midpoint m of edge (c, b), connect to get four triangles:
split
Local Operations - Edge Split
37
a
b
d
c
c
a
b
d
Insert midpoint m of edge (c, b), connect to get four triangles:
split
m
Local Operations - Edge Collapse
38
Replace edge (c, d) with a single vertex m:
collapse
a
b
c
d
a
b
c
d
Local Operations - Edge Collapse
39
Replace edge (c, d) with a single vertex m:
collapse
a
b
c
d
a
b
c
d
c
d
Local Operations - Edge Collapse
40
Replace edge (c, d) with a single vertex m:
collapse
a
b
c
d
a
b
d
m
41
a
b
c
d
42
a
b
c
d
43
a
b
m
Local Operations
a
b
d
c
flip
c
a
b
d
split
c
a
b
d
m
a
b
d
c
a
b
c
d
b
c
d
c
d
collapse
d
m
e0
e0
any of e0, e10, e11
e0
any of e0, e10, e11
any of e0, e9, e12, e16
e0
f4, e3->next() = e12
any of e0, e10, e11
any of e0, e9, e12, e16
e0
V0
any of e0, e10, e11
any of e0, e9, e12, e16
f4, e3->next() = e12
e0
V0
any of e0, e10, e11
any of e0, e9, e12, e16
either of e6, e10
f4, e3->next() = e12
e0
any of e0, e10, e11
any of e0, e9, e12, e16
V0
either of e6, e10
e13->next() = e3
f4->halfedge() = any of e3, e12, e13
e0->face() = f3
e0->next() = e10
V3->halfedge() = either of e3, e14
f4, e3->next() = e12
Subdivision
Subdivision Motivation
55
Subdivision Motivation
56
Loop Subdivision
57
Loop Subdivision
1/8
3/8
3/8
1/8
New vertices
Old vertices
u
u
u
u
u
u
1 - n*u
n: vertex degree
u: 3/16 if n = 3, 3/(8n) otherwise
Loop Subdivision
59
Example: degree 6
1/16
1/16
1/16
1/16
1/16
1/16
10/16
Loop Subdivision Example
Loop Subdivision Example
61
Worksheet Question 2
A
B
C
D
E
F
G
This result depends on the order that edges are processed in! ��Do you see why?
This result depends on the order that edges are processed in! ��Do you see why?
For any new edge that connects new vertex to old vertex…
This result depends on the order that edges are processed in! ��Do you see why?
For any new edge that connects new vertex to old vertex…
Edge flip!
This result depends on the order that edges are processed in! ��Do you see why?
For any new edge that connects new vertex to old vertex…
Edge flip!
This completes the face splitting procedure.
<= hint
The position of a new vertex unchanged if and only if the midpoint of the opposite vertices A and C lies at the exact same location as the midpoint of edge BD (i.e., when $A, B, C, D$ form a parallelogram)
Proof:
Set V_new = midpoint of BD
Hint:
Loop Subdivision
1/8
3/8
3/8
1/8
New vertices
Old vertices
u
u
u
u
u
u
1 - n*u
n: vertex degree
u: 3/16 if n = 3, 3/(8n) otherwise
Hint:
Since n = 5,
weight u = 3/8n = 3/40
So v’_old = (1 - 5 * (3/40)) * (4, 2, 0) + (3/40) * (25, 15, 0)
=
Solution:
towards the centroid (average position) of its 1-ring neighboring vertices
Slide link!
https://tinyurl.com/4ns3tdab
D7 Attendance!
https://tinyurl.com/4p3xcpsx
Attendance Code:
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
Procedure:
86
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
For each face, add a face point and set its position to be the average of all original points in the same face.
87
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
2. Add edge point:
For each edge, add an edge point and set its position to be the average of 2 neighboring face points (AF) and the midpoint of the edge (ME).
88
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
3. Move original vertices:
For each original vertex (P), take the average (F) of all n neighboring face points, and the average (R) of all n midpoints on neighboring edges (Note: edge midpoint is not the same as edge point! )
Move each vertex to
89
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
4. Form new edges and faces:
Connect each new face point to the new edge points of all original edges defining the original face
90
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
4. Form new edges and faces:
Connect each new vertex point to the new edge points of all original edges incident on the original vertex
91
Catmull-Clark Subdivision
Designed for meshes with variable polygons (triangles/quadrilaterals/pentagons)
4. Form new edges and faces:
Define new faces as enclosed by the new edges.
92
Catmull-Clark Subdivision Example
93
Ray Tracing Basics
Ray Equation
r(t) = o + td
Ray Tracing
Ray Tracing
Bonus Question!
How would you check if an intersection is inside a triangle?
Bonus Question!
How would you check if an intersection is inside a triangle?
Try placing the ray in this diagram to get intuition
Try placing the ray in this diagram to get intuition
Ray Triangle Intersection
Last week: Ray-Plane Intersection
Ray Triangle Intersection
But meshes are made of triangles, so we need ray-triangle intersection!
116
Last week:
Ray Triangle Intersection
Ray Triangle Intersection Derivation
118
Acceleration Structures
Acceleration Structures Motivation
127
Sneak Peek
In the next assignment, you will be able to render images like these!
128
Idea: Bounding Volume Hierarchy
Internal nodes:
129
Idea: Bounding Volume Hierarchy
Internal nodes:
130
Leaf nodes:
Worksheet Question 2
132
133
split this side
134
split this side
135
There are 2 valid splits!
136
We’ll just consider this one.
137
138
139
140
141
142
143
Using a Bounding Volume Hierarchy
144
Using a Bounding Volume Hierarchy
145
Using a Bounding Volume Hierarchy
146
Using a Bounding Volume Hierarchy
147
Using a Bounding Volume Hierarchy
148
Using a Bounding Volume Hierarchy
149
Using a Bounding Volume Hierarchy
150
Using a Bounding Volume Hierarchy
151
Using a Bounding Volume Hierarchy
152
Using a Bounding Volume Hierarchy
153
Using a Bounding Volume Hierarchy
154
Using a Bounding Volume Hierarchy
155
Using a Bounding Volume Hierarchy
156
2.2. Using a Bounding Volume Hierarchy
158
Hint: Axis-aligned ray-plane intersection equation
2.2. Using a Bounding Volume Hierarchy
159
2.2. Using a Bounding Volume Hierarchy
160
2.2. Using a Bounding Volume Hierarchy
161
Radiometry & Photometry
Radiometry
Flux (Power) is measured in Watts.
Radiometry
Flux (Power) is measured in Watts.
Radiant intensity is flux per solid angle.
Radiometry
Flux (Power) is measured in Watts.
Radiant intensity is flux per solid angle.
Radiance is flux per area per solid angle.
AKA brightness!
Radiometry
Flux (Power) is measured in Watts.
Radiant intensity is flux per solid angle.
Irradiance is flux per area.
Radiance is flux per area per solid angle.
AKA brightness!
Radiant flux is energy received per time. Watts.
Radiant (luminous) flux is energy received per time. Watts (lumens).
Photometry mirrors radiometry but adjusts for human vision.
Radiant (luminous) intensity is flux per solid angle. W/sr (candela).
Radiant (luminous) flux is energy received per time. Watts (lumens).
Photometry mirrors radiometry but adjusts for human vision.
Radiant (luminous) intensity is flux per solid angle. W/sr (candela).
Radiant (luminous) flux is energy received per time. Watts (lumens).
Radiance is flux per area per solid angle. W/(sr m2) (nit).
Photometry mirrors radiometry but adjusts for human vision.
Radiant (luminous) intensity is flux per solid angle. W/sr (candela).
Irradiance is flux per area.
W/m2 (lux).
Radiant (luminous) flux is energy received per time. Watts (lumens).
Radiance is flux per area per solid angle. W/(sr m2) (nit).
Photometry mirrors radiometry but adjusts for human vision.
Radiant (luminous) intensity is flux per solid angle. W/sr (candela).
Irradiance is flux per area.
W/m2 (lux).
Radiant (luminous) flux is energy received per time. Watts (lumens).
n
l
θ
Lambert’s cosine law
Radiance is flux per area per solid angle. W/(sr m2) (nit).
Photometry mirrors radiometry but adjusts for human vision.
3.1. Radiometry Definitions and Relations
173
3.1. Radiometry Definitions and Relations
174
3.1. Radiometry Definitions and Relations
3.1. Radiometry Definitions and Relations
177
Solid Angle
178
Solid Angle
179
Solid Angle
180
Approximate dA as a rectangle!
Solid Angle
181
How do we approximate?
Solid Angle
182
How do we approximate?
Solid Angle
183
How do we approximate?
θ
dθ
r
r dθ
Solid Angle
184
How do we approximate?
Solid Angle
185
How do we approximate?
Solid Angle
186
How do we approximate?
φ
dφ
r sin θ
r sin θ dφ
Solid Angle
187
Worksheet Question 4.1
4 Shedding Some Light
189
4 Shedding Some Light
190
3.2. Solid Angle
191
Approximate this value
as a rectangle.
Recall the arclength of a circle: L = r · 𝜃
What’s the radius of this circle?
What’s the radius of this circle?
3.2. Solid Angle
192
193
194
195
Lambert’s Cosine Law
197
Definition: The radiance (luminance) is the power emitted by a surface, per unit solid angle, per unit projected area.
199
Light Emitted By A Surface
“Surface Radiance”
Units Summary
Units Summary
Units Summary
203
A scales as R2, so E(x) decreases as R increases.
Units Summary
Units Summary
Worksheet Question 4.2
4.2 Irradiance Calculation
207
4.2 Irradiance Calculation
208
Irradiance is power/area:
2πr2
Φ
cos(Ө)
4.2 Irradiance Calculation
209
Irradiance is power/area:
What do we know?
2πr2
Φ
cos(Ө)
4.2 Irradiance Calculation
210
Irradiance is power/area:
What do we know?
Φ = 100 W
What do we not know?
2πr2
Φ
cos(Ө)
4.2 Irradiance Calculation
211
Irradiance is power/area:
What do we know?
Φ = 100 W
What do we not know?
r, Ө
2πr2
Φ
cos(Ө)
4.2 Irradiance Calculation
212
Irradiance is power/area:
Use the Pythagorean Theorem
r = (62 + 82)½ = 10
This is r !
2πr2
Φ
cos(Ө)
4.2 Irradiance Calculation
213
=
Irradiance is power/area:
Cosine angle between surface normal and the light position is given by the dot product of normalized vectors:
cos(Ө) = (6, 0, 8)/10 · (1, 1, 1)/√3
10√3
14
2πr2
Φ
cos(Ө)
normal
Ө
4.2 Irradiance Calculation
214
=
Irradiance is power/area:
E =
2πr2
Φ
cos(Ө)
2πr2
Φ
cos(Ө)
2π(10)2
100
10√3
14
W/m2
=
10π√3
7
W/m2
215
1
Light Source
Surface 1:
Irradiance = E
Solid Angle = w
Surface 2:
Irradiance = E / r2
Solid Angle = w / r2
r
How does radiance change with distance?
Hint:�
1. The light source emits uniform flux.��2. With irradiance E and solid angle w at surface 1, what are these values at the surface 2?
216
1
Light Source
Surface 1:
Irradiance = E
Solid Angle = w
Surface 2:
Irradiance = E / r2
Solid Angle = w / r2
r
Since L = dE / dw (cos θ = 1 here), the radiance at the two surfaces is the same.
Radiance does not change with distance.
217