Optimism in Design

?

?

W, K, P / S, J, N Jump to previous / next timestamp

t / T Toggle theatre / SUPERtheatre mode

V Revert filter to original state Y Select link (requires manual Ctrl-c)

X, ShiftSpace Toggle category and focus previous

v Invert topics / media as per focus

# Keyboard Navigation

## Global Keys

[, < / ], > Jump to previous / next episodeW, K, P / S, J, N Jump to previous / next timestamp

t / T Toggle theatre / SUPERtheatre mode

V Revert filter to original state Y Select link (requires manual Ctrl-c)

## Menu toggling

q Quotes r References f Filter y Link c Credits## In-Menu and Index Controls

a

w

s

s

d

h
j
k
l

←

↑

↓

↓

→

Esc Close menu / unfocus timestamp

## Quotes and References Menus and Index

Enter Jump to timestamp## Quotes, References and Credits Menus

o Open URL (in new tab)## Filter Menu

x, Space Toggle category and focus nextX, ShiftSpace Toggle category and focus previous

v Invert topics / media as per focus

## Filter and Link Menus

z Toggle filter / linking mode## Credits Menu

Enter Open URL (in new tab)⏫

Previous: 'LibQuincy'

⏫

0:00 : Welcome Davis

0:00 : Welcome Davis

0:00 : Welcome Davis

0:36 : Clarification: Covering a rasterised version of voxel engines

0:36 : Clarification: Covering a rasterised version of voxel engines

0:36 : Clarification: Covering a rasterised version of voxel engines

0:50 : Optimism in Design: A Talk About Voxels

0:50 : Optimism in Design: A Talk About Voxels

0:50 : Optimism in Design: A Talk About Voxels

0:54 : Let's create a voxel engine

0:54 : Let's create a voxel engine

0:54 : Let's create a voxel engine

1:01 : Well, what even is a voxel?

1:01 : Well, what even is a voxel?

1:01 : Well, what even is a voxel?

1:14 : A Point in a 3D Grid

1:14 : A Point in a 3D Grid

1:14 : A Point in a 3D Grid

1:25 : What space does our grid exist in?

1:25 : What space does our grid exist in?

1:25 : What space does our grid exist in?

1:37 : What data should our voxel have?

1:37 : What data should our voxel have?

1:37 : What data should our voxel have?

1:47 : What kinds of voxels do we want to start with?

1:47 : What kinds of voxels do we want to start with?

1:47 : What kinds of voxels do we want to start with?

2:01 : Next, let's assign IDs

2:01 : Next, let's assign IDs

2:01 : Next, let's assign IDs

2:14 : What does our voxel look like in memory?

2:14 : What does our voxel look like in memory?

2:14 : What does our voxel look like in memory?

2:21 : A voxel with its type in a 3D grid

2:21 : A voxel with its type in a 3D grid

2:21 : A voxel with its type in a 3D grid

2:27 : What is our volume? What kind of world do we want to have?

2:27 : What is our volume? What kind of world do we want to have?

2:27 : What is our volume? What kind of world do we want to have?

2:35 : Instead of having one massive world…

2:35 : Instead of having one massive world…

2:35 : Instead of having one massive world…

2:50 : …we can break it up into smaller chunks

2:50 : …we can break it up into smaller chunks

2:50 : …we can break it up into smaller chunks

3:01 : Now we can be focused in how we update things

3:01 : Now we can be focused in how we update things

3:01 : Now we can be focused in how we update things

3:10 : But what size should these smaller chunks be? It's a balancing act

3:10 : But what size should these smaller chunks be? It's a balancing act

3:10 : But what size should these smaller chunks be? It's a balancing act

3:24 : For convenience later, let's go with a size of 64

3:24 : For convenience later, let's go with a size of 64

3:24 : For convenience later, let's go with a size of 64

3:43 : Now our world is made up of 64³ chunks

3:43 : Now our world is made up of 64³ chunks

3:43 : Now our world is made up of 64³ chunks

3:49 : What does our chunk look like in memory?

3:49 : What does our chunk look like in memory?

3:49 : What does our chunk look like in memory?

4:14 : How to compose a 3D position into a single digit?

4:14 : How to compose a 3D position into a single digit?

4:14 : How to compose a 3D position into a single digit?

4:17 : 3D Position to a Single Index: x

4:17 : 3D Position to a Single Index: x

4:17 : 3D Position to a Single Index: x

4:44 : 3D Position to a Single Index: x, z

4:44 : 3D Position to a Single Index: x, z

4:44 : 3D Position to a Single Index: x, z

5:30 : 3D Position to a Single Index: x, y, z

5:30 : 3D Position to a Single Index: x, y, z

5:30 : 3D Position to a Single Index: x, y, z

5:45 : 3D Position to a Single Index: Completed Formula

5:45 : 3D Position to a Single Index: Completed Formula

