I am trying to implement planetary rendering and I am trying to use OpenGL tessellation to model the terrain. Here is an overview picture using cube faces projected onto a sphere:
If I use the following code for the tessellation evaluation shader, I get a smooth sphere even when rendering a near view.
#version 410 core
layout(quads, equal_spacing, ccw) in;
in mediump vec2 texcoord_tes[];
out mediump vec2 texcoord_geo;
uniform mat4 projection;
uniform mat4 transform;
void main()
{
vec2 c = mix(texcoord_tes[0], texcoord_tes[1], gl_TessCoord.x);
vec2 d = mix(texcoord_tes[3], texcoord_tes[2], gl_TessCoord.x);
texcoord_geo = mix(c, d, gl_TessCoord.y);
vec4 a = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
vec4 b = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
vec4 p = mix(a, b, gl_TessCoord.y);
float s = 1.0 / sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
gl_Position = projection * transform * vec4(p.xyz * s * 6388000, 1);
}
Here is a near view using the computed scaling factor (float s = 1.0 / sqrt(p.x ...)
):
However if I take the scale factors from a floating-point texture, I can see quantisation artifacts.
The scale factors (or heightmap values) are extracted from the texture using float s = texture(hf, texcoord_geo).r
. The code for the tessellation evaluation shader in this case is as follows:
#version 410 core
layout(quads, equal_spacing, ccw) in;
in mediump vec2 texcoord_tes[];
out mediump vec2 texcoord_geo;
uniform sampler2D hf;
uniform mat4 projection;
uniform mat4 transform;
void main()
{
vec2 c = mix(texcoord_tes[0], texcoord_tes[1], gl_TessCoord.x);
vec2 d = mix(texcoord_tes[3], texcoord_tes[2], gl_TessCoord.x);
texcoord_geo = mix(c, d, gl_TessCoord.y);
float s = texture(hf, texcoord_geo).r;
vec4 a = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);
vec4 b = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
vec4 p = mix(a, b, gl_TessCoord.y);
gl_Position = projection * transform * vec4(p.xyz * s * 6388000, 1);
}
In this case the near view looks like this and shows artifacts:
My question is, what am I doing wrong? Or is it normal that OpenGL textures are less accurate than 4-byte floating point numbers? Any help is appreciated.