SRTM example: fix close-view normals by computing them in geometry shader instead

This commit is contained in:
Nikita Lisitsa 2020-11-08 19:17:22 +03:00
parent 7fa031da00
commit 63da1987be

View file

@ -39,7 +39,6 @@
// TODO: use LRU cache for tile generation requests, combine with threadpool
// TODO: fix frustum culling
// TODO: fix seams at tile borders
// TODO: fix normals at closest view
// TODO: try a different coordinate system for closer tiles
// TODO: use closer near plane, maybe try reversed-Z
// TODO: add space, stars, the sun
@ -460,7 +459,47 @@ void main()
color = (in_height > 0.0) ? texture(u_colormap, in_height / 8000.0).rgb : texture(u_colormap_neg, -in_height / 10000.0).rgb;
})";
static char const tile_fs[] =
static char const tile_close_gs[] =
R"(#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
in vec3 color[];
in vec3 pos[];
out vec3 g_color;
out vec3 g_normal;
void main()
{
g_normal = normalize(cross(pos[1] - pos[0], pos[2] - pos[0]));
for (int i = 0; i < 3; ++i)
{
g_color = color[i];
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
})";
static char const tile_close_fs[] =
R"(#version 330
uniform vec3 u_light;
in vec3 g_color;
in vec3 g_normal;
out vec4 out_color;
void main()
{
float l = (0.5 + dot(normalize(g_normal), u_light) * 0.5);
out_color = vec4(g_color * l, 1.0);
})";
static char const tile_far_fs[] =
R"(#version 330
uniform vec3 u_light;
@ -471,10 +510,8 @@ out vec4 out_color;
void main()
{
vec3 dx = dFdx(pos);
vec3 dy = dFdy(pos);
vec3 n = normalize(cross(dx, dy));
float l = (0.5 + dot(n, u_light) * 0.5);
vec3 normal = cross(dFdx(pos), dFdy(pos));
float l = (0.5 + dot(normalize(normal), u_light) * 0.5);
out_color = vec4(color * l, 1.0);
})";
@ -496,7 +533,8 @@ struct srtm_app
node_controller nodes;
gfx::program tile_program{tile_vs, tile_fs};
gfx::program tile_close_program{tile_vs, tile_close_gs, tile_close_fs};
gfx::program tile_far_program{tile_vs, tile_far_fs};
gfx::texture_1d color_map;
gfx::texture_1d color_map_neg;
@ -680,12 +718,18 @@ void srtm_app::present()
auto const frustum = cg::frustum(camera_transform);
(void)frustum;
tile_program.bind();
tile_program["u_transform"] = camera_transform;
tile_program["u_N"] = static_cast<int>(node_size);
tile_program["u_light"] = geom::vector<float, 3>{0.f, 0.f, 1.f};
tile_program["u_colormap"] = 0;
tile_program["u_colormap_neg"] = 1;
tile_close_program.bind();
tile_close_program["u_transform"] = camera_transform;
tile_close_program["u_N"] = static_cast<int>(node_size);
tile_close_program["u_light"] = geom::vector<float, 3>{0.f, 0.f, 1.f};
tile_close_program["u_colormap"] = 0;
tile_close_program["u_colormap_neg"] = 1;
tile_far_program.bind();
tile_far_program["u_transform"] = camera_transform;
tile_far_program["u_N"] = static_cast<int>(node_size);
tile_far_program["u_light"] = geom::vector<float, 3>{0.f, 0.f, 1.f};
tile_far_program["u_colormap"] = 0;
tile_far_program["u_colormap_neg"] = 1;
gl::ActiveTexture(gl::TEXTURE0);
color_map.bind();
gl::ActiveTexture(gl::TEXTURE1);
@ -805,10 +849,13 @@ void srtm_app::present()
gfx::blue
};
tile_program["u_p0"] = v[0];
tile_program["u_p1"] = v[1];
tile_program["u_p2"] = v[2];
tile_program["u_color"] = colors[tile_n % 4];
auto * program = (level == max_child_level) ? &tile_close_program : &tile_far_program;
program->bind();
(*program)["u_p0"] = v[0];
(*program)["u_p1"] = v[1];
(*program)["u_p2"] = v[2];
(*program)["u_color"] = colors[tile_n % 4];
return n->draw(tile_n);
}