Hey,
I'm going to share some technical background first before I describe my normal map problem.
The planet is generated using cube to sphere mapping. I have QuadTree for each cube face to handle LOD and I have 18x18 quad mesh in each patch/node. Everything on the CPU side is in double float precision.
For each patch, I pass the patch corners (cube space coordinates) to the position map shader. The shader generates a position map by transforming each texel to cube space and then to object sphere space before it enters as an input to the noise function. Once I get the height value for a texel, I then store the texel's (object sphere space) * height in the RGB channels. So basically each texel in the position map has its sphere object space XYZ coordinates.
Here's the position map shader:
// Patch coordinates in cube space
vec3 xNW = v0;
vec3 xNE = v1;
vec3 xSW = v2;
// Get the direction, from the origin (top-left) to the end vector (bottom-right).
vec3 xDirection = xNE - xNW;
vec3 zDirection = xSW - xNW;
// Scale the distance by the texture coordinate (which is between 0 and 1).
xDirection *= vTextureCoord.x;
zDirection *= vTextureCoord.y;
// Get current position on the cube face patch
vec3 pos = xNW + xDirection + zDirection;
// Map the cube coordinate to sphere
pos = getSpherePos(pos);
float height = fBm3(pos, 0.05, 3.0, 0.7, 1.0, 1.0);
gl_FragColor = vec4(pos * height, 1.0);
Then in the main shader I generate normals by sampling the position map. Here's the shader:
vec3 getNormal() {
vec2 tpos = vPositionMapUV;
float one = 1.0 / 128.0;
vec3 currentPos = getPosMap(vec2(tpos.x, tpos.y));
vec3 e0 = getPosMap(vec2(tpos.x - one, tpos.y)) - currentPos;
vec3 e2 = getPosMap(vec2(tpos.x , tpos.y - one)) - currentPos;
vec3 n0 = cross(e0, e2);
return normalize(n0);
}
When I reach around depth 15 I start to see artifacts on the normal map, lots of noise and stripes. Here's a picture:
I think the problem is because I'm out of double float precision in the GPU, the vertices are probably like 0.00000005 units apart from each other. I have no clue on how to overcome the issue.
Any help is greatly appreciated.
Thanks!