Hi and thanks for your time!
So over the past few days I have been playing with isosurface construction from volume textures, I have it running on the cpu and all is well from a "just got it working" stand point eg. surface reconstruction works and I have my really cool voxel mesh drawing.
I have based my code(converted to VB.net) on Paul Bourke's work here: Polygonising a scalar field and like I said it works well apart from the fact that my normals are wrong and I have these strange fully black on both sides triangles, I think I'm doing my normals wrong but the way they are now is the beast I can get, I tried a few ways to build the normals and this one is the only way I could get smooth normals.
Here you can see how my normals are wrong, green should be up, gray\dark should be unlit and the hay'ish colour is the lit side.
I have tried to flip and invert them but as you can see they are not wrong all the same way.
HLSL Normals 1st try:
float3x3 cotangent_frame(float3 N, float3 p, float2 uv) // get edge vectors of the pixel triangle float3 dp1 = ddx(p); float3 dp2 = ddy(p); float2 duv1 = ddx(uv); float2 duv2 = ddy(uv); // solve the linear system float3 dp2perp = cross(dp2, N); float3 dp1perp = cross(N, dp1); float3 T = dp2perp * duv1.x + dp1perp * duv2.x; float3 B = dp2perp * duv1.y + dp1perp * duv2.y; // construct a scale-invariant frame float invmax = -sqrt(max(dot(T, T), dot(B, B))); return float3x3(T * invmax, B * invmax, N);
HLSL Normals 2nd try:
NormalData CalcWS_Normal(float2 WS_TexCoord, float3 WS_Pos) NormalData dout; float3 dp1 = ddx(WS_Pos); float3 dp2 = ddy(WS_Pos); float2 duv1 = ddx(WS_TexCoord); float2 duv2 = ddy(WS_TexCoord); float3x3 M = float3x3(dp1, dp2, cross(dp1, dp2)); float2x3 inverseM = float2x3(cross(M, M), cross(M, M)); float3 t = mul(float2(duv1.x, duv2.x), inverseM); float3 b = mul(float2(duv1.y, duv2.y), inverseM); float3 normal = normalize(cross(normalize(b), normalize(t))); dout.Normal = normal; dout.Tang = t; dout.BiTang = b; return dout;
Heres is how I'm doing it now, takes a vertex and then samples the volume texture
Private Function vGetNormal(fX As Single, fY As Single, fZ As Single, fScale As Single) As Vector3 Dim rfNormal As Vector3 rfNormal.X = fSample1(fX - fScale, fY, fZ) - fSample1(fX + fScale, fY, fZ) rfNormal.Y = fSample1(fX, fY - fScale, fZ) - fSample1(fX, fY + fScale, fZ) rfNormal.Z = fSample1(fX, fY, fZ - fScale) - fSample1(fX, fY, fZ + fScale) Return Vector3.Normalize(rfNormal) End Function Private Function vGetNormal(fX As Single, fY As Single, fZ As Single, fScale As Vector3) As Vector3 Dim rfNormal As Vector3 rfNormal.X = fSample1(fX - fScale.X, fY, fZ) - fSample1(fX + fScale.X, fY, fZ) rfNormal.Y = fSample1(fX, fY - fScale.Y, fZ) - fSample1(fX, fY + fScale.Y, fZ) rfNormal.Z = fSample1(fX, fY, fZ - fScale.Z) - fSample1(fX, fY, fZ + fScale.Z) Return Vector3.Normalize(rfNormal) End Function
Volume sampling code:
Public Function GetVolumeData(_pos As Vector3) As Half Dim x2 As Single = Math.Abs((_pos.X / CellsPerPatch * 32) Mod mWidth) Dim y2 As Single = Math.Abs((_pos.Y / CellsPerPatch * 8) Mod mDepth) Dim z2 As Single = Math.Abs((_pos.Z / CellsPerPatch * 32) Mod mHeight) Return mScalars(CInt(Math.Truncate(x2)) + (CInt(Math.Truncate(z2)) * mWidth) + (CInt(Math.Truncate(y2) * mWidth * mWidth))) End Function
The rest of the isosurface construction code is just a copy-> convert-> paste of Paul Bourke's c code.
Just to makes sure everyone knows what I'm asking: Can anyone tell me what I'm doing wrong? Is it a problem with my normals or the isosurface stuffs or both?
All of the above is just so u have some context, I'm happy to post more code if ppl need to see it
[EDIT]: Black squares come from having no depth info at that point so my deferred render hates those spots, this is leading back to maybe a problem with the surface reconstruction? But why its only happening in those spots, one would think that it would happen everywhere?