5:45 : 3D Position to a Single Index: Completed Formula

5:59 : Index Back to 3D Position

5:59 : Index Back to 3D Position

5:59 : Index Back to 3D Position

6:40 : Now we can define what our chunk looks like in memory

6:40 : Now we can define what our chunk looks like in memory

6:40 : Now we can define what our chunk looks like in memory

6:53 : What about our world?

6:53 : What about our world?

6:53 : What about our world?

7:21 : Now that we have everything in memory, how do we get it all on the screen?

7:21 : Now that we have everything in memory, how do we get it all on the screen?

7:21 : Now that we have everything in memory, how do we get it all on the screen?

7:30 : Let's start with a single voxel

7:30 : Let's start with a single voxel

7:30 : Let's start with a single voxel

7:37 : How is a voxel going to be represented in our world?

7:37 : How is a voxel going to be represented in our world?

7:37 : How is a voxel going to be represented in our world?

7:45 : Let's say our voxel is geometrically a cube. How can we draw it?

7:45 : Let's say our voxel is geometrically a cube. How can we draw it?

7:45 : Let's say our voxel is geometrically a cube. How can we draw it?

7:51 : How can we draw a voxel?

7:51 : How can we draw a voxel?

7:51 : How can we draw a voxel?

8:13 : What is our vertex made of?

8:13 : What is our vertex made of?

8:13 : What is our vertex made of?

8:48 : Now, we can draw our cube

8:48 : Now, we can draw our cube

8:48 : Now, we can draw our cube

8:54 : How do we do this for the entire world?

8:54 : How do we do this for the entire world?

8:54 : How do we do this for the entire world?

8:57 : Wait, that's overkill

8:57 : Wait, that's overkill

8:57 : Wait, that's overkill

9:16 : Naively extracting a mesh, or Naive Meshing

9:16 : Naively extracting a mesh, or Naive Meshing

9:16 : Naively extracting a mesh, or Naive Meshing

9:39 : Next, let's do this for every voxel in our chunk

9:39 : Next, let's do this for every voxel in our chunk

9:39 : Next, let's do this for every voxel in our chunk

9:59 : Great, so now we're done, right?

9:59 : Great, so now we're done, right?

9:59 : Great, so now we're done, right?

10:08 : It's kind of slow

10:08 : It's kind of slow

10:08 : It's kind of slow

10:37 : We can do better, with Greedy Meshing

10:37 : We can do better, with Greedy Meshing

10:37 : We can do better, with Greedy Meshing

10:41 : What is Greedy Meshing?

10:41 : What is Greedy Meshing?

10:41 : What is Greedy Meshing?

10:50 : How are we able to join faces?

10:50 : How are we able to join faces?

10:50 : How are we able to join faces?

11:17 : That's great, but how does it actually work?

11:17 : That's great, but how does it actually work?

11:17 : That's great, but how does it actually work?

11:21 : Let's take a 2D slice of our world

11:21 : Let's take a 2D slice of our world

11:21 : Let's take a 2D slice of our world

11:28 : To start, we can focus on those sand blocks

11:28 : To start, we can focus on those sand blocks

11:28 : To start, we can focus on those sand blocks

11:32 : Then, we'll start at the bottom left voxel

11:32 : Then, we'll start at the bottom left voxel

11:32 : Then, we'll start at the bottom left voxel

11:38 : At first, we try to grow vertically

11:38 : At first, we try to grow vertically

11:38 : At first, we try to grow vertically

12:05 : Since we can't grow vertically anymore, let's grow horizontally

12:05 : Since we can't grow vertically anymore, let's grow horizontally

12:05 : Since we can't grow vertically anymore, let's grow horizontally

12:30 : Let's apply this algorithm to the rest of our scene

12:30 : Let's apply this algorithm to the rest of our scene

12:30 : Let's apply this algorithm to the rest of our scene

12:34 : Nice! That's a significant reduction in faces

12:34 : Nice! That's a significant reduction in faces

12:34 : Nice! That's a significant reduction in faces

12:57 : Can we do better?

12:57 : Can we do better?

12:57 : Can we do better?

13:19 : What are we currently limited by?

13:19 : What are we currently limited by?

13:19 : What are we currently limited by?

13:37 : What makes up our Vertex?

13:37 : What makes up our Vertex?

13:37 : What makes up our Vertex?

13:59 : Instead, we can upload the type buffer directly to the GPU

13:59 : Instead, we can upload the type buffer directly to the GPU

13:59 : Instead, we can upload the type buffer directly to the GPU

14:29 : We aren't getting rid of any data, we're just moving it around

14:29 : We aren't getting rid of any data, we're just moving it around

14:29 : We aren't getting rid of any data, we're just moving it around

14:40 : Where does this leave us?

14:40 : Where does this leave us?

