//Description: 从sdf数据中生成网格
//Create Date: 2021-07-10 14:46:27
//Author: channy
体素顶点的sdf (signed distance function) 值表示该顶点到目标网格面的最近距离,如果目标网格面是封闭的,sdf<0表示该顶点在网格面内部,>0表示在网格面外部
基本流程:
优势
劣势
基本流程:
优势
劣势
基本流程:
优势
劣势
基本流程:
优势
劣势
基本流程:
优势
劣势
设sdf函数为f(v),对每一个voxel,如果该voxel的12条棱中存在至少一条棱满足f(v1) * f(v2) <= 0,说明这个voxel包含有网格面,记为活动voxel。
对于MC,根据活动voxel所有顶点的情况共可分为10+个种类,依靠查找MC表确定活动voxel产生的顶点数和面数,每个产生的顶点都在voxel的边上,不会出现在内部或外部。
而对于DC和SN,都是每个活动voxel产生一个网格顶点,DC由法线控制,顶点可能会出现离voxel偏远的情况或是解矩阵方程无解的情况,需要特殊处理。
考虑到地形可能很大,从计算机角度看一次性直接计算所有数据容易造成内存和cpu不够 用。故把整个地形分割成若干块,每个块为包含19 * 19 * 19个单位立方体的大立方体。 先对每个块生成三角形网格,再对所有块进行合并
对每个块中的每个单位立方体,判断该单位立方体的8个顶点对应的SDF值是否同号; 如果8个顶点同号且tag相同,即顶点SDF值均为正数或均为负数,且tag均为同一类,则 说明该单位立方体要么全部位于地形外部,要么全部位于地形内部,不产生地形网格; 如果8个顶点异号或tag不相同,即其中至少有一个正数和一个负数,或tag包含两种类别 以上,则说明该单位立方体有地形表面经过,需要产生地形网格。不同的tag保证了水和 陆地相接触的立方体也能生成网格,即大陆架网格
对每一个需要产生地形网格的单位立方体,记顶点的三维坐标位置e(ex, ey, ez),8个顶 点的三维坐标位置$e_i(ex_{i}, ey_{i}, ez_{i})$,其中i = [1, 8],每个顶点的SDF值sdf_{ei},计算该单位立方体生成的网格顶点的位置p(px, py, pz) = \sum (e_i * sdf_{ei}), i = 1…8。
根据材质调整生成的网格顶点的位置。对于生成该网格顶点的8个单位立方体顶点,如果 存在至少一个顶点的材质为规则材质,则表示需要生成方块地形,则把该网格顶点移到 该单位立方体的中心点;如果存在至少一个顶点的材质为半规则材质,则表示需要生成 带棱角的网格,则需要根据每种材质的光滑程度[0,1],对该顶点进行一定的位移。例 如:玄武岩的光滑程度为0.3,记生成的网格顶点坐标位置为q(x, y, z),则先对单位立文 体左下角的顶点p取哈希值得到偏移坐标值offset(ox, oy, oz),再把生成的网格顶点坐标 位置q + offset得到最终的网格顶点坐标位置。为了计算方便,如果偏移后得到的坐标位 置超出了该单位立方体,则需要移回到立方体内部
连接相邻单位立方体的顶点生成三角形网格。对于每一个块中的每一个单位立方体顶点p (x, y, z),检测p1(x + 1, y, z), p2(x, y + 1, z) 和 p3(x, y, z + 1)三个相邻的顶点,如果p和 p_i的tag不相同,则把这几个单位立方体对应生成的网格顶点连接成三角形网格。 例 如:单位立方体顶点p(x, y, z)和p1(x + 1, y, z)的tag不相同,则单位立方体b(x, y, z)和b2 (x,y + 1, z)和b3(x, y, z + 1)和b23(x, y + 1, z + 1)四个单位立方体对应生成的网格顶点 bp、bp2、bp3和bp23连接成两个三角形(bp, bp2, bp23)和(bp, bp23, bp3)
计算生成的每个三角形面的法线,再根据材质类型计算每个三角形顶点,即网格顶点的 法线,用于渲染出棱角。对于一个网格顶点,如果生成该网格顶点的单位立方体8个顶点 中,存在至少一个顶点的材质为非规则材质或水,则网格顶点不共用法线,即每个三角 形面的顶点有自己的法线,即为该三角形面的法线;否则网格顶点共用法线,即如果两 个三角形面有一个共同的顶点,则该顶点的法线为两个三角形面的法线的平均值。
生成LOD(Level of Detail)网格。渲染对于近处和远处需要呈现的细节不同,故远处的 三角形网格可以比近处的三角形网格稀疏