diff options
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/font.cpp | 6 | ||||
-rw-r--r-- | scene/resources/importer_mesh.cpp | 41 | ||||
-rw-r--r-- | scene/resources/importer_mesh.h | 2 | ||||
-rw-r--r-- | scene/resources/sky_material.cpp | 86 | ||||
-rw-r--r-- | scene/resources/sky_material.h | 4 |
5 files changed, 85 insertions, 54 deletions
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 189d8d5502..3d9e4e4a63 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -554,7 +554,6 @@ Font::Font() { } Font::~Font() { - reset_state(); } /*************************************************************************/ @@ -2433,11 +2432,10 @@ int32_t FontFile::get_glyph_index(int p_size, char32_t p_char, char32_t p_variat } FontFile::FontFile() { - /* NOP */ } FontFile::~FontFile() { - reset_state(); + _clear_cache(); } /*************************************************************************/ @@ -2688,7 +2686,6 @@ FontVariation::FontVariation() { } FontVariation::~FontVariation() { - reset_state(); } /*************************************************************************/ @@ -3081,5 +3078,4 @@ SystemFont::SystemFont() { } SystemFont::~SystemFont() { - reset_state(); } diff --git a/scene/resources/importer_mesh.cpp b/scene/resources/importer_mesh.cpp index 0afca95de0..de3d502102 100644 --- a/scene/resources/importer_mesh.cpp +++ b/scene/resources/importer_mesh.cpp @@ -254,7 +254,20 @@ void ImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_ma mesh.unref(); } -void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_split_angle) { +#define VERTEX_SKIN_FUNC(bone_count, vert_idx, read_array, write_array, transform_array, bone_array, weight_array) \ + Vector3 transformed_vert = Vector3(); \ + for (unsigned int weight_idx = 0; weight_idx < bone_count; weight_idx++) { \ + int bone_idx = bone_array[vert_idx * bone_count + weight_idx]; \ + float w = weight_array[vert_idx * bone_count + weight_idx]; \ + if (w < FLT_EPSILON) { \ + continue; \ + } \ + ERR_FAIL_INDEX(bone_idx, static_cast<int>(transform_array.size())); \ + transformed_vert += transform_array[bone_idx].xform(read_array[vert_idx]) * w; \ + } \ + write_array[vert_idx] = transformed_vert; + +void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_split_angle, Array p_bone_transform_array) { if (!SurfaceTool::simplify_scale_func) { return; } @@ -265,6 +278,12 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli return; } + LocalVector<Transform3D> bone_transform_vector; + for (int i = 0; i < p_bone_transform_array.size(); i++) { + ERR_FAIL_COND(p_bone_transform_array[i].get_type() != Variant::TRANSFORM3D); + bone_transform_vector.push_back(p_bone_transform_array[i]); + } + for (int i = 0; i < surfaces.size(); i++) { if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) { continue; @@ -276,6 +295,8 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli Vector<Vector3> normals = surfaces[i].arrays[RS::ARRAY_NORMAL]; Vector<Vector2> uvs = surfaces[i].arrays[RS::ARRAY_TEX_UV]; Vector<Vector2> uv2s = surfaces[i].arrays[RS::ARRAY_TEX_UV2]; + Vector<int> bones = surfaces[i].arrays[RS::ARRAY_BONES]; + Vector<float> weights = surfaces[i].arrays[RS::ARRAY_WEIGHTS]; unsigned int index_count = indices.size(); unsigned int vertex_count = vertices.size(); @@ -301,6 +322,22 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, float p_normal_spli } } + if (bones.size() > 0 && weights.size() && bone_transform_vector.size() > 0) { + Vector3 *vertices_ptrw = vertices.ptrw(); + + // Apply bone transforms to regular surface. + unsigned int bone_weight_length = surfaces[i].flags & Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS ? 8 : 4; + + const int *bo = bones.ptr(); + const float *we = weights.ptr(); + + for (unsigned int j = 0; j < vertex_count; j++) { + VERTEX_SKIN_FUNC(bone_weight_length, j, vertices_ptr, vertices_ptrw, bone_transform_vector, bo, we) + } + + vertices_ptr = vertices.ptr(); + } + float normal_merge_threshold = Math::cos(Math::deg_to_rad(p_normal_merge_angle)); float normal_pre_split_threshold = Math::cos(Math::deg_to_rad(MIN(180.0f, p_normal_split_angle * 2.0f))); float normal_split_threshold = Math::cos(Math::deg_to_rad(p_normal_split_angle)); @@ -1246,7 +1283,7 @@ void ImporterMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_surface_name", "surface_idx", "name"), &ImporterMesh::set_surface_name); ClassDB::bind_method(D_METHOD("set_surface_material", "surface_idx", "material"), &ImporterMesh::set_surface_material); - ClassDB::bind_method(D_METHOD("generate_lods", "normal_merge_angle", "normal_split_angle"), &ImporterMesh::generate_lods); + ClassDB::bind_method(D_METHOD("generate_lods", "normal_merge_angle", "normal_split_angle", "bone_transform_array"), &ImporterMesh::generate_lods); ClassDB::bind_method(D_METHOD("get_mesh", "base_mesh"), &ImporterMesh::get_mesh, DEFVAL(Ref<ArrayMesh>())); ClassDB::bind_method(D_METHOD("clear"), &ImporterMesh::clear); diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index dce2638c19..088a77edd1 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -112,7 +112,7 @@ public: void set_surface_material(int p_surface, const Ref<Material> &p_material); - void generate_lods(float p_normal_merge_angle, float p_normal_split_angle); + void generate_lods(float p_normal_merge_angle, float p_normal_split_angle, Array p_skin_pose_transform_array); void create_shadow_mesh(); Ref<ImporterMesh> get_shadow_mesh() const; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index fc999d5fcb..d21f04fab8 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -34,7 +34,7 @@ #include "core/version.h" Mutex ProceduralSkyMaterial::shader_mutex; -RID ProceduralSkyMaterial::shader; +RID ProceduralSkyMaterial::shader_cache[2]; void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) { sky_top_color = p_sky_top; @@ -147,7 +147,11 @@ float ProceduralSkyMaterial::get_sun_curve() const { void ProceduralSkyMaterial::set_use_debanding(bool p_use_debanding) { use_debanding = p_use_debanding; - RS::get_singleton()->material_set_param(_get_material(), "use_debanding", use_debanding); + _update_shader(); + // Only set if shader already compiled + if (shader_set) { + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(use_debanding)]); + } } bool ProceduralSkyMaterial::get_use_debanding() const { @@ -161,7 +165,8 @@ Shader::Mode ProceduralSkyMaterial::get_shader_mode() const { RID ProceduralSkyMaterial::get_rid() const { _update_shader(); if (!shader_set) { - RS::get_singleton()->material_set_shader(_get_material(), shader); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[1 - int(use_debanding)]); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(use_debanding)]); shader_set = true; } return _get_material(); @@ -169,7 +174,7 @@ RID ProceduralSkyMaterial::get_rid() const { RID ProceduralSkyMaterial::get_shader_rid() const { _update_shader(); - return shader; + return shader_cache[int(use_debanding)]; } void ProceduralSkyMaterial::_validate_property(PropertyInfo &p_property) const { @@ -241,21 +246,24 @@ void ProceduralSkyMaterial::_bind_methods() { } void ProceduralSkyMaterial::cleanup_shader() { - if (shader.is_valid()) { - RS::get_singleton()->free(shader); + if (shader_cache[0].is_valid()) { + RS::get_singleton()->free(shader_cache[0]); + RS::get_singleton()->free(shader_cache[1]); } } void ProceduralSkyMaterial::_update_shader() { shader_mutex.lock(); - if (shader.is_null()) { - shader = RS::get_singleton()->shader_create(); + if (shader_cache[0].is_null()) { + for (int i = 0; i < 2; i++) { + shader_cache[i] = RS::get_singleton()->shader_create(); - // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). - RS::get_singleton()->shader_set_code(shader, R"( + // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). + RS::get_singleton()->shader_set_code(shader_cache[i], vformat(R"( // NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s ProceduralSkyMaterial. shader_type sky; +%s uniform vec4 sky_top_color : source_color = vec4(0.385, 0.454, 0.55, 1.0); uniform vec4 sky_horizon_color : source_color = vec4(0.646, 0.656, 0.67, 1.0); @@ -269,14 +277,6 @@ uniform float ground_curve : hint_range(0, 1) = 0.02; uniform float ground_energy = 1.0; uniform float sun_angle_max = 30.0; uniform float sun_curve : hint_range(0, 1) = 0.15; -uniform bool use_debanding = true; - -// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare -vec3 interleaved_gradient_noise(vec2 pos) { - const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f); - float res = fract(magic.z * fract(dot(pos, magic.xy))) * 2.0 - 1.0; - return vec3(res, -res, res) / 255.0; -} void sky() { float v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0)); @@ -332,11 +332,10 @@ void sky() { ground *= ground_energy; COLOR = mix(ground, sky, step(0.0, EYEDIR.y)); - if (use_debanding) { - COLOR += interleaved_gradient_noise(FRAGCOORD.xy); - } } -)"); +)", + i ? "render_mode use_debanding;" : "")); + } } shader_mutex.unlock(); } @@ -546,7 +545,11 @@ float PhysicalSkyMaterial::get_energy_multiplier() const { void PhysicalSkyMaterial::set_use_debanding(bool p_use_debanding) { use_debanding = p_use_debanding; - RS::get_singleton()->material_set_param(_get_material(), "use_debanding", use_debanding); + _update_shader(); + // Only set if shader already compiled + if (shader_set) { + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(use_debanding)]); + } } bool PhysicalSkyMaterial::get_use_debanding() const { @@ -570,7 +573,8 @@ Shader::Mode PhysicalSkyMaterial::get_shader_mode() const { RID PhysicalSkyMaterial::get_rid() const { _update_shader(); if (!shader_set) { - RS::get_singleton()->material_set_shader(_get_material(), shader); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[1 - int(use_debanding)]); + RS::get_singleton()->material_set_shader(_get_material(), shader_cache[int(use_debanding)]); shader_set = true; } return _get_material(); @@ -578,7 +582,7 @@ RID PhysicalSkyMaterial::get_rid() const { RID PhysicalSkyMaterial::get_shader_rid() const { _update_shader(); - return shader; + return shader_cache[int(use_debanding)]; } void PhysicalSkyMaterial::_validate_property(PropertyInfo &p_property) const { @@ -588,7 +592,7 @@ void PhysicalSkyMaterial::_validate_property(PropertyInfo &p_property) const { } Mutex PhysicalSkyMaterial::shader_mutex; -RID PhysicalSkyMaterial::shader; +RID PhysicalSkyMaterial::shader_cache[2]; void PhysicalSkyMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient); @@ -642,21 +646,24 @@ void PhysicalSkyMaterial::_bind_methods() { } void PhysicalSkyMaterial::cleanup_shader() { - if (shader.is_valid()) { - RS::get_singleton()->free(shader); + if (shader_cache[0].is_valid()) { + RS::get_singleton()->free(shader_cache[0]); + RS::get_singleton()->free(shader_cache[1]); } } void PhysicalSkyMaterial::_update_shader() { shader_mutex.lock(); - if (shader.is_null()) { - shader = RS::get_singleton()->shader_create(); + if (shader_cache[0].is_null()) { + for (int i = 0; i < 2; i++) { + shader_cache[i] = RS::get_singleton()->shader_create(); - // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). - RS::get_singleton()->shader_set_code(shader, R"( + // Add a comment to describe the shader origin (useful when converting to ShaderMaterial). + RS::get_singleton()->shader_set_code(shader_cache[i], vformat(R"( // NOTE: Shader automatically converted from )" VERSION_NAME " " VERSION_FULL_CONFIG R"('s PhysicalSkyMaterial. shader_type sky; +%s uniform float rayleigh : hint_range(0, 64) = 2.0; uniform vec4 rayleigh_color : source_color = vec4(0.3, 0.405, 0.6, 1.0); @@ -668,7 +675,6 @@ uniform float turbidity : hint_range(0, 1000) = 10.0; uniform float sun_disk_scale : hint_range(0, 360) = 1.0; uniform vec4 ground_color : source_color = vec4(0.1, 0.07, 0.034, 1.0); uniform float exposure : hint_range(0, 128) = 1.0; -uniform bool use_debanding = true; uniform sampler2D night_sky : source_color, hint_default_black; @@ -683,13 +689,6 @@ float henyey_greenstein(float cos_theta, float g) { return k * (1.0 - g * g) / (pow(1.0 + g * g - 2.0 * g * cos_theta, 1.5)); } -// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare -vec3 interleaved_gradient_noise(vec2 pos) { - const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f); - float res = fract(magic.z * fract(dot(pos, magic.xy))) * 2.0 - 1.0; - return vec3(res, -res, res) / 255.0; -} - void sky() { if (LIGHT0_ENABLED) { float zenith_angle = clamp( dot(UP, normalize(LIGHT0_DIRECTION)), -1.0, 1.0 ); @@ -737,16 +736,15 @@ void sky() { vec3 color = Lin + L0; COLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade)))); COLOR *= exposure; - if (use_debanding) { - COLOR += interleaved_gradient_noise(FRAGCOORD.xy); - } } else { // There is no sun, so display night_sky and nothing else. COLOR = texture(night_sky, SKY_COORDS).xyz; COLOR *= exposure; } } -)"); +)", + i ? "render_mode use_debanding;" : "")); + } } shader_mutex.unlock(); diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index b517fd806b..fbb202d8d8 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -55,7 +55,7 @@ private: bool use_debanding = true; static Mutex shader_mutex; - static RID shader; + static RID shader_cache[2]; static void _update_shader(); mutable bool shader_set = false; @@ -160,7 +160,7 @@ class PhysicalSkyMaterial : public Material { private: static Mutex shader_mutex; - static RID shader; + static RID shader_cache[2]; float rayleigh = 0.0f; Color rayleigh_color; |