14:40 : Where does this leave us?

14:43 : Now instead of having to only mesh similar types…

14:43 : Now instead of having to only mesh similar types…

14:43 : Now instead of having to only mesh similar types…

14:48 : …it's become a binary problem!

14:48 : …it's become a binary problem!

14:48 : …it's become a binary problem!

14:58 : We can now mesh all faces without discrimination

14:58 : We can now mesh all faces without discrimination

14:58 : We can now mesh all faces without discrimination

15:29 : Okay, do we still have to work with IDs?

15:29 : Okay, do we still have to work with IDs?

15:29 : Okay, do we still have to work with IDs?

15:33 : It's a binary problem, so we only need a binary representation of our scene

15:33 : It's a binary problem, so we only need a binary representation of our scene

15:33 : It's a binary problem, so we only need a binary representation of our scene

15:48 : Right now, our chunk is a 3D grid of voxel structs stored in an array

15:48 : Right now, our chunk is a 3D grid of voxel structs stored in an array

15:48 : Right now, our chunk is a 3D grid of voxel structs stored in an array

16:01 : What we can use as a binary representation of our voxel data is an array of bits

16:01 : What we can use as a binary representation of our voxel data is an array of bits

16:01 : What we can use as a binary representation of our voxel data is an array of bits

16:14 : Let's make a bit array

16:14 : Let's make a bit array

16:14 : Let's make a bit array

16:17 : Let's make a bit array: First, we take our current index formula and chop off the Y

16:17 : Let's make a bit array: First, we take our current index formula and chop off the Y

16:17 : Let's make a bit array: First, we take our current index formula and chop off the Y

16:22 : Let's make a bit array: That index can then access a column in an array of unsigned 64-bit integers

16:22 : Let's make a bit array: That index can then access a column in an array of unsigned 64-bit integers

16:26 : Let's make a bit array: And then Y can be used to index into a voxel at a specific height in this column

16:26 : Let's make a bit array: And then Y can be used to index into a voxel at a specific height in this column

16:49 : So now that we can, let's turn our scene into binary

16:49 : So now that we can, let's turn our scene into binary

16:49 : So now that we can, let's turn our scene into binary

16:57 : All set voxels become ones, and all air voxels become zeros

16:57 : All set voxels become ones, and all air voxels become zeros

16:57 : All set voxels become ones, and all air voxels become zeros

17:10 : Before we combine our faces, what are 64-bit integers perfect for?

17:10 : Before we combine our faces, what are 64-bit integers perfect for?

17:10 : Before we combine our faces, what are 64-bit integers perfect for?

17:15 : Bitwise Operations!

17:15 : Bitwise Operations!

17:15 : Bitwise Operations!

17:20 : Bitwise ANDs

17:20 : Bitwise ANDs

17:20 : Bitwise ANDs

17:37 : Considering 64 voxels at once with bitwise AND Meshing

17:37 : Considering 64 voxels at once with bitwise AND Meshing

17:37 : Considering 64 voxels at once with bitwise AND Meshing

18:26 : We've significantly reduced the amount of operations too!

18:26 : We've significantly reduced the amount of operations too!

18:26 : We've significantly reduced the amount of operations too!

18:58 : Alright, but there is a property of voxel worlds that we're ignoring

18:58 : Alright, but there is a property of voxel worlds that we're ignoring

18:58 : Alright, but there is a property of voxel worlds that we're ignoring

19:02 : They often have a more complicated 3D scene

19:02 : They often have a more complicated 3D scene

19:02 : They often have a more complicated 3D scene

19:17 : If we take that scene and turn it into bits…

19:17 : If we take that scene and turn it into bits…

19:17 : If we take that scene and turn it into bits…

19:20 : …we see we need to take that bitwise AND idea and make it work with "3D" columns

19:20 : …we see we need to take that bitwise AND idea and make it work with "3D" columns

19:20 : …we see we need to take that bitwise AND idea and make it work with "3D" columns

19:34 : We can do that by breaking down the problem into smaller parts

19:34 : We can do that by breaking down the problem into smaller parts

19:34 : We can do that by breaking down the problem into smaller parts

19:43 : How can we extract the first two set bits here?

19:43 : How can we extract the first two set bits here?

19:43 : How can we extract the first two set bits here?

19:51 : We can use something that 64-bit integers are also great for: intrinsics, specifically one called Trailing Zero Count

19:51 : We can use something that 64-bit integers are also great for: intrinsics, specifically one called Trailing Zero Count

20:01 : To start, we take the first column and invert it

20:01 : To start, we take the first column and invert it

20:01 : To start, we take the first column and invert it

20:06 : Then we count the first series of zeros, which is our first set bits inverted

20:06 : Then we count the first series of zeros, which is our first set bits inverted

20:06 : Then we count the first series of zeros, which is our first set bits inverted

20:13 : Now we can create a new mask

