Voxel Algorithm

Started by
16 comments, last by _swx_ 12 years, 3 months ago
I'd like to implement a piece of voxel terrain, according to this paper:
http://www.terathon.com/lengyel/Lengyel-VoxelTerrain.pdf

but i got really stuck at page 34/35, it's about voxel sharing
(Fig. 3.8a) -> i understand that only on the locations 0,1,2,3 a new vertex is allowed, but what i don't understand is the following 3 Bit direction code!

If you didn't already, read the paper :) it's very intresting - but not very easy, at least for me, to understand

In the event that the sample value at a corner is exactly zero, the vertex lying on any
active edge adjacent to that corner is placed precisely at the corner location. The only
corner at which a new vertex is allowed to be created is corner 7, so vertices for any other
corners must be reused from preceding cells. A 3-bit direction code leading to the proper
cell can easily be obtained by inverting the 3-bit corner index (bitwise, by exclusive
ORing with the number 7), where the bit values 1, 2, and 4 indicate that we must subtract
one from the the x, y, and/or z coordinate, respectively.
For cells occurring along the minimal boundaries of a block, the preceding cells
needed for vertex reuse may not exist. In these cases, we allow new vertex creation on
additional edges of a cell. While iterating through the cells in a block, a 3-bit mask is
maintained whose bits indicate whether corresponding bits in a direction code are valid.
When a direction code is used to locate a preceding cell, it is first ANDed with the
validity mask to determine whether the preceding cell exists, and if not, the creation of a
new vertex in the current cell is permitted. (This test always fails for 4-bit direction codes
having the bit with value 8 set. This is the motivation for assigning the codes 0x81,
0x82, and 0x83 to the maximal edges instead of 0x01, 0x02, and 0x03.)
For each cell, we must have space to store four vertex indexes corresponding to the
locations shown in Figure 3.8(a) so that they can be reused by cells triangulated at a later
time. It is never the case that all four vertex slots are used at once (because a vertex lying
on the interior of an edge implies no vertex at the corner), but we must be able to identify
the vertices using a fixed indexing scheme. The vertices used by a cell are always owned
by the cell itself, the preceding cell in the same row, one of two adjacent cells in the
preceding row, or one of four cells in the preceding deck. We can therefore limit the
36
vertex history that we store while processing a block to two decks containing 16?16 cells
each and ping-pong between them as the z coordinate is incremented.
Advertisement
The 3-bit direction code just tells the triangulation code where to go to find a previously generated vertex that can be reused in the current cell. Direction codes are provided in the data tables and don't need to be generated by your program. As an example, suppose you've determined that a vertex needs to appear on the edge of a cell between corners 4 and 6, then you know that vertex was already created for the cell edge between corners 5 and 7 for the preceding cell in the same row (unless this is the first cell in the row, which is why there's a mask). In this case, the binary direction code is 001, indicating that you subtract 1 from the x-coordinate of the cell. The hex code 0x11 shown in figure 3.8(b) for this case means that you apply the direction code 1 (the high 8 bits) and then choose vertex number 1 (the low 8 bits) from that cell.

The 3-bit direction code just tells the triangulation code where to go to find a previously generated vertex that can be reused in the current cell. Direction codes are provided in the data tables and don't need to be generated by your program. As an example, suppose you've determined that a vertex needs to appear on the edge of a cell between corners 4 and 6, then you know that vertex was already created for the cell edge between corners 5 and 7 for the preceding cell in the same row (unless this is the first cell in the row, which is why there's a mask). In this case, the binary direction code is 001, indicating that you subtract 1 from the x-coordinate of the cell. The hex code 0x11 shown in figure 3.8(b) for this case means that you apply the direction code 1 (the high 8 bits) and then choose vertex number 1 (the low 8 bits) from that cell.


thx for your help!
Wow =) the voxel master replied =) ... i really like your work on the transvoxel algorithm and the c4 engine!!
I've just implemented a veeeery basic version of it in java with jmonkeyengine, for now i'm trying to implement the vertex sharing and triplanar texturing, the LoD approach seems very complicated to me x)
you got your PhD. for this work -> nice ;-) ... just begining my informatics studies in vienna xD

i have a question on voxel terrain / c4 engine in general:
do you generate the terrain by geomtry shader or are you cooking your meshes on the cpu ?
how do you handle collision detection? from voxel data / using the cooked mesh (checking against each triangle) / using a low detail version of the cooked mesh?
do you generate the terrain by geomtry shader or are you cooking your meshes on the cpu ?


Triangle meshes are generated from voxel data on the CPU and stored for later rendering.

how do you handle collision detection? from voxel data / using the cooked mesh (checking against each triangle) / using a low detail version of the cooked mesh?


The triangles for the highest-detail terrain mesh are organized into an octree structure that is later used for collision detection while the game is running.
thx =)
I am having some problems implementing transition cell generation using the tables available at: http://www.terathon.com/voxels/

+++
- - - = 63
- - -

+++
+++ = 7
- - -

transitionCellClass[63] = 11
transitionCellClass[7] = 4

Shouldn't I get class #12 for these? Feels like I'm missing something very simple :(
Unless I've somehow misunderstood how the indexing or something else works, the tables appear to be incorrect :(. The above mentioned case = 63 (000111111) returns the edge between vertices B and C. Both vertices have positive values in this case, so the edge can not be intersecting the surface.
Ah, I see that the location numbering in Figure 4.16 is not the numbering for which the tables were generated. This would certainly cause some confusion -- sorry about that -- I will update the paper. The case code for a transition cell should be constructed using the following location numbering:

0x040 --- 0x020 --- 0x010
| | |
0x080 --- 0x100 --- 0x008
| | |
0x001 --- 0x002 --- 0x004


The tables are known to be absolutely 100% correct for this numbering. Each of the 512 cases has been manually created in a test environment and individually inspected by experts to make sure that the correct triangles are produced. The algorithm has also been tested in a real-world production environment by thousands of people.

Using the numbering above, your first case is 0x18F, and your second case is still 0x007. These both map to class #4 in the tables, which has the same topological layout as class #12 (i.e, the same numbers of vertices and triangles, and the same triangle layout). The class numbers in the data tables have been remapped in order to collapse topologically equivalent classes even though the vertex positions are different.
Thanks for the reply, got it working with the new indexing :)

voxellod.png

Thanks for the reply, got it working with the new indexing :)


Nice!

This topic is closed to new replies.

Advertisement