From 7fba7e0f8d0cfd87f1d1a865ce48f0d1e9525a7c Mon Sep 17 00:00:00 2001 From: Xtarsia <69606701+Xtarsia@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:57:13 +0000 Subject: [PATCH] fix region edges behaviour --- src/shaders/main.glsl | 50 ++++++++++++++++++++++++--------------- src/terrain_3d.cpp | 6 ++--- src/terrain_3d_editor.cpp | 8 +++---- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/shaders/main.glsl b/src/shaders/main.glsl index fa4a3198..e5566d7e 100644 --- a/src/shaders/main.glsl +++ b/src/shaders/main.glsl @@ -23,8 +23,11 @@ render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlic * */ -// Private uniforms +// Defined Constants +#define VERTEX_PASS 1 +#define FRAGMENT_PASS 2 +// Private uniforms uniform uint _background_mode = 1u; // NONE = 0, FLAT = 1, NOISE = 2 uniform uint _mouse_layer = 0x80000000u; // Layer 32 uniform float _vertex_spacing = 1.0; @@ -92,14 +95,23 @@ varying vec3 v_normal; // Vertex //////////////////////// -// Takes in UV world space coordinates, returns ivec3 with: +// Takes in UV world space coordinates & search depth (only applicable for background mode none) +// Returns ivec3 with: // XY: (0 to _region_size) coordinates within a region // Z: layer index used for texturearrays, -1 if not in a region -ivec3 get_region_uv(const vec2 uv) { - ivec2 pos = ivec2(floor(uv * _region_texel_size)) + (_region_map_size / 2); - int bounds = int(uint(pos.x | pos.y) < uint(_region_map_size)); - int layer_index = _region_map[ pos.y * _region_map_size + pos.x ] * bounds - 1; - return ivec3(ivec2(mod(uv,_region_size)), layer_index); +ivec3 get_region_uv(const vec2 uv, const int search) { + vec2 r_uv = uv + 1.0; + ivec2 pos; + int bounds, layer_index = 0; + for (int i = -1; i < clamp(search, VERTEX_PASS, FRAGMENT_PASS); i++) { + if ((layer_index == -1 && _background_mode == 0u ) || i < 0) { + r_uv -= 1.0; + pos = ivec2(floor((r_uv) * _region_texel_size)) + (_region_map_size / 2); + bounds = int(uint(pos.x | pos.y) < uint(_region_map_size)); + layer_index = (_region_map[ pos.y * _region_map_size + pos.x ] * bounds - 1); + } + } + return ivec3(ivec2(mod(r_uv,_region_size)), layer_index); } // Takes in UV2 region space coordinates, returns vec3 with: @@ -131,19 +143,19 @@ void vertex() { UV2 = fma(UV, vec2(_region_texel_size), vec2(0.5 * _region_texel_size)); // Discard vertices for Holes. 1 lookup - v_region = get_region_uv(UV); + v_region = get_region_uv(UV, VERTEX_PASS); uint control = texelFetch(_control_maps, v_region, 0).r; bool hole = bool(control >>2u & 0x1u); // Show holes to all cameras except mouse camera (on exactly 1 layer) if ( !(CAMERA_VISIBLE_LAYERS == _mouse_layer) && - (hole || (_background_mode == 0u && (get_region_uv(UV - _region_texel_size) & v_region).z < 0))) { + (hole || (_background_mode == 0u && v_region.z < 0))) { v_vertex.x = 0. / 0.; } else { // Set final vertex height & calculate vertex normals. 3 lookups float h = texelFetch(_height_maps, v_region, 0).r; - float u = texelFetch(_height_maps, get_region_uv(UV + vec2(1,0)), 0).r; - float v = texelFetch(_height_maps, get_region_uv(UV + vec2(0,1)), 0).r; + float u = texelFetch(_height_maps, get_region_uv(UV + vec2(1,0), VERTEX_PASS), 0).r; + float v = texelFetch(_height_maps, get_region_uv(UV + vec2(0,1), VERTEX_PASS), 0).r; //INSERT: WORLD_NOISE2 v_vertex.y = h; v_normal = vec3(h - u, _vertex_spacing, h - v); @@ -338,10 +350,10 @@ void fragment() { ivec3 indexUV[4]; // control map lookups, used for some normal lookups as well - indexUV[0] = get_region_uv(index_id + offsets.xy); - indexUV[1] = get_region_uv(index_id + offsets.yy); - indexUV[2] = get_region_uv(index_id + offsets.yx); - indexUV[3] = get_region_uv(index_id + offsets.xx); + indexUV[0] = get_region_uv(index_id + offsets.xy, FRAGMENT_PASS); + indexUV[1] = get_region_uv(index_id + offsets.yy, FRAGMENT_PASS); + indexUV[2] = get_region_uv(index_id + offsets.yx, FRAGMENT_PASS); + indexUV[3] = get_region_uv(index_id + offsets.xx, FRAGMENT_PASS); // Terrain normals vec3 index_normal[4]; @@ -371,10 +383,10 @@ void fragment() { // 5 lookups // Fetch the additional required height values for smooth normals h[3] = texelFetch(_height_maps, indexUV[1], 0).r; // 3 (1,1) - h[4] = texelFetch(_height_maps, get_region_uv(index_id + offsets.yz), 0).r; // 4 (1,2) - h[5] = texelFetch(_height_maps, get_region_uv(index_id + offsets.zy), 0).r; // 5 (2,1) - h[6] = texelFetch(_height_maps, get_region_uv(index_id + offsets.zx), 0).r; // 6 (2,0) - h[7] = texelFetch(_height_maps, get_region_uv(index_id + offsets.xz), 0).r; // 7 (0,2) + h[4] = texelFetch(_height_maps, get_region_uv(index_id + offsets.yz, FRAGMENT_PASS), 0).r; // 4 (1,2) + h[5] = texelFetch(_height_maps, get_region_uv(index_id + offsets.zy, FRAGMENT_PASS), 0).r; // 5 (2,1) + h[6] = texelFetch(_height_maps, get_region_uv(index_id + offsets.zx, FRAGMENT_PASS), 0).r; // 6 (2,0) + h[7] = texelFetch(_height_maps, get_region_uv(index_id + offsets.xz, FRAGMENT_PASS), 0).r; // 7 (0,2) // Calculate the normal for the remaining index ids. index_normal[0] = normalize(vec3(h[2] - h[3] + u, _vertex_spacing, h[2] - h[7] + v)); diff --git a/src/terrain_3d.cpp b/src/terrain_3d.cpp index c1513441..65fc9248 100644 --- a/src/terrain_3d.cpp +++ b/src/terrain_3d.cpp @@ -268,19 +268,19 @@ void Terrain3D::_update_collision() { if (map_x.is_valid()) { map_data[index] = (is_hole(cmap_x->get_pixel(0, z).r)) ? NAN : map_x->get_pixel(0, z).r; } else { - map_data[index] = 0.0f; + map_data[index] = NAN; } } else if (z == _region_size && x < _region_size) { if (map_z.is_valid()) { map_data[index] = (is_hole(cmap_z->get_pixel(x, 0).r)) ? NAN : map_z->get_pixel(x, 0).r; } else { - map_data[index] = 0.0f; + map_data[index] = NAN; } } else if (x == _region_size && z == _region_size) { if (map_xz.is_valid()) { map_data[index] = (is_hole(cmap_xz->get_pixel(0, 0).r)) ? NAN : map_xz->get_pixel(0, 0).r; } else { - map_data[index] = 0.0f; + map_data[index] = NAN; } } } diff --git a/src/terrain_3d_editor.cpp b/src/terrain_3d_editor.cpp index d7fe8af5..fc66681f 100644 --- a/src/terrain_3d_editor.cpp +++ b/src/terrain_3d_editor.cpp @@ -261,19 +261,19 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_ Vector3 up_position = brush_global_position + Vector3(0.f, 0.f, vertex_spacing); real_t left = data->get_pixel(map_type, left_position).r; if (std::isnan(left)) { - left = 0.f; + left = srcf; } real_t right = data->get_pixel(map_type, right_position).r; if (std::isnan(right)) { - right = 0.f; + right = srcf; } real_t up = data->get_pixel(map_type, up_position).r; if (std::isnan(up)) { - up = 0.f; + up = srcf; } real_t down = data->get_pixel(map_type, down_position).r; if (std::isnan(down)) { - down = 0.f; + down = srcf; } real_t avg = (srcf + left + right + up + down) * 0.2f; destf = Math::lerp(srcf, avg, CLAMP(brush_alpha * strength * 2.f, .02f, 1.f));