20:13 : Now we can create a new mask

20:13 : Now we can create a new mask

20:17 : We can then use this mask to compare the rest of our columns

20:17 : We can then use this mask to compare the rest of our columns

20:17 : We can then use this mask to compare the rest of our columns

20:31 : We then skip the zeros to get to the next column, and repeat the extraction process

20:31 : We then skip the zeros to get to the next column, and repeat the extraction process

20:31 : We then skip the zeros to get to the next column, and repeat the extraction process

20:55 : Then, we mesh again using this new mask

20:55 : Then, we mesh again using this new mask

20:55 : Then, we mesh again using this new mask

21:02 : We repeat this process for our entire chunk

21:02 : We repeat this process for our entire chunk

21:02 : We repeat this process for our entire chunk

21:10 : We now have our more complicated scene, meshed binarily, using bitwise operations and intrinsics

21:10 : We now have our more complicated scene, meshed binarily, using bitwise operations and intrinsics

21:20 : Let's Talk About Speed

21:20 : Let's Talk About Speed

21:20 : Let's Talk About Speed

21:23 : Old Greedy Meshing times (3–5ms) vs Now (0.12ms) for 64³ area

21:23 : Old Greedy Meshing times (3–5ms) vs Now (0.12ms) for 64³ area

21:23 : Old Greedy Meshing times (3–5ms) vs Now (0.12ms) for 64³ area

22:25 : But we could be faster

22:25 : But we could be faster

22:25 : But we could be faster

22:28 : Simple Thread Queue: on i7 8700k 0.01ms per 64³ chunk on average

22:28 : Simple Thread Queue: on i7 8700k 0.01ms per 64³ chunk on average

22:28 : Simple Thread Queue: on i7 8700k 0.01ms per 64³ chunk on average

24:02 : Old Greedy Meshing times (3–5ms) vs Now (0.01ms) for 64³ area

24:02 : Old Greedy Meshing times (3–5ms) vs Now (0.01ms) for 64³ area

24:02 : Old Greedy Meshing times (3–5ms) vs Now (0.01ms) for 64³ area

24:12 : But we could be even faster

24:12 : But we could be even faster

24:12 : But we could be even faster

24:16 : If we think about it, what are we really doing with our meshing?

24:16 : If we think about it, what are we really doing with our meshing?

24:16 : If we think about it, what are we really doing with our meshing?

24:35 : We could just use one face to represent all possible faces for any slice of voxels

24:35 : We could just use one face to represent all possible faces for any slice of voxels

24:35 : We could just use one face to represent all possible faces for any slice of voxels

25:12 : Let's do this for an entire chunk

25:12 : Let's do this for an entire chunk

25:12 : Let's do this for an entire chunk

25:38 : Let's use this for the entire world!

25:38 : Let's use this for the entire world!

25:38 : Let's use this for the entire world!

25:46 : Global Lattice Stats

25:46 : Global Lattice Stats

25:46 : Global Lattice Stats

27:16 : What does not having to mesh mean?

27:16 : What does not having to mesh mean?

27:16 : What does not having to mesh mean?

28:35 : Statistics

28:35 : Statistics

28:35 : Statistics

28:58 : Let's solve some problems with the Global Lattice

28:58 : Let's solve some problems with the Global Lattice

28:58 : Let's solve some problems with the Global Lattice

29:04 : Global Lattice examples: 1) A Solution for Floating Point Precision, "The Treadmill"

29:04 : Global Lattice examples: 1) A Solution for Floating Point Precision, "The Treadmill"

29:04 : Global Lattice examples: 1) A Solution for Floating Point Precision, "The Treadmill"

30:14 : Global Lattice examples: 1) A Solution for Floating Point Precision, "The Treadmill" illustration

30:14 : Global Lattice examples: 1) A Solution for Floating Point Precision, "The Treadmill" illustration

30:48 : Global Lattice examples: 2) Maximizing What's in View With Frustum Rotation

30:48 : Global Lattice examples: 2) Maximizing What's in View With Frustum Rotation

30:48 : Global Lattice examples: 2) Maximizing What's in View With Frustum Rotation

30:53 : Global Lattice examples: 2) Frustum Rotation

30:53 : Global Lattice examples: 2) Frustum Rotation

30:53 : Global Lattice examples: 2) Frustum Rotation

31:39 : Global Lattice examples: 2) Frustum Rotation with a lower FOV

31:39 : Global Lattice examples: 2) Frustum Rotation with a lower FOV

31:39 : Global Lattice examples: 2) Frustum Rotation with a lower FOV

32:03 : In Conclusion

32:03 : In Conclusion

32:03 : In Conclusion

33:46 : Thanks

^{1}33:46 : Thanks

^{1}33:46 : Thanks

^{1}⏬

Next: 'Optimism in Design - Q&A'

⏬