Skip to main content
2 of 2
added 113 characters in body
János Turánszki
  • 3.1k
  • 3
  • 16
  • 22

I am just through implementing scene voxelization myself, and I am doing the dominant axis selection for a primitive like this in the geometry shader:

// First calculate the face normal
float3 facenormal = abs(normalize(input[0].normal + input[1].normal + input[2].normal));
// Then the dominant axis is the face normal's max component:
uint maxi = facenormal[1] > facenormal[0] ? 1 : 0;
maxi = facenormal[2] > facenormal[maxi] ? 2 : maxi;

for( uint i = 0; i < 3; ++i )
{
  // The position is in World space, transform to voxel space:
  output[i].pos = float4((input[i].pos.xyz - (float3)VoxelSceneCenterPos / (float)VoxelSceneScale, 1);

  // Projection matrix is unnecessary, just a swizzle is enough:
  if (maxi == 0)
  {
    output[i].pos.xyz = output[i].pos.zyx;
  }
  else if (maxi == 1)
  {
    output[i].pos.xyz = output[i].pos.xzy;
  }
  // And if the dominant axis is Z, then I do nothing because that is the default projection plane for me.

  // Then I just project the voxel space pos like this:
  output[i].pos.xy /= (float)VoxelSceneResolution;
  output[i].pos.zw = 1;
  // After this step, the output[i].pos is in clip space, the rasterization will take place on this value.
}

In my code, input is the three vertices from the vertex shader stage, output is the TriangleStream which the geometry shader emits (which is also three vertices).

VoxelSceneCenterPos is a uniform from a constant buffer which is the center of the voxelization (for example (0,0,0) vector).
VoxelSceneScale is a uniform from a constant buffer which is the size of a single voxel (default value is 1).
VoxelSceneResolution is a uniform from a constant buffer which is the resolution of the voxel grid (for example for a 256256256 grid this value is 256).

My main idea comes from this cool presentation by NVIDIA.

Good luck!

János Turánszki
  • 3.1k
  • 3
  • 16
  • 22