trsh said:
when you zoom into something it's just lots of tiny cubes.
Yeah, but that's simple to do, and just deforming the vertices to get smooth results seems an option.
Code below is how i do this, density Gradient can be used as normal for lighting.
It reminds about something similar from this post, see Surface Nets: https://0fps.net/2012/07/12/smooth-voxel-terrain-part-2/
Maybe his method is better, with smoother results. Need to try that at some time. He used the average of density / edge intersection.
He also has source code, but because i have requirement on manifolds i decided to start from scratch - given code examples always contain look up tables which makes them hard to understand.
static void VertexPositionAndNormalFromDensityField (
vec &displacedPosition, vec &densityGradient,
const vec gridPosition,
const int x, const int y, const int z, // grid indices
const std::vector<float> &density, const int regDim, // density volume and dimension
const float cellSize, const float densCentDisp = 2.0f, const float gradDisp = 1.0f)
{
vec p = gridPosition;
vec cd(0);
float dSum = 0;
float d[8];
int n = 0;
for (int Z=-1; Z<1; Z++)
for (int Y=-1; Y<1; Y++)
for (int X=-1; X<1; X++)
{
float D = density[Index(x+X,y+Y,z+Z, regDim)];
cd += D * vec(float(X)+0.5f, float(Y)+0.5f, float(Z)+0.5f);
dSum += D;
d[n++] = D;
}
cd *= cellSize / dSum;
p += cd * densCentDisp;
vec g;
g[0] = d[0b001] - d[0b000];
g[0] += d[0b011] - d[0b010];
g[0] += d[0b101] - d[0b100];
g[0] += d[0b111] - d[0b110];
g[1] = d[0b010] - d[0b000];
g[1] += d[0b110] - d[0b100];
g[1] += d[0b011] - d[0b001];
g[1] += d[0b111] - d[0b101];
g[2] = d[0b100] - d[0b000];
g[2] += d[0b101] - d[0b001];
g[2] += d[0b110] - d[0b010];
g[2] += d[0b111] - d[0b011];
g *= cellSize / 4;
p -= g * gradDisp;
displacedPosition = p;
densityGradient = g;
}