Skip to content

Commit eabd86c

Browse files
committed
if draw resolution is independent of available height data, it often renders using low resolution data, making a stair case effect.
(AlpineMapsOrg#162) - disabled shadow mapping for now - disabled normal computation for now idea: use several geometry sets, with varying resolution. draw, e.g. 17x17 geometry, if we are 2 zoom levels below max res.
1 parent c96d6d8 commit eabd86c

12 files changed

+59
-85
lines changed

app/RenderingContext.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ void RenderingContext::initialise()
155155
m->engine_context->set_ortho_layer(std::make_shared<gl_engine::TextureLayer>(512));
156156
m->engine_context->tile_geometry()->set_quad_limit(512);
157157
m->engine_context->tile_geometry()->set_aabb_decorator(m->aabb_decorator);
158+
m->engine_context->set_aabb_decorator(m->aabb_decorator);
158159
m->engine_context->ortho_layer()->set_quad_limit(512);
159160

160161
connect(m->geometry.scheduler.get(), &nucleus::tile::GeometryScheduler::gpu_quads_updated, m->engine_context->tile_geometry(), &gl_engine::TileGeometry::update_gpu_quads);

gl_engine/MapLabels.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ void MapLabels::init(ShaderRegistry* shader_registry)
7474
m_indices_count = m_mapLabelFactory.m_indices.size();
7575
}
7676

77-
MapLabels::TileSet MapLabels::generate_draw_list(const nucleus::camera::Definition& camera) const { return m_draw_list_generator.cull(m_draw_list_generator.generate_for(camera), camera.frustum()); }
77+
MapLabels::TileSet MapLabels::generate_draw_list(const nucleus::camera::Definition& camera) const
78+
{
79+
return m_draw_list_generator.cull(m_draw_list_generator.generate_for(camera), camera.frustum());
80+
}
7881

