Merge branch 'master' into storage_refactoring

master
Marc Gilleron 2022-09-03 17:22:41 +01:00
commit 191c963e2a
16 changed files with 62 additions and 59 deletions

View File

@ -587,12 +587,13 @@ Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, Node *par
for (int i = 0; i < materials.size(); ++i) {
Ref<ShaderMaterial> sm = materials[i];
if (sm.is_valid() && sm->get_shader().is_valid() &&
sm->get_shader()->has_uniform(VoxelStringNames::get_singleton().u_block_local_transform)) {
sm->get_shader()->has_parameter(VoxelStringNames::get_singleton().u_block_local_transform)) {
// That parameter should have a valid default value matching the local transform relative to the
// volume, which is usually per-instance, but in Godot 3 we have no such feature, so we have to
// duplicate.
sm = sm->duplicate(false);
sm->set_shader_uniform(VoxelStringNames::get_singleton().u_block_local_transform, local_transform);
sm->set_shader_parameter(
VoxelStringNames::get_singleton().u_block_local_transform, local_transform);
materials[i] = sm;
}
}

View File

@ -22,7 +22,7 @@ void ChartView::set_points(Span<const Vector2> points) {
_points.write[i] = points[i];
}
update();
queue_redraw();
}
void ChartView::auto_fit_view(Vector2 margin_ratios) {
@ -44,7 +44,7 @@ void ChartView::auto_fit_view(Vector2 margin_ratios) {
_view_min -= view_size * margin_ratios;
_view_max += view_size * margin_ratios;
update();
queue_redraw();
}
void ChartView::_notification(int p_what) {

View File

@ -253,7 +253,7 @@ void VoxelGraphEditorNode::set_profiling_ratio_visible(bool visible) {
return;
}
_profiling_ratio_enabled = visible;
update();
queue_redraw();
}
void VoxelGraphEditorNode::set_profiling_ratio(float ratio) {
@ -261,7 +261,7 @@ void VoxelGraphEditorNode::set_profiling_ratio(float ratio) {
return;
}
_profiling_ratio = ratio;
update();
queue_redraw();
}
// Color has no lerp??

View File

@ -11,12 +11,12 @@ using namespace math;
void get_curve_monotonic_sections(Curve &curve, std::vector<CurveMonotonicSection> &sections) {
const int res = curve.get_bake_resolution();
float prev_y = curve.interpolate_baked(0.f);
float prev_y = curve.sample_baked(0.f);
sections.clear();
CurveMonotonicSection section;
section.x_min = 0.f;
section.y_min = curve.interpolate_baked(0.f);
section.y_min = curve.sample_baked(0.f);
float prev_x = 0.f;
bool current_stationary = true;
@ -24,7 +24,7 @@ void get_curve_monotonic_sections(Curve &curve, std::vector<CurveMonotonicSectio
for (int i = 1; i < res; ++i) {
const float x = static_cast<float>(i) / res;
const float y = curve.interpolate_baked(x);
const float y = curve.sample_baked(x);
// Curve can sometimes appear flat but it still oscillates by very small amounts due to float imprecision
// which occurred during bake(). Attempting to workaround that by taking the error into account
const bool increasing = y > prev_y + CURVE_RANGE_MARGIN;
@ -65,21 +65,21 @@ Interval get_curve_range(Curve &curve, const std::vector<CurveMonotonicSection>
unsigned int i = 0;
if (x.min < sections[0].x_min) {
// X range starts before the curve's minimum X
y = Interval::from_single_value(curve.interpolate_baked(0.f));
y = Interval::from_single_value(curve.sample_baked(0.f));
} else {
// Find section from where the range starts
for (; i < sections.size(); ++i) {
const CurveMonotonicSection &section = sections[i];
if (x.min >= section.x_min) {
const float begin_y = curve.interpolate_baked(x.min);
const float begin_y = curve.sample_baked(x.min);
if (x.max < section.x_max) {
// X range starts and ends in that section
return Interval::from_unordered_values(begin_y, curve.interpolate_baked(x.max))
return Interval::from_unordered_values(begin_y, curve.sample_baked(x.max))
.padded(CURVE_RANGE_MARGIN);
} else {
// X range starts in that section, and continues after it.
// Will need to keep iterating, starting from here
y = Interval::from_unordered_values(begin_y, curve.interpolate_baked(section.x_max));
y = Interval::from_unordered_values(begin_y, curve.sample_baked(section.x_max));
++i;
break;
}
@ -93,7 +93,7 @@ Interval get_curve_range(Curve &curve, const std::vector<CurveMonotonicSection>
y.add_interval(Interval::from_unordered_values(section.y_min, section.y_max));
} else {
// X range ends in that section
y.add_interval(Interval::from_unordered_values(section.y_min, curve.interpolate_baked(x.max)));
y.add_interval(Interval::from_unordered_values(section.y_min, curve.sample_baked(x.max)));
break;
}
}
@ -104,12 +104,12 @@ Interval get_curve_range(Curve &curve, bool &is_monotonic_increasing) {
// TODO Would be nice to have the cache directly
const int res = curve.get_bake_resolution();
Interval range;
float prev_v = curve.interpolate_baked(0.f);
if (curve.interpolate_baked(1.f) > prev_v) {
float prev_v = curve.sample_baked(0.f);
if (curve.sample_baked(1.f) > prev_v) {
is_monotonic_increasing = true;
}
for (int i = 0; i < res; ++i) {
const float v = curve.interpolate_baked(static_cast<float>(i) / res);
const float v = curve.sample_baked(static_cast<float>(i) / res);
range.add_point(v);
if (v < prev_v) {
is_monotonic_increasing = false;

View File

@ -1033,14 +1033,14 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
VoxelGraphRuntime::Buffer &out = ctx.get_output(0);
const Params p = ctx.get_params<Params>();
for (uint32_t i = 0; i < out.size; ++i) {
out.data[i] = p.curve->interpolate_baked(a.data[i]);
out.data[i] = p.curve->sample_baked(a.data[i]);
}
};
t.range_analysis_func = [](RangeAnalysisContext &ctx) {
const Interval a = ctx.get_input(0);
const Params p = ctx.get_params<Params>();
if (a.is_single_value()) {
const float v = p.curve->interpolate_baked(a.min);
const float v = p.curve->sample_baked(a.min);
ctx.set_output(0, Interval::from_single_value(v));
} else {
const Interval r = get_curve_range(*p.curve, p.curve_range_data->sections, a);

View File

@ -81,8 +81,7 @@ VoxelGenerator::Result VoxelGeneratorNoise2D::generate_block(VoxelGenerator::Vox
Curve &curve = **params.curve;
result = VoxelGeneratorHeightmap::generate(
out_buffer,
[&noise, &curve](
int x, int z) { return curve.interpolate_baked(0.5 + 0.5 * noise.get_noise_2d(x, z)); },
[&noise, &curve](int x, int z) { return curve.sample_baked(0.5 + 0.5 * noise.get_noise_2d(x, z)); },
input.origin_in_voxels, input.lod);
}
@ -114,7 +113,7 @@ void VoxelGeneratorNoise2D::generate_series(Span<const float> positions_x, Span<
Curve &curve = **params.curve;
generate_series_template(
[&noise, &curve](float x, float z) { //
return curve.interpolate_baked(0.5 + 0.5 * noise.get_noise_2d(x, z));
return curve.sample_baked(0.5 + 0.5 * noise.get_noise_2d(x, z));
},
positions_x, positions_y, positions_z, channel, out_values, min_pos, max_pos);
}

View File

@ -157,6 +157,9 @@ void VoxelModifier::_bind_methods() {
"get_operation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "smoothness", PROPERTY_HINT_RANGE, "0.0, 100.0, 0.1"), "set_smoothness",
"get_smoothness");
BIND_ENUM_CONSTANT(OPERATION_ADD);
BIND_ENUM_CONSTANT(OPERATION_REMOVE);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -189,7 +189,7 @@ void VoxelStreamRegionFiles::_save_block(VoxelBufferInternal &voxel_buffer, Vect
FileResult load_res = load_meta();
if (load_res != FILE_OK && load_res != FILE_CANT_OPEN) {
// The file is present but there is a problem with it
String meta_path = _directory_path.plus_file(META_FILE_NAME);
String meta_path = _directory_path.path_join(META_FILE_NAME);
ERR_PRINT(String("Could not read {0}: error {1}").format(varray(meta_path, zylann::to_string(load_res))));
return;
}
@ -291,7 +291,7 @@ FileResult VoxelStreamRegionFiles::save_meta() {
}
}
const String meta_path = _directory_path.plus_file(META_FILE_NAME);
const String meta_path = _directory_path.path_join(META_FILE_NAME);
const CharString meta_path_utf8 = meta_path.utf8();
Error err;
@ -337,7 +337,7 @@ FileResult VoxelStreamRegionFiles::load_meta() {
// Ensure you cleanup previous world before loading another
CRASH_COND(_region_cache.size() > 0);
const String meta_path = _directory_path.plus_file(META_FILE_NAME);
const String meta_path = _directory_path.path_join(META_FILE_NAME);
String json_string;
{
@ -423,7 +423,7 @@ String VoxelStreamRegionFiles::get_region_file_path(const Vector3i &region_pos,
a[2] = region_pos.y;
a[3] = region_pos.z;
a[4] = RegionFormat::FILE_EXTENSION;
return _directory_path.plus_file(String("regions/lod{0}/r.{1}.{2}.{3}.{4}").format(a));
return _directory_path.path_join(String("regions/lod{0}/r.{1}.{2}.{3}.{4}").format(a));
}
VoxelStreamRegionFiles::CachedRegion *VoxelStreamRegionFiles::get_region_from_cache(const Vector3i pos, int lod) const {
@ -614,7 +614,7 @@ void VoxelStreamRegionFiles::_convert_files(Meta new_meta) {
{
for (int lod = 0; lod < old_meta.lod_count; ++lod) {
const String lod_folder =
old_stream->_directory_path.plus_file("regions").plus_file("lod") + String::num_int64(lod);
old_stream->_directory_path.path_join("regions").path_join("lod") + String::num_int64(lod);
const String ext = String(".") + RegionFormat::FILE_EXTENSION;
Ref<DirAccess> da = DirAccess::open(lod_folder);

View File

@ -61,15 +61,15 @@ void ShaderMaterialPoolVLT::recycle(Ref<ShaderMaterial> material) {
ZN_ASSERT_RETURN(material.is_valid());
// Reset textures to avoid hoarding them in the pool
material->set_shader_uniform(VoxelStringNames::get_singleton().u_voxel_normalmap_atlas, Ref<Texture2DArray>());
material->set_shader_uniform(VoxelStringNames::get_singleton().u_voxel_cell_lookup, Ref<Texture2D>());
material->set_shader_parameter(VoxelStringNames::get_singleton().u_voxel_normalmap_atlas, Ref<Texture2DArray>());
material->set_shader_parameter(VoxelStringNames::get_singleton().u_voxel_cell_lookup, Ref<Texture2D>());
// TODO Would be nice if we repurposed `u_transition_mask` to store extra flags.
// Here we exploit cell_size==0 as "there is no virtual normalmaps on this block"
material->set_shader_uniform(VoxelStringNames::get_singleton().u_voxel_cell_size, 0.f);
material->set_shader_uniform(VoxelStringNames::get_singleton().u_voxel_virtual_texture_fade, 0.f);
material->set_shader_parameter(VoxelStringNames::get_singleton().u_voxel_cell_size, 0.f);
material->set_shader_parameter(VoxelStringNames::get_singleton().u_voxel_virtual_texture_fade, 0.f);
material->set_shader_uniform(VoxelStringNames::get_singleton().u_transition_mask, 0);
material->set_shader_uniform(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
material->set_shader_parameter(VoxelStringNames::get_singleton().u_transition_mask, 0);
material->set_shader_parameter(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
ShaderMaterialPool::recycle(material);
}
@ -458,7 +458,7 @@ void VoxelLodTerrain::set_mesh_block_active(VoxelMeshBlockVLT &block, bool activ
Ref<ShaderMaterial> mat = block.get_shader_material();
if (mat.is_valid()) {
mat->set_shader_uniform(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
mat->set_shader_parameter(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
}
} else if (active && _lod_fade_duration > 0.f) {
@ -467,7 +467,7 @@ void VoxelLodTerrain::set_mesh_block_active(VoxelMeshBlockVLT &block, bool activ
// parameter. Otherwise, it would be active but invisible due to still being faded out.
Ref<ShaderMaterial> mat = block.get_shader_material();
if (mat.is_valid()) {
mat->set_shader_uniform(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
mat->set_shader_parameter(VoxelStringNames::get_singleton().u_lod_fade, Vector2(0.0, 0.0));
}
}
@ -1550,24 +1550,24 @@ void VoxelLodTerrain::apply_virtual_texture_update_to_block(
if (material.is_valid()) {
const VoxelStringNames &sn = VoxelStringNames::get_singleton();
const bool had_texture = material->get_shader_uniform(sn.u_voxel_cell_lookup) != Variant();
material->set_shader_uniform(sn.u_voxel_normalmap_atlas, normalmap_textures.atlas);
material->set_shader_uniform(sn.u_voxel_cell_lookup, normalmap_textures.lookup);
const bool had_texture = material->get_shader_parameter(sn.u_voxel_cell_lookup) != Variant();
material->set_shader_parameter(sn.u_voxel_normalmap_atlas, normalmap_textures.atlas);
material->set_shader_parameter(sn.u_voxel_cell_lookup, normalmap_textures.lookup);
const int cell_size = 1 << lod_index;
material->set_shader_uniform(sn.u_voxel_cell_size, cell_size);
material->set_shader_uniform(sn.u_voxel_block_size, get_mesh_block_size());
material->set_shader_parameter(sn.u_voxel_cell_size, cell_size);
material->set_shader_parameter(sn.u_voxel_block_size, get_mesh_block_size());
if (!had_texture) {
if (_lod_fade_duration > 0.f) {
// Fade-in to reduce "popping" details
_fading_virtual_textures.push_back(FadingVirtualTexture{ block.position, lod_index, 0.f });
material->set_shader_uniform(sn.u_voxel_virtual_texture_fade, 0.f);
material->set_shader_parameter(sn.u_voxel_virtual_texture_fade, 0.f);
} else {
material->set_shader_uniform(sn.u_voxel_virtual_texture_fade, 1.f);
material->set_shader_parameter(sn.u_voxel_virtual_texture_fade, 1.f);
}
const unsigned int tile_size = get_virtual_texture_tile_resolution_for_lod(
_update_data->settings.virtual_texture_settings, lod_index);
material->set_shader_uniform(sn.u_voxel_virtual_texture_tile_size, tile_size);
material->set_shader_parameter(sn.u_voxel_virtual_texture_tile_size, tile_size);
}
}
// If the material is not valid... well it means the user hasn't set up one, so all the hardwork of making these
@ -1703,7 +1703,7 @@ void VoxelLodTerrain::process_fading_blocks(float delta) {
_fading_out_meshes[i] = std::move(_fading_out_meshes.back());
_fading_out_meshes.pop_back();
} else {
item.shader_material->set_shader_uniform(
item.shader_material->set_shader_parameter(
VoxelStringNames::get_singleton().u_lod_fade, Vector2(1.f - item.progress, 0.f));
++i;
}
@ -1727,7 +1727,7 @@ void VoxelLodTerrain::process_fading_blocks(float delta) {
if (sm.is_valid()) {
item.progress = math::min(item.progress + speed, 1.f);
remove = item.progress >= 1.f;
sm->set_shader_uniform(
sm->set_shader_parameter(
VoxelStringNames::get_singleton().u_voxel_virtual_texture_fade, item.progress);
}
}

View File

@ -150,7 +150,7 @@ void VoxelMeshBlockVLT::set_shader_material(Ref<ShaderMaterial> material) {
if (_shader_material.is_valid()) {
const Transform3D local_transform(Basis(), _position_in_voxels);
_shader_material->set_shader_uniform(
_shader_material->set_shader_parameter(
VoxelStringNames::get_singleton().u_block_local_transform, local_transform);
}
}
@ -188,7 +188,7 @@ void VoxelMeshBlockVLT::set_transition_mask(uint8_t m) {
tm |= bits[Cube::SIDE_POSITIVE_Z] << 5;
// TODO Godot 4: we may replace this with a per-instance parameter so we can lift material access limitation
_shader_material->set_shader_uniform(VoxelStringNames::get_singleton().u_transition_mask, tm);
_shader_material->set_shader_parameter(VoxelStringNames::get_singleton().u_transition_mask, tm);
}
for (int dir = 0; dir < Cube::SIDE_COUNT; ++dir) {
DirectMeshInstance &mi = _transition_mesh_instances[dir];
@ -287,7 +287,7 @@ bool VoxelMeshBlockVLT::update_fading(float speed) {
}
if (_shader_material.is_valid()) {
_shader_material->set_shader_uniform(VoxelStringNames::get_singleton().u_lod_fade, p);
_shader_material->set_shader_parameter(VoxelStringNames::get_singleton().u_lod_fade, p);
}
return finished;

View File

@ -61,7 +61,7 @@ bool create_clean_dir(const char *dirpath) {
const Error err = da->make_dir(dirpath);
ERR_FAIL_COND_V(err != OK, false);
ERR_FAIL_COND_V(!create_empty_file(String(dirpath).plus_file(".gdignore")), false);
ERR_FAIL_COND_V(!create_empty_file(String(dirpath).path_join(".gdignore")), false);
return true;
}

View File

@ -1190,7 +1190,7 @@ void test_get_curve_monotonic_sections() {
{
math::Interval xi(0.2f, 0.8f);
math::Interval yi = get_curve_range(**curve, sections, xi);
math::Interval yi_expected(curve->interpolate_baked(xi.min), curve->interpolate_baked(xi.max));
math::Interval yi_expected(curve->sample_baked(xi.min), curve->sample_baked(xi.max));
ZYLANN_TEST_ASSERT(L::is_equal_approx(yi.min, yi_expected.min));
ZYLANN_TEST_ASSERT(L::is_equal_approx(yi.max, yi_expected.max));
}
@ -1382,7 +1382,7 @@ void test_region_file() {
const char *region_file_name = "test_region_file.vxr";
zylann::testing::TestDirectory test_dir;
ZYLANN_TEST_ASSERT(test_dir.is_valid());
String region_file_path = test_dir.get_path().plus_file(region_file_name);
String region_file_path = test_dir.get_path().path_join(region_file_name);
struct RandomBlockGenerator {
RandomPCG rng;

View File

@ -94,10 +94,10 @@ void DirectMeshInstance::set_cast_shadows_setting(RenderingServer::ShadowCasting
vs.instance_geometry_set_cast_shadows_setting(_mesh_instance, mode);
}
void DirectMeshInstance::set_shader_instance_uniform(StringName key, Variant value) {
void DirectMeshInstance::set_shader_instance_parameter(StringName key, Variant value) {
ERR_FAIL_COND(!_mesh_instance.is_valid());
RenderingServer &vs = *RenderingServer::get_singleton();
vs.instance_geometry_set_shader_uniform(_mesh_instance, key, value);
vs.instance_geometry_set_shader_parameter(_mesh_instance, key, value);
}
Ref<Mesh> DirectMeshInstance::get_mesh() const {

View File

@ -25,7 +25,7 @@ public:
void set_material_override(Ref<Material> material);
void set_visible(bool visible);
void set_cast_shadows_setting(RenderingServer::ShadowCastingSetting mode);
void set_shader_instance_uniform(StringName key, Variant value);
void set_shader_instance_parameter(StringName key, Variant value);
// Convenience
enum GIMode { //

View File

@ -9,7 +9,7 @@ namespace zylann {
// See https://github.com/godotengine/godot/issues/64467
bool shader_has_uniform(const Shader &shader, StringName uniform_name) {
List<PropertyInfo> params;
RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader.get_rid(), &params);
RenderingServer::get_singleton()->get_shader_parameter_list(shader.get_rid(), &params);
for (const PropertyInfo &pi : params) {
if (pi.name == uniform_name) {
return true;
@ -35,7 +35,7 @@ String get_missing_uniform_names(Span<const StringName> expected_uniforms, const
// }
List<PropertyInfo> params;
RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader.get_rid(), &params);
RenderingServer::get_singleton()->get_shader_parameter_list(shader.get_rid(), &params);
for (const StringName &name : expected_uniforms) {
bool found = false;

View File

@ -14,7 +14,7 @@ void ShaderMaterialPool::set_template(Ref<ShaderMaterial> tpl) {
if (shader.is_valid()) {
List<PropertyInfo> params;
RenderingServer::get_singleton()->shader_get_shader_uniform_list(shader->get_rid(), &params);
RenderingServer::get_singleton()->get_shader_parameter_list(shader->get_rid(), &params);
for (const PropertyInfo &pi : params) {
_shader_params_cache.push_back(pi.name);
@ -42,7 +42,7 @@ Ref<ShaderMaterial> ShaderMaterialPool::allocate() {
material->set_shader(_template_material->get_shader());
for (const StringName &name : _shader_params_cache) {
// Note, I don't need to make copies of textures. They are shared.
material->set_shader_uniform(name, _template_material->get_shader_uniform(name));
material->set_shader_parameter(name, _template_material->get_shader_parameter(name));
}
return material;
}
@ -71,7 +71,7 @@ void copy_shader_params(const ShaderMaterial &src, ShaderMaterial &dst, Span<con
// }
for (unsigned int i = 0; i < params.size(); ++i) {
const StringName &name = params[i];
dst.set_shader_uniform(name, src.get_shader_uniform(name));
dst.set_shader_parameter(name, src.get_shader_parameter(name));
}
}