Skip to content

Commit 32af77f

Browse files
committed
fix normals (AlpineMapsOrg#162)
1 parent bbff632 commit 32af77f

File tree

2 files changed

+134
-19
lines changed

2 files changed

+134
-19
lines changed

gl_engine/shaders/tile.glsl

+127-13
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,133 @@ highp float y_to_lat(highp float y) {
3939
return latRad;
4040
}
4141

42-
highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direction, out float quad_width, out float quad_height, out float altitude_correction_factor) {
43-
highp uvec3 instance_tile_id = unpack_tile_id(instance_tile_id_packed);
4442

45-
highp uvec3 dtm_tile_id = instance_tile_id;
43+
void compute_vertex(out vec3 position, out vec2 uv, out uvec3 tile_id, bool compute_normal, out vec3 normal) {
44+
tile_id = unpack_tile_id(instance_tile_id_packed);
45+
46+
highp uvec3 dtm_tile_id = tile_id;
47+
{
48+
uint dtm_zoom = texelFetch(instance_2_zoom_sampler, ivec2(uint(gl_InstanceID), 0), 0).x;
49+
decrease_zoom_level_until(dtm_tile_id, dtm_zoom);
50+
}
51+
highp int n_quads_per_direction_int = (n_edge_vertices - 1) >> (tile_id.z - dtm_tile_id.z);
52+
highp float n_quads_per_direction = float(n_quads_per_direction_int);
53+
highp float quad_size = (instance_bounds.z - instance_bounds.x) / n_quads_per_direction;
54+
55+
highp int row = gl_VertexID / n_edge_vertices;
56+
highp int col = gl_VertexID - (row * n_edge_vertices);
57+
highp int curtain_vertex_id = gl_VertexID - n_edge_vertices * n_edge_vertices;
58+
if (curtain_vertex_id >= 0) {
59+
if (curtain_vertex_id < n_edge_vertices) {
60+
row = (n_edge_vertices - 1) - curtain_vertex_id;
61+
col = (n_edge_vertices - 1);
62+
}
63+
else if (curtain_vertex_id >= n_edge_vertices && curtain_vertex_id < 2 * n_edge_vertices - 1) {
64+
row = 0;
65+
col = (n_edge_vertices - 1) - (curtain_vertex_id - n_edge_vertices) - 1;
66+
}
67+
else if (curtain_vertex_id >= 2 * n_edge_vertices - 1 && curtain_vertex_id < 3 * n_edge_vertices - 2) {
68+
row = curtain_vertex_id - 2 * n_edge_vertices + 2;
69+
col = 0;
70+
}
71+
else {
72+
row = (n_edge_vertices - 1);
73+
col = curtain_vertex_id - 3 * n_edge_vertices + 3;
74+
}
75+
}
76+
if (row > n_quads_per_direction_int) {
77+
row = n_quads_per_direction_int;
78+
curtain_vertex_id = 1;
79+
}
80+
if (col > n_quads_per_direction_int) {
81+
col = n_quads_per_direction_int;
82+
curtain_vertex_id = 1;
83+
}
84+
85+
position.y = float(n_quads_per_direction_int - row) * float(quad_size) + instance_bounds.y;
86+
position.x = float(col) * quad_size + instance_bounds.x;
87+
uv = vec2(float(col) / n_quads_per_direction, float(row) / n_quads_per_direction);
88+
89+
highp vec2 dtm_uv = uv;
90+
uint dtm_zoom = dtm_tile_id.z;
91+
dtm_tile_id = tile_id;
92+
decrease_zoom_level_until(dtm_tile_id, dtm_uv, dtm_zoom);
93+
highp float dtm_texture_layer_f = float(texelFetch(instance_2_array_index_sampler, ivec2(uint(gl_InstanceID), 0), 0).x);
94+
float altitude_tex = float(texture(height_tex_sampler, vec3(dtm_uv, dtm_texture_layer_f)).r);
95+
96+
// Note: for higher zoom levels it would be enough to calculate the altitude_correction_factor on cpu
97+
// for lower zoom levels we could bake it into the texture.
98+
// there was no measurable difference despite a cos and a atan, so leaving as is for now.
99+
highp float world_space_y = position.y + camera.position.y;
100+
highp float altitude_correction_factor = 0.125 / cos(y_to_lat(world_space_y)); // https://github.com/AlpineMapsOrg/renderer/issues/5
101+
float adjusted_altitude = altitude_tex * altitude_correction_factor;
102+
position.z = adjusted_altitude - camera.position.z;
103+
104+
if (curtain_vertex_id >= 0) {
105+
float curtain_height = CURTAIN_REFERENCE_HEIGHT;
106+
#if CURTAIN_HEIGHT_MODE == 1
107+
float dist_factor = clamp(length(position) / 100000.0, 0.2, 1.0);
108+
curtain_height *= dist_factor;
109+
#endif
110+
#if CURTAIN_HEIGHT_MODE == 2
111+
float zoom_factor = 1.0 - max(0.1, float(tile_id.z) / 25.f);
112+
curtain_height *= zoom_factor;
113+
#endif
114+
position.z = position.z - curtain_height;
115+
}
116+
117+
if (compute_normal) {
118+
// from here: https://stackoverflow.com/questions/6656358/calculating-normals-in-a-triangle-mesh/21660173#21660173
119+
vec2 offset = vec2(1.0, 0.0) / (n_edge_vertices - 1);
120+
121+
highp float hL = float(texture(height_tex_sampler, vec3(dtm_uv - offset.xy, dtm_texture_layer_f)).r);
122+
hL *= altitude_correction_factor;
123+
highp float hR = float(texture(height_tex_sampler, vec3(dtm_uv + offset.xy, dtm_texture_layer_f)).r);
124+
hR *= altitude_correction_factor;
125+
highp float hD = float(texture(height_tex_sampler, vec3(dtm_uv + offset.yx, dtm_texture_layer_f)).r);
126+
hD *= altitude_correction_factor;
127+
highp float hU = float(texture(height_tex_sampler, vec3(dtm_uv - offset.yx, dtm_texture_layer_f)).r);
128+
hU *= altitude_correction_factor;
129+
130+
highp float threshold = 0.5 * offset.x;
131+
highp float quad_height = quad_size;
132+
highp float quad_width = quad_size;
133+
if (dtm_uv.x < threshold || dtm_uv.x > 1.0 - threshold )
134+
quad_width = quad_size / 2.0; // half on the edge of a tile_id_packed, as the height texture is clamped
135+
136+
if (dtm_uv.y < threshold || dtm_uv.y > 1.0 - threshold )
137+
quad_height = quad_size / 2.0;
138+
139+
normal = normalize(vec3((hL - hR)/quad_width, (hD - hU)/quad_height, 2.));
140+
}
141+
}
142+
143+
void compute_vertex(out vec3 position, out vec2 uv, out uvec3 tile_id, out vec3 normal) {
144+
compute_vertex(position, uv, tile_id, true, normal);
145+
}
146+
147+
void compute_vertex(out vec3 position) {
148+
highp vec2 uv;
149+
highp uvec3 tile_id;
150+
vec3 normal;
151+
compute_vertex(position, uv, tile_id, false, normal);
152+
}
153+
154+
155+
156+
highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direction, out float quad_size, out float quad_height, out float altitude_correction_factor) {
157+
highp uvec3 tile_id = unpack_tile_id(instance_tile_id_packed);
158+
159+
highp uvec3 dtm_tile_id = tile_id;
46160
{
47161
uint dtm_zoom = texelFetch(instance_2_zoom_sampler, ivec2(uint(gl_InstanceID), 0), 0).x;
48162
decrease_zoom_level_until(dtm_tile_id, dtm_zoom);
49163
}
50164

51-
highp int n_quads_per_direction_int = (n_edge_vertices - 1) >> (instance_tile_id.z - dtm_tile_id.z);
165+
highp int n_quads_per_direction_int = (n_edge_vertices - 1) >> (tile_id.z - dtm_tile_id.z);
52166
n_quads_per_direction = float(n_quads_per_direction_int);
53167
// highp vec4 bounds = texelFetch(instance_2_bounds_sampler, ivec2(uint(gl_InstanceID), 0), 0);
54-
quad_width = (instance_bounds.z - instance_bounds.x) / n_quads_per_direction;
168+
quad_size = (instance_bounds.z - instance_bounds.x) / n_quads_per_direction;
55169
quad_height = (instance_bounds.w - instance_bounds.y) / n_quads_per_direction;
56170

57171
highp int row = gl_VertexID / n_edge_vertices;
@@ -86,7 +200,7 @@ highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direct
86200
// Note: for higher zoom levels it would be enough to calculate the altitude_correction_factor on cpu
87201
// for lower zoom levels we could bake it into the texture.
88202
// but there was no measurable difference despite a cos and a atan, so leaving as is for now.
89-
highp float var_pos_cws_y = float(n_quads_per_direction_int - row) * float(quad_width) + instance_bounds.y;
203+
highp float var_pos_cws_y = float(n_quads_per_direction_int - row) * float(quad_size) + instance_bounds.y;
90204
highp float pos_y = var_pos_cws_y + camera.position.y;
91205
altitude_correction_factor = 0.125 / cos(y_to_lat(pos_y)); // https://github.com/AlpineMapsOrg/renderer/issues/5
92206

@@ -95,7 +209,7 @@ highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direct
95209
/////////
96210
highp vec2 dtm_uv = uv;
97211
uint dtm_zoom = dtm_tile_id.z;
98-
dtm_tile_id = instance_tile_id;
212+
dtm_tile_id = tile_id;
99213
decrease_zoom_level_until(dtm_tile_id, dtm_uv, dtm_zoom);
100214

101215
highp float dtm_texture_layer_f = float(texelFetch(instance_2_array_index_sampler, ivec2(uint(gl_InstanceID), 0), 0).x);
@@ -104,7 +218,7 @@ highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direct
104218
// float altitude_tex = float(texelFetch(height_tex_sampler, ivec3(col, row, height_texture_layer), 0).r);
105219
float adjusted_altitude = altitude_tex * altitude_correction_factor;
106220

107-
highp vec3 var_pos_cws = vec3(float(col) * quad_width + instance_bounds.x, var_pos_cws_y, adjusted_altitude - camera.position.z);
221+
highp vec3 var_pos_cws = vec3(float(col) * quad_size + instance_bounds.x, var_pos_cws_y, adjusted_altitude - camera.position.z);
108222

109223
if (curtain_vertex_id >= 0) {
110224
float curtain_height = CURTAIN_REFERENCE_HEIGHT;
@@ -125,13 +239,13 @@ highp vec3 camera_world_space_position(out vec2 uv, out float n_quads_per_direct
125239
highp vec3 camera_world_space_position() {
126240
vec2 uv;
127241
float n_quads_per_direction;
128-
float quad_width;
242+
float quad_size;
129243
float quad_height;
130244
float altitude_correction_factor;
131-
return camera_world_space_position(uv, n_quads_per_direction, quad_width, quad_height, altitude_correction_factor);
245+
return camera_world_space_position(uv, n_quads_per_direction, quad_size, quad_height, altitude_correction_factor);
132246
}
133247

134-
highp vec3 normal_by_finite_difference_method(vec2 uv, float edge_vertices_count, float quad_width, float quad_height, float altitude_correction_factor) {
248+
highp vec3 normal_by_finite_difference_method(vec2 uv, float edge_vertices_count, float quad_size, float quad_height, float altitude_correction_factor) {
135249
// from here: https://stackoverflow.com/questions/6656358/calculating-normals-in-a-triangle-mesh/21660173#21660173
136250
vec2 offset = vec2(1.0, 0.0) / (edge_vertices_count);
137251

@@ -148,10 +262,10 @@ highp vec3 normal_by_finite_difference_method(vec2 uv, float edge_vertices_count
148262

149263
highp float threshold = 0.5 / edge_vertices_count;
150264
if (uv.x < threshold || uv.x > 1.0 - threshold )
151-
quad_width = quad_width / 2.0; // half on the edge of a instance_tile_id_packed, as the height texture is clamped
265+
quad_size = quad_size / 2.0; // half on the edge of a tile_id_packed, as the height texture is clamped
152266

153267
if (uv.y < threshold || uv.y > 1.0 - threshold )
154268
quad_height = quad_height / 2.0;
155269

156-
return normalize(vec3((hL - hR)/quad_width, (hD - hU)/quad_height, 2.));
270+
return normalize(vec3((hL - hR)/quad_size, (hD - hU)/quad_height, 2.));
157271
}

gl_engine/shaders/tile.vert

+7-6
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ flat out highp uint instance_id;
3535

3636
void main() {
3737
float n_quads_per_direction;
38-
float quad_width;
38+
float quad_size;
3939
float quad_height;
4040
float altitude_correction_factor;
41-
var_pos_cws = camera_world_space_position(var_uv, n_quads_per_direction, quad_width, quad_height, altitude_correction_factor);
41+
// var_pos_cws = camera_world_space_position(var_uv, n_quads_per_direction, quad_size, quad_height, altitude_correction_factor);
4242

43-
if (conf.normal_mode == 1u) {
44-
var_normal = normal_by_finite_difference_method(var_uv, n_quads_per_direction, quad_width, quad_height, altitude_correction_factor);
45-
}
43+
// if (conf.normal_mode == 1u) {
44+
// var_normal = normal_by_finite_difference_method(var_uv, n_quads_per_direction, quad_size, quad_height, altitude_correction_factor);
45+
// }
46+
compute_vertex(var_pos_cws, var_uv, var_tile_id, conf.normal_mode == 1u, var_normal);
4647

47-
var_tile_id = unpack_tile_id(instance_tile_id_packed);
48+
// var_tile_id = unpack_tile_id(instance_tile_id_packed);
4849
gl_Position = camera.view_proj_matrix * vec4(var_pos_cws, 1);
4950
instance_id = uint(gl_InstanceID);
5051

0 commit comments

Comments
 (0)