I'm trying to render a sphere as an impostor, but I have a problem in calculating the depth value of the points of the sphere's surface.
Here you can see what happens when I move the camera around the impostor-sphere and a "real" cube that intersects the sphere.
You can see that when I move the camera, the depth values are not consistent and some parts of the cube that should be inside the sphere, depending on the position of the camera, pop in and out of the sphere.
These are the vertex and fragment shaders for the impostor-sphere.
vertex shader :
#version 450 core
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 coords;
void main()
{
switch (gl_VertexID)
{
case 0:
coords = vec2(-1.0f, -1.0f);
break;
case 1:
coords = vec2(-1.0f, +1.0f);
break;
case 2:
coords = vec2(+1.0f, -1.0f);
break;
case 3:
coords = vec2(+1.0f, +1.0f);
break;
}
// right & up axes camera space
vec3 right = vec3(view[0][0], view[1][0], view[2][0]);
vec3 up = vec3(view[0][1], view[1][1], view[2][1]);
vec3 center = vec3(0.0f);
float radius = 1.0f;
// vertex position
vec3 position = radius * vec3(coords, 0.0f);
position = right * position.x + up * position.y;
mat4 MVP = projection * view * model;
gl_Position = MVP * vec4(center + position, 1.0f);
}
fragment shader :
#version 450 core
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
in vec2 coords;
out vec4 pixel;
void main()
{
float d = dot(coords, coords);
if (d > 1.0f)
{
discard;
}
float z = sqrt(1.0f - d);
vec3 normal = vec3(coords, z);
normal = mat3(transpose((view * model))) * normal;
vec3 center = vec3(0.0f);
float radius = 1.0f;
vec3 position = center + radius * normal;
mat4 MVP = projection * view * model;
// gl_DepthRange.diff value is the far value minus the near value
vec4 clipPos = MVP * vec4(position, 1.0f);
float ndcDepth = clipPos.z / clipPos.w;
gl_FragDepth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) * 0.5f;
pixel = vec4((normal + 1.0f) * 0.5f, 1.0f);
}
I followed this example to calculate the depth value.
The model matrix that I pass to the shaders is an identity matrix, so it doesn't affect the operations.
Thanks a lot for your help!!
glClipControl()
anywhere in your program? – Michael Kenzelgl_FragDepth = (ndcDepth + 1.0f) * 0.5f;
, which simply maps the depth values from the range [-1, +1] in clip space to the range [0, 1]. I think the code is almost correct, but something is missing, especially when the depth values between objects are close. If you have any other idea or you think it could be useful to check other parts of the code, please just tell me! Thanks a lot! – Arctic Pi