7982
void MapLabels::upload_to_gpu(const TileId& id, const PointOfInterestCollection& features)
8083
{

gl_engine/ShadowMapping.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ void ShadowMapping::draw(TileGeometry* tile_geometry,
5555
std::shared_ptr<UniformBuffer<uboShadowConfig>> shadow_config,
5656
std::shared_ptr<UniformBuffer<uboSharedConfig>> shared_config)
5757
{
58+
Q_UNUSED(tile_geometry);
59+
Q_UNUSED(draw_tileset);
5860

5961
// NOTE: ReverseZ is not necessary for ShadowMapping since a directional light is using an orthographic projection
6062
// and therefore the distribution of depth is linear anyway.
@@ -87,7 +89,7 @@ void ShadowMapping::draw(TileGeometry* tile_geometry,
8789
m_f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
8890

8991
m_shadow_program->set_uniform("current_layer", i);
90-
tile_geometry->draw(m_shadow_program.get(), camera, draw_tileset, false, glm::dvec3(0.0));
92+
// tile_geometry->draw(m_shadow_program.get(), camera, draw_tileset, false, glm::dvec3(0.0));
9193
m_shadowmapbuffer[i]->unbind();
9294
}
9395
m_shadow_program->release();

gl_engine/TextureLayer.cpp

+4-8
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,17 @@ void gl_engine::TextureLayer::init(ShaderRegistry* shader_registry)
4848
m_instanced_array_index->setParams(Texture::Filter::Nearest, Texture::Filter::Nearest);
4949
}
5050

51-
void TextureLayer::draw(const TileGeometry& tile_geometry,
52-
const nucleus::camera::Definition& camera,
53-
const nucleus::tile::DrawListGenerator::TileSet& draw_tiles,
54-
bool sort_tiles,
55-
glm::dvec3 sort_position) const
51+
void TextureLayer::draw(
52+
const TileGeometry& tile_geometry, const nucleus::camera::Definition& camera, const std::vector<nucleus::tile::TileBounds>& draw_list) const
5653
{
5754
m_shader->bind();
5855
m_texture_array->bind(2);
5956
m_shader->set_uniform("texture_sampler", 2);
6057

61-
const auto draw_list = tile_geometry.sort(camera, draw_tiles);
6258
nucleus::Raster<uint8_t> zoom_level_raster = { glm::uvec2 { 1024, 1 } };
6359
nucleus::Raster<uint16_t> array_index_raster = { glm::uvec2 { 1024, 1 } };
6460
for (unsigned i = 0; i < std::min(unsigned(draw_list.size()), 1024u); ++i) {
65-
const auto layer = m_gpu_array_helper.layer(draw_list[i]);
61+
const auto layer = m_gpu_array_helper.layer(draw_list[i].id);
6662
zoom_level_raster.pixel({ i, 0 }) = layer.id.zoom_level;
6763
array_index_raster.pixel({ i, 0 }) = layer.index;
6864
}
@@ -75,7 +71,7 @@ void TextureLayer::draw(const TileGeometry& tile_geometry,
7571
m_shader->set_uniform("instanced_texture_zoom_sampler", 8);
7672
m_instanced_zoom->upload(zoom_level_raster);
7773

78-
tile_geometry.draw(m_shader.get(), camera, draw_tiles, sort_tiles, sort_position);
74+
tile_geometry.draw(m_shader.get(), camera, draw_list);
7975
}
8076

8177
unsigned TextureLayer::tile_count() const { return m_gpu_array_helper.n_occupied(); }

gl_engine/TextureLayer.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <nucleus/tile/GpuArrayHelper.h>
2626
#include <nucleus/tile/types.h>
2727

28-
namespace camera {
28+
namespace nucleus::camera {
2929
class Definition;
3030
}
3131

@@ -44,11 +44,7 @@ class TextureLayer : public QObject {
4444
public:
4545
explicit TextureLayer(unsigned resolution = 256, QObject* parent = nullptr);
4646
void init(ShaderRegistry* shader_registry); // needs OpenGL context
47-
void draw(const TileGeometry& tile_geometry,
48-
const nucleus::camera::Definition& camera,
49-
const nucleus::tile::DrawListGenerator::TileSet& draw_tiles,
50-
bool sort_tiles,
51-
glm::dvec3 sort_position) const;
47+
void draw(const TileGeometry& tile_geometry, const nucleus::camera::Definition& camera, const std::vector<nucleus::tile::TileBounds>& draw_list) const;
5248

5349
unsigned int tile_count() const;
5450

gl_engine/TileGeometry.cpp

+15-53
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ void TileGeometry::init()
6767
m_draw_tile_id_buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
6868
m_draw_tile_id_buffer->allocate(GLsizei(m_gpu_array_helper.size() * sizeof(glm::u32vec2)));
6969

70-
m_height_texture_layer_buffer = std::make_unique<QOpenGLBuffer>(QOpenGLBuffer::VertexBuffer);
71-
m_height_texture_layer_buffer->create();
72-
m_height_texture_layer_buffer->bind();
73-
m_height_texture_layer_buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
74-
m_height_texture_layer_buffer->allocate(GLsizei(m_gpu_array_helper.size() * sizeof(int32_t)));
75-
7670
m_vao = std::make_unique<QOpenGLVertexArrayObject>();
7771
m_vao->create();
7872
m_vao->bind();
@@ -103,8 +97,6 @@ void TileGeometry::init()
10397
qDebug() << "attrib location for bounds: " << bounds;
10498
int packed_tile_id = example_shader->attribute_location("packed_tile_id");
10599
qDebug() << "attrib location for packed_tile_id: " << packed_tile_id;
106-
int height_texture_layer = example_shader->attribute_location("height_texture_layer");
107-
qDebug() << "attrib location for height_texture_layer: " << height_texture_layer;
108100

109101
m_vao->bind();
110102
QOpenGLExtraFunctions* f = QOpenGLContext::currentContext()->extraFunctions();
@@ -120,12 +112,6 @@ void TileGeometry::init()
120112
f->glVertexAttribIPointer(GLuint(packed_tile_id), /*size*/ 2, /*type*/ GL_UNSIGNED_INT, /*stride*/ 0, nullptr);
121113
f->glVertexAttribDivisor(GLuint(packed_tile_id), 1);
122114
}
123-
if (height_texture_layer != -1) {
124-
m_height_texture_layer_buffer->bind();
125-
f->glEnableVertexAttribArray(GLuint(height_texture_layer));
126-
f->glVertexAttribIPointer(GLuint(height_texture_layer), /*size*/ 1, /*type*/ GL_INT, /*stride*/ 0, nullptr);
127-
f->glVertexAttribDivisor(GLuint(height_texture_layer), 1);
128-
}
129115

130116
update_gpu_id_map();
131117
}
@@ -159,64 +145,43 @@ std::vector<nucleus::tile::Id> TileGeometry::sort(const nucleus::camera::Definit
159145
return sorted_ids;
160146
}
161147

162-
void TileGeometry::draw(ShaderProgram* shader, const nucleus::camera::Definition& camera, const TileSet& draw_tiles, bool sort_tiles, glm::dvec3 sort_position) const
148+
void TileGeometry::draw(ShaderProgram* shader, const nucleus::camera::Definition& camera, const std::vector<nucleus::tile::TileBounds>& draw_list) const
163149
{
164150
QOpenGLExtraFunctions* f = QOpenGLContext::currentContext()->extraFunctions();
165151
shader->set_uniform("n_edge_vertices", N_EDGE_VERTICES);
166152
shader->set_uniform("height_tex_sampler", 1);
167153
shader->set_uniform("height_tex_index_sampler", 3);
168154
shader->set_uniform("height_tex_tile_id_sampler", 4);
169155

170-
// Sort depending on distance to sort_position
171-
std::vector<std::pair<float, const TileInfo*>> tile_list;
172-
for (const auto& tileset : m_gpu_tiles) {
173-
float dist = 0.0;
174-
if (!draw_tiles.contains(tileset.tile_id))
175-
continue;
176-
if (sort_tiles) {
177-
glm::vec2 pos_wrt = glm::vec2(tileset.bounds.min.x - sort_position.x, tileset.bounds.min.y - sort_position.y);
178-
dist = glm::length(pos_wrt);
179-
}
180-
tile_list.push_back(std::pair<float, const TileInfo*>(dist, &tileset));
181-
}
182-
if (sort_tiles)
183-
std::sort(tile_list.begin(), tile_list.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
184-
185156
m_heightmap_textures->bind(1);
186157
m_array_index_texture->bind(3);
187158
m_tile_id_texture->bind(4);
188159
m_vao->bind();
189160

190161
std::vector<glm::vec4> bounds;
191-
bounds.reserve(tile_list.size());
162+
bounds.reserve(draw_list.size());
192163

193164
std::vector<glm::u32vec2> packed_id;
194-
packed_id.reserve(tile_list.size());
195-
196-
std::vector<int32_t> height_texture_layer;
197-
height_texture_layer.reserve(tile_list.size());
198-
199-
for (const auto& tileset : tile_list) {
200-
bounds.emplace_back(tileset.second->bounds.min.x - camera.position().x,
201-
tileset.second->bounds.min.y - camera.position().y,
202-
tileset.second->bounds.max.x - camera.position().x,
203-
tileset.second->bounds.max.y - camera.position().y);
204-
205-
packed_id.emplace_back(nucleus::srs::pack(tileset.second->tile_id));
206-
height_texture_layer.emplace_back(tileset.second->height_texture_layer);
207-
}
165+
packed_id.reserve(draw_list.size());
208166

209167
{
210-
const auto draw_list = tile_list;
211168
nucleus::Raster<uint8_t> zoom_level_raster = { glm::uvec2 { 1024, 1 } };
212169
nucleus::Raster<uint16_t> array_index_raster = { glm::uvec2 { 1024, 1 } };
213170
nucleus::Raster<glm::vec4> bounds_raster = { glm::uvec2 { 1024, 1 } };
214171
for (unsigned i = 0; i < std::min(unsigned(draw_list.size()), 1024u); ++i) {
215-
const auto layer = m_gpu_array_helper.layer(draw_list[i].second->tile_id);
172+
const auto& tile = draw_list[i];
173+
const auto bounds_2d = glm::vec4 { tile.bounds.min.x - camera.position().x,
174+
tile.bounds.min.y - camera.position().y,
175+
tile.bounds.max.x - camera.position().x,
176+
tile.bounds.max.y - camera.position().y };
177+
bounds.push_back(bounds_2d);
178+
packed_id.push_back(nucleus::srs::pack(tile.id));
179+
180+
bounds_raster.pixel({ i, 0 }) = bounds_2d;
181+
182+
const auto layer = m_gpu_array_helper.layer(draw_list[i].id);
216183
zoom_level_raster.pixel({ i, 0 }) = layer.id.zoom_level;
217184
array_index_raster.pixel({ i, 0 }) = layer.index;
218-
const auto aabb = m_aabb_decorator->aabb(layer.id);
219-
bounds_raster.pixel({ i, 0 }) = { aabb.min.x - camera.position().x, aabb.min.y - camera.position().y, aabb.max.x - camera.position().x, aabb.max.y - camera.position().y };
220185
}
221186

222187
m_instanced_array_index->bind(5);
@@ -238,10 +203,7 @@ void TileGeometry::draw(ShaderProgram* shader, const nucleus::camera::Definition
238203
m_draw_tile_id_buffer->bind();
239204
m_draw_tile_id_buffer->write(0, packed_id.data(), GLsizei(packed_id.size() * sizeof(decltype(packed_id)::value_type)));
240205

241-
m_height_texture_layer_buffer->bind();
242-
m_height_texture_layer_buffer->write(0, height_texture_layer.data(), GLsizei(height_texture_layer.size() * sizeof(decltype(height_texture_layer)::value_type)));
243-
244-
f->glDrawElementsInstanced(GL_TRIANGLE_STRIP, GLsizei(m_index_buffer.second), GL_UNSIGNED_SHORT, nullptr, GLsizei(tile_list.size()));
206+
f->glDrawElementsInstanced(GL_TRIANGLE_STRIP, GLsizei(m_index_buffer.second), GL_UNSIGNED_SHORT, nullptr, GLsizei(draw_list.size()));
245207
f->glBindVertexArray(0);
246208
}
247209

gl_engine/TileGeometry.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class TileGeometry : public QObject {
5151

5252
explicit TileGeometry(QObject* parent = nullptr);
5353
void init(); // needs OpenGL context
54-
void draw(ShaderProgram* shader_program, const nucleus::camera::Definition& camera, const TileSet& draw_tiles, bool sort_tiles, glm::dvec3 sort_position) const;
54+
void draw(ShaderProgram* shader_program, const nucleus::camera::Definition& camera, const std::vector<nucleus::tile::TileBounds>& draw_list) const;
5555

5656
TileSet generate_tilelist(const nucleus::camera::Definition& camera) const;
5757
TileSet cull(const TileSet& tileset, const nucleus::camera::Frustum& frustum) const;
@@ -84,7 +84,6 @@ public slots:
8484
std::pair<std::unique_ptr<QOpenGLBuffer>, size_t> m_index_buffer;
8585
std::unique_ptr<QOpenGLBuffer> m_bounds_buffer;
8686
std::unique_ptr<QOpenGLBuffer> m_draw_tile_id_buffer;
87-
std::unique_ptr<QOpenGLBuffer> m_height_texture_layer_buffer;
8887

8988
std::vector<TileInfo> m_gpu_tiles;
9089
nucleus::tile::DrawListGenerator m_draw_list_generator;

gl_engine/Window.cpp

+13-9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <QTimer>
4545
#include <glm/glm.hpp>
4646
#include <glm/gtx/transform.hpp>
47+
#include <nucleus/tile/drawing.h>
4748
#include <nucleus/timing/CpuTimer.h>
4849
#include <nucleus/timing/TimerManager.h>
4950
#include <nucleus/utils/bit_coding.h>
@@ -70,6 +71,7 @@
7071
using gl_engine::UniformBuffer;
7172
using gl_engine::Window;
7273
using namespace gl_engine;
74+
using namespace nucleus::tile;
7375

7476
Window::Window(std::shared_ptr<Context> context)
7577
: m_context(context)
@@ -299,20 +301,22 @@ void Window::paint(QOpenGLFramebufferObject* framebuffer)
299301
tile_stats["n_label_tiles_gpu"] = m_context->map_label_manager()->tile_count();
300302
tile_stats["n_label_tiles_drawn"] = unsigned(label_tile_set.size());
301303
}
302-
const auto tile_set = m_context->tile_geometry()->generate_tilelist(m_camera);
303-
const auto culled_tile_set = m_context->tile_geometry()->cull(tile_set, m_camera.frustum());
304+
305+
const auto draw_list
306+
= drawing::compute_bounds(drawing::limit(drawing::generate_list(m_camera, m_context->aabb_decorator(), 20), 1024u), m_context->aabb_decorator());
307+
const auto culled_draw_list = drawing::sort(drawing::cull(draw_list, m_camera), m_camera.position());
304308

305309
tile_stats["n_geometry_tiles_gpu"] = m_context->tile_geometry()->tile_count();
306310
tile_stats["n_ortho_tiles_gpu"] = m_context->ortho_layer()->tile_count();
307-
tile_stats["n_geometry_tiles_drawn"] = unsigned(culled_tile_set.size());
311+
tile_stats["n_geometry_tiles_drawn"] = unsigned(culled_draw_list.size());
308312
m_timer->stop_timer("draw_list");
309313

310314
// DRAW SHADOWMAPS
311-
if (m_shared_config_ubo->data.m_csm_enabled) {
312-
m_timer->start_timer("shadowmap");
313-
m_shadowmapping->draw(m_context->tile_geometry(), tile_set, m_camera, m_shadow_config_ubo, m_shared_config_ubo);
314-
m_timer->stop_timer("shadowmap");
315-
}
315+
// if (m_shared_config_ubo->data.m_csm_enabled) {
316+
// m_timer->start_timer("shadowmap");
317+
// m_shadowmapping->draw(m_context->tile_geometry(), tile_set, m_camera, m_shadow_config_ubo, m_shared_config_ubo);
318+
// m_timer->stop_timer("shadowmap");
319+
// }
316320

317321
// DRAW GBUFFER
318322
m_gbuffer->bind();
@@ -339,7 +343,7 @@ void Window::paint(QOpenGLFramebufferObject* framebuffer)
339343
f->glDepthFunc(GL_GREATER); // reverse z
340344

341345
m_timer->start_timer("tiles");
342-
m_context->ortho_layer()->draw(*m_context->tile_geometry(), m_camera, culled_tile_set, true, m_camera.position());
346+
m_context->ortho_layer()->draw(*m_context->tile_geometry(), m_camera, culled_draw_list);
343347
m_timer->stop_timer("tiles");
344348

345349
m_gbuffer->unbind();

gl_engine/shaders/tile.glsl

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
*****************************************************************************/
1919

2020
#include "tile_id.glsl"
21+
#line 22
2122

2223
uniform highp usampler2D instanced_geom_array_index_sampler;
2324
uniform highp usampler2D instanced_geom_zoom_sampler;
2425
uniform highp sampler2D instanced_geom_bounds_sampler;
2526

2627
layout(location = 0) in highp vec4 bounds;
27-
layout(location = 1) in highp int height_texture_layer;
28-
layout(location = 2) in highp uvec2 packed_tile_id;
28+
layout(location = 1) in highp uvec2 packed_tile_id;
2929

3030
uniform highp int n_edge_vertices;
3131
uniform mediump usampler2DArray height_tex_sampler;
@@ -83,7 +83,7 @@ highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direct
8383
decrease_zoom_level_until(geom_tile_id, geom_uv, geom_zoom);
8484
highp float geom_texture_layer_f = float(texelFetch(instanced_geom_array_index_sampler, ivec2(uint(gl_InstanceID), 0), 0).x);
8585
// float altitude_tex = float(geom_texture_layer_f);
86-
float altitude_tex = float(texture(height_tex_sampler, vec3(uv, height_texture_layer)).r);
86+
float altitude_tex = float(texture(height_tex_sampler, vec3(geom_uv, geom_texture_layer_f)).r);
8787
////////
8888
// float altitude_tex = float(texelFetch(height_tex_sampler, ivec3(col, row, height_texture_layer), 0).r);
8989
float adjusted_altitude = altitude_tex * altitude_correction_factor;
@@ -119,6 +119,8 @@ highp vec3 normal_by_finite_difference_method(vec2 uv, float edge_vertices_count
119119
// from here: https://stackoverflow.com/questions/6656358/calculating-normals-in-a-triangle-mesh/21660173#21660173
120120
vec2 offset = vec2(1.0, 0.0) / (edge_vertices_count);
121121

122+
float height_texture_layer = 0;
123+
122124
highp float hL = float(texture(height_tex_sampler, vec3(uv - offset.xy, height_texture_layer)).r);
123125
hL *= altitude_correction_factor;
124126
highp float hR = float(texture(height_tex_sampler, vec3(uv + offset.xy, height_texture_layer)).r);

gl_engine/shaders/tile.vert

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ void main() {
5353
case 2u: vertex_color = color_from_id_hash(uint(packed_tile_id.x ^ packed_tile_id.y)); break;
5454
case 3u: vertex_color = color_from_id_hash(uint(var_tile_id.z)); break;
5555
case 4u: vertex_color = color_from_id_hash(uint(gl_VertexID)); break;
56-
case 5u: vertex_color = vec3(texture(height_tex_sampler, vec3(var_uv, height_texture_layer)).rrr) / 65535.0; break;
56+
// case 5u: vertex_color = vec3(texture(height_tex_sampler, vec3(var_uv, height_texture_layer)).rrr) / 65535.0; break;
5757
}
5858
}

nucleus/EngineContext.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ using namespace nucleus;
2222

2323
EngineContext::EngineContext() { }
2424

25+
const tile::utils::AabbDecoratorPtr& EngineContext::aabb_decorator() const { return m_aabb_decorator; }
26+
27+
void EngineContext::set_aabb_decorator(const tile::utils::AabbDecoratorPtr& new_aabb_decorator) { m_aabb_decorator = new_aabb_decorator; }
28+
2529
EngineContext::EngineContext(QObject* parent)
2630
: QObject(parent)
2731
{

nucleus/EngineContext.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
#include <QObject>
2222

23-
#include "nucleus/track/Manager.h"
23+
#include <nucleus/tile/utils.h>
24+
#include <nucleus/track/Manager.h>
2425

2526
namespace nucleus {
2627

@@ -34,6 +35,9 @@ class EngineContext : public QObject {
3435
[[nodiscard]] virtual track::Manager* track_manager() = 0;
3536
bool is_alive() const;
3637

38+
[[nodiscard]] const tile::utils::AabbDecoratorPtr& aabb_decorator() const;
39+
void set_aabb_decorator(const tile::utils::AabbDecoratorPtr& new_aabb_decorator);
40+
3741
protected:
3842
explicit EngineContext();
3943
virtual void internal_initialise() = 0;
@@ -45,5 +49,6 @@ class EngineContext : public QObject {
4549
private:
4650
bool m_initialised = false;
4751
bool m_destroyed = false;
52+
tile::utils::AabbDecoratorPtr m_aabb_decorator;
4853
};
4954
} // namespace nucleus

0 commit comments

Comments
 (0)