计算行进立方体网格的法线、索引和 UV 坐标

Posted

技术标签:

【中文标题】计算行进立方体网格的法线、索引和 UV 坐标【英文标题】:Calculating normals, indices and UV coordinates for marching cubes mesh 【发布时间】:2014-12-31 22:21:15 【问题描述】:

我正在关注这篇文章:

http://paulbourke.net/geometry/polygonise/

但是提供的源代码只生成三角形。

如何计算法线、索引和 UV 坐标?

【问题讨论】:

【参考方案1】:

对于正常计算,您有两种选择。您可以取三角形两条边的叉积,如here 所示,这将使三角形的每个顶点具有相同的法线,从而为您提供平坦的阴影。另一个选项为您提供平滑的法线,并通过线性插值 12 个顶点的邻居中的每一个的差异来完成。 GPU Gems article 就是这样做的。

float d = 1.0/(float)voxels_per_block;  
float3 grad;  
grad.x = density_vol.Sample(TrilinearClamp, uvw + float3( d, 0, 0)) -  
         density_vol.Sample(TrilinearClamp, uvw + float3(-d, 0, 0));  
grad.y = density_vol.Sample(TrilinearClamp, uvw + float3( 0, d, 0)) -  
         density_vol.Sample(TrilinearClamp, uvw + float3( 0,-d, 0));  
grad.z = density_vol.Sample(TrilinearClamp, uvw + float3( 0, 0, d)) -  
         density_vol.Sample(TrilinearClamp, uvw + float3( 0, 0,-d));  
output.wsNormal = -normalize(grad);

不幸的是,我没有任何创建索引缓冲区的第一手经验,但对于 UV 坐标,最好使用三平面纹理映射。 UV 坐标是在像素着色器中使用世界坐标和法线计算的,同一篇 GPU Gems 文章提供了示例代码,您只需稍加修改即可使用:

// Determine the blend weights for the 3 planar projections.  
// N_orig is the vertex-interpolated normal vector.  
float3 blend_weights = abs( N_orig.xyz );   // Tighten up the blending zone:  
blend_weights = (blend_weights - 0.2) * 7;  
blend_weights = max(blend_weights, 0);      // Force weights to sum to 1.0 (very important!)  
blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ).xxx;   
// Now determine a color value and bump vector for each of the 3  
// projections, blend them, and store blended results in these two  
// vectors:  
float4 blended_color; // .w hold spec value  
float3 blended_bump_vec;  
  
// Compute the UV coords for each of the 3 planar projections.  
// tex_scale (default ~ 1.0) determines how big the textures appear.  
float2 coord1 = v2f.wsCoord.yz * tex_scale;  
float2 coord2 = v2f.wsCoord.zx * tex_scale;  
float2 coord3 = v2f.wsCoord.xy * tex_scale;  
// This is where you would apply conditional displacement mapping.  
//if (blend_weights.x > 0) coord1 = . . .  
//if (blend_weights.y > 0) coord2 = . . .  
//if (blend_weights.z > 0) coord3 = . . .  
// Sample color maps for each projection, at those UV coords.  
float4 col1 = colorTex1.Sample(coord1);  
float4 col2 = colorTex2.Sample(coord2);  
float4 col3 = colorTex3.Sample(coord3);

【讨论】:

以上是关于计算行进立方体网格的法线、索引和 UV 坐标的主要内容,如果未能解决你的问题,请参考以下文章

哪些网格数据格式分别提供位置、法线和 UV 坐标的索引?

渲染具有多个索引的网格

渲染具有多个索引的网格

渲染具有多个索引的网格

使用索引时如何为 UV 添加 vec2 以进行纹理映射

行进立方体未创建预期的网格