From 9a1def8da1279f60e86bcdb740c30ac6293e4cc8 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Thu, 13 Jun 2024 15:16:18 -0700 Subject: [PATCH] Add new StandardMaterial properties to allow users to control FPS-style objects (hands, weapons, tools close to the camera) Add new shader built in Z_CLIP_SCALE to easily adjust clipping distance to avoid clipping walls etc. Add fov_override to StandardMaterial3D to easily have a custom FOV for FPS objects Add IN_SHADOW_PASS built-in to shaders for tweaking materials without impacting shadow maps --- doc/classes/BaseMaterial3D.xml | 21 +++++- drivers/gles3/shaders/scene.glsl | 22 ++++++ drivers/gles3/storage/material_storage.cpp | 3 + scene/resources/material.cpp | 75 ++++++++++++++++++- scene/resources/material.h | 12 +++ .../render_forward_clustered.cpp | 2 + .../scene_shader_forward_clustered.cpp | 7 +- .../scene_shader_forward_clustered.h | 3 +- .../scene_shader_forward_mobile.cpp | 9 ++- .../scene_forward_clustered.glsl | 28 ++++--- .../forward_mobile/scene_forward_mobile.glsl | 28 ++++++- .../renderer_rd/shaders/scene_data_inc.glsl | 43 ++++++----- .../storage_rd/render_scene_data_rd.cpp | 41 +++++----- .../storage_rd/render_scene_data_rd.h | 48 ++++++------ servers/rendering/shader_types.cpp | 2 + 15 files changed, 254 insertions(+), 90 deletions(-) diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index 77b6bb68173..c2917c47b54 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -229,6 +229,10 @@ If [code]true[/code], the object is rendered at the same size regardless of distance. The object's size on screen is the same as if the camera was [code]1.0[/code] units away from the object's origin, regardless of the actual distance from the camera. The [Camera3D]'s field of view (or [member Camera3D.size] when in orthogonal/frustum mode) still affects the size the object is drawn at. + + Overrides the [Camera3D]'s field of view angle (in degrees). + [b]Note:[/b] This behaves as if the field of view is set on a [Camera3D] with [member Camera3D.keep_aspect] set to [constant Camera3D.KEEP_HEIGHT]. Additionally, it may not look correct on a non-perspective camera where the field of view setting is ignored. + If [code]true[/code], enables the vertex grow setting. This can be used to create mesh-based outlines using a second material pass and its [member cull_mode] set to [constant CULL_FRONT]. See also [member grow_amount]. [b]Note:[/b] Vertex growth cannot create new vertices, which means that visible gaps may occur in sharp corners. This can be alleviated by designing the mesh to use smooth normals exclusively using [url=http://wiki.polycount.com/wiki/Face_weighted_normals]face weighted normals[/url] in the 3D authoring software. In this case, grow will be able to join every outline together, just like in the original mesh. @@ -407,6 +411,9 @@ The material's transparency mode. Some transparency modes will disable shadow casting. Any transparency mode other than [constant TRANSPARENCY_DISABLED] has a greater performance impact compared to opaque rendering. See also [member blend_mode]. + + If [code]true[/code] use [member fov_override] to override the [Camera3D]'s field of view angle. + If [code]true[/code], enables parts of the shader required for [GPUParticles3D] trails to function. This also requires using a mesh with appropriate skinning, such as [RibbonTrailMesh] or [TubeTrailMesh]. Enabling this feature outside of materials used in [GPUParticles3D] meshes will break material rendering. @@ -414,6 +421,9 @@ If [code]true[/code], render point size can be changed. [b]Note:[/b] This is only effective for objects whose geometry is point-based rather than triangle-based. See also [member point_size]. + + If [code]true[/code] use [member z_clip_scale] to scale the object being rendered towards the camera to avoid clipping into things like walls. + How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else. @@ -453,6 +463,9 @@ If [code]true[/code], the vertex color is used as albedo color. + + Scales the object being rendered towards the camera to avoid clipping into things like walls. This is intended to be used for objects that are fixed with respect to the camera like player arms, tools, etc. Lighting and shadows will continue to work correctly when this setting is adjusted, but screen-space effects like SSAO and SSR may break with lower scales. Therefore, try to keep this setting as close to [code]1.0[/code] as possible. + @@ -727,7 +740,13 @@ Disables specular occlusion. - + + Enables using [member z_clip_scale]. + + + Enables using [member fov_override]. + + Represents the size of the [enum Flags] enum. diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 0ff75bf7640..2e313ccaf39 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -46,6 +46,12 @@ LIGHTMAP_BICUBIC_FILTER = false #define SHADER_IS_SRGB true #define SHADER_SPACE_FAR -1.0 +#if defined(RENDER_SHADOWS) || defined(RENDER_SHADOWS_LINEAR) +#define IN_SHADOW_PASS true +#else +#define IN_SHADOW_PASS false +#endif + #include "stdlib_inc.glsl" #if !defined(MODE_RENDER_DEPTH) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) ||defined(LIGHT_CLEARCOAT_USED) @@ -607,6 +613,10 @@ void main() { #endif #endif +#ifdef Z_CLIP_SCALE_USED + float z_clip_scale = 1.0; +#endif + float roughness = 1.0; highp mat4 modelview = scene_data.view_matrix * model_matrix; @@ -712,6 +722,12 @@ void main() { gl_Position = projection_matrix * vec4(vertex_interp, 1.0); #endif +#if !defined(RENDER_SHADOWS) && !defined(RENDER_SHADOWS_LINEAR) +#ifdef Z_CLIP_SCALE_USED + gl_Position.z = mix(gl_Position.w, gl_Position.z, z_clip_scale); +#endif +#endif + #ifdef RENDER_MATERIAL vec2 uv_dest_attrib; if (uv_scale != vec4(0.0)) { @@ -833,6 +849,12 @@ void main() { #define SHADER_IS_SRGB true #define SHADER_SPACE_FAR -1.0 +#if defined(RENDER_SHADOWS) || defined(RENDER_SHADOWS_LINEAR) +#define IN_SHADOW_PASS true +#else +#define IN_SHADOW_PASS false +#endif + #define FLAGS_NON_UNIFORM_SCALE (1 << 4) /* Varyings */ diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index e8d38a41f74..65b68bf765b 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1232,6 +1232,7 @@ MaterialStorage::MaterialStorage() { actions.renames["POINT_SIZE"] = "point_size"; actions.renames["INSTANCE_ID"] = "gl_InstanceID"; actions.renames["VERTEX_ID"] = "gl_VertexID"; + actions.renames["Z_CLIP_SCALE"] = "z_clip_scale"; actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold"; actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale"; @@ -1247,6 +1248,7 @@ MaterialStorage::MaterialStorage() { actions.renames["E"] = String::num(Math::E); actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR"; + actions.renames["IN_SHADOW_PASS"] = "IN_SHADOW_PASS"; actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; @@ -1336,6 +1338,7 @@ MaterialStorage::MaterialStorage() { actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; actions.usage_defines["LIGHT_VERTEX"] = "#define LIGHT_VERTEX_USED\n"; + actions.usage_defines["Z_CLIP_SCALE"] = "#define Z_CLIP_SCALE_USED\n"; actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n"; actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n"; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index de5bee6b623..382bc233b99 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -666,6 +666,8 @@ void BaseMaterial3D::init_shaders() { shader_names->alpha_antialiasing_edge = "alpha_antialiasing_edge"; shader_names->albedo_texture_size = "albedo_texture_size"; + shader_names->z_clip_scale = "z_clip_scale"; + shader_names->fov_override = "fov_override"; } HashMap> BaseMaterial3D::materials_for_2d; @@ -1135,6 +1137,14 @@ uniform vec3 uv2_scale; uniform vec3 uv2_offset; )"; + if (flags[FLAG_USE_Z_CLIP_SCALE]) { + code += "uniform float z_clip_scale : hint_range(0.01, 1.0, 0.01);\n"; + } + + if (flags[FLAG_USE_FOV_OVERRIDE]) { + code += "uniform float fov_override : hint_range(1.0, 179.0, 0.1);\n"; + } + // Generate vertex shader. code += R"( void vertex() {)"; @@ -1378,6 +1388,25 @@ void vertex() {)"; )"; } + if (flags[FLAG_USE_Z_CLIP_SCALE]) { + code += R"( + Z_CLIP_SCALE = z_clip_scale; +)"; + } + + if (flags[FLAG_USE_FOV_OVERRIDE]) { + code += R"( + if (!IN_SHADOW_PASS) { + float flip_y = sign(PROJECTION_MATRIX[1][1]); + float aspect = PROJECTION_MATRIX[1][1] / PROJECTION_MATRIX[0][0]; + float f = flip_y / tan(fov_override * PI / 360.0); + PROJECTION_MATRIX[0][0] = f / aspect; + PROJECTION_MATRIX[1][1] = f; + } +)"; + } + + // End of the vertex shader function. code += "}\n"; if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) { @@ -2375,7 +2404,9 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) { p_flag == FLAG_SUBSURFACE_MODE_SKIN || p_flag == FLAG_USE_POINT_SIZE || p_flag == FLAG_UV1_USE_TRIPLANAR || - p_flag == FLAG_UV2_USE_TRIPLANAR) { + p_flag == FLAG_UV2_USE_TRIPLANAR || + p_flag == FLAG_USE_Z_CLIP_SCALE || + p_flag == FLAG_USE_FOV_OVERRIDE) { notify_property_list_changed(); } @@ -2510,6 +2541,14 @@ void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const { p_property.usage = PROPERTY_USAGE_NO_EDITOR; } + if (p_property.name == "z_clip_scale" && !flags[FLAG_USE_Z_CLIP_SCALE]) { + p_property.usage = PROPERTY_USAGE_NO_EDITOR; + } + + if (p_property.name == "fov_override" && !flags[FLAG_USE_FOV_OVERRIDE]) { + p_property.usage = PROPERTY_USAGE_NO_EDITOR; + } + // you can only enable anti-aliasing (in materials) on alpha scissor and alpha hash const bool can_select_aa = (transparency == TRANSPARENCY_ALPHA_SCISSOR || transparency == TRANSPARENCY_ALPHA_HASH); // alpha anti aliasiasing is only enabled when you can select aa @@ -2860,6 +2899,24 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() return refraction_texture_channel; } +void BaseMaterial3D::set_z_clip_scale(float p_z_clip_scale) { + z_clip_scale = p_z_clip_scale; + _material_set_param(shader_names->z_clip_scale, p_z_clip_scale); +} + +float BaseMaterial3D::get_z_clip_scale() const { + return z_clip_scale; +} + +void BaseMaterial3D::set_fov_override(float p_fov_override) { + fov_override = p_fov_override; + _material_set_param(shader_names->fov_override, p_fov_override); +} + +float BaseMaterial3D::get_fov_override() const { + return fov_override; +} + Ref BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, AlphaAntiAliasing p_alpha_antialiasing_mode, RID *r_shader_rid) { uint64_t key = 0; key |= ((int8_t)p_shaded & 0x01) << 0; @@ -3212,6 +3269,12 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_distance_fade_min_distance", "distance"), &BaseMaterial3D::set_distance_fade_min_distance); ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance); + ClassDB::bind_method(D_METHOD("set_z_clip_scale", "scale"), &BaseMaterial3D::set_z_clip_scale); + ClassDB::bind_method(D_METHOD("get_z_clip_scale"), &BaseMaterial3D::get_z_clip_scale); + + ClassDB::bind_method(D_METHOD("set_fov_override", "scale"), &BaseMaterial3D::set_fov_override); + ClassDB::bind_method(D_METHOD("get_fov_override"), &BaseMaterial3D::get_fov_override); + ADD_GROUP("Transparency", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); @@ -3381,7 +3444,10 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "point_size", PROPERTY_HINT_RANGE, "0.1,128,0.1,suffix:px"), "set_point_size", "get_point_size"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_particle_trails"), "set_flag", "get_flag", FLAG_PARTICLE_TRAILS_MODE); - + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_z_clip_scale"), "set_flag", "get_flag", FLAG_USE_Z_CLIP_SCALE); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "z_clip_scale", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"), "set_z_clip_scale", "get_z_clip_scale"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_fov_override"), "set_flag", "get_flag", FLAG_USE_FOV_OVERRIDE); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fov_override", PROPERTY_HINT_RANGE, "1,179,0.1,degrees"), "set_fov_override", "get_fov_override"); ADD_GROUP("Proximity Fade", "proximity_fade_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "proximity_fade_enabled"), "set_proximity_fade_enabled", "is_proximity_fade_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "proximity_fade_distance", PROPERTY_HINT_RANGE, "0.01,4096,0.01,suffix:m"), "set_proximity_fade_distance", "get_proximity_fade_distance"); @@ -3495,6 +3561,8 @@ void BaseMaterial3D::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF); BIND_ENUM_CONSTANT(FLAG_DISABLE_FOG); BIND_ENUM_CONSTANT(FLAG_DISABLE_SPECULAR_OCCLUSION); + BIND_ENUM_CONSTANT(FLAG_USE_Z_CLIP_SCALE); + BIND_ENUM_CONSTANT(FLAG_USE_FOV_OVERRIDE); BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); @@ -3589,6 +3657,9 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_heightmap_deep_parallax_max_layers(32); set_heightmap_deep_parallax_flip_tangent(false); //also sets binormal + set_z_clip_scale(1.0); + set_fov_override(75.0); + flags[FLAG_ALBEDO_TEXTURE_MSDF] = false; flags[FLAG_USE_TEXTURE_REPEAT] = true; diff --git a/scene/resources/material.h b/scene/resources/material.h index 17f14d51bea..441bd666fc7 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -269,6 +269,8 @@ public: FLAG_ALBEDO_TEXTURE_MSDF, FLAG_DISABLE_FOG, FLAG_DISABLE_SPECULAR_OCCLUSION, + FLAG_USE_Z_CLIP_SCALE, + FLAG_USE_FOV_OVERRIDE, FLAG_MAX }; @@ -466,6 +468,8 @@ private: StringName alpha_antialiasing_edge; StringName albedo_texture_size; + StringName z_clip_scale; + StringName fov_override; }; static Mutex material_mutex; @@ -563,6 +567,9 @@ private: AlphaAntiAliasing alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF; + float z_clip_scale = 1.0; + float fov_override = 75.0; + bool features[FEATURE_MAX] = {}; Ref textures[TEXTURE_MAX]; @@ -782,6 +789,11 @@ public: void set_refraction_texture_channel(TextureChannel p_channel); TextureChannel get_refraction_texture_channel() const; + void set_z_clip_scale(float p_z_clip_scale); + float get_z_clip_scale() const; + void set_fov_override(float p_fov_override); + float get_fov_override() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 2d7718da59a..23da0160797 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -2744,6 +2744,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page scene_data.time = time; scene_data.time_step = time_step; scene_data.main_cam_transform = p_main_cam_transform; + scene_data.shadow_pass = true; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -2836,6 +2837,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con scene_data.time = time; scene_data.time_step = time_step; scene_data.main_cam_transform = p_cam_transform; + scene_data.shadow_pass = true; // Not a shadow pass, but should be treated like one. RenderDataRD render_data; render_data.scene_data = &scene_data; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index cbd5bb9f09a..5e5da94515f 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -79,6 +79,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { writes_modelview_or_projection = false; uses_world_coordinates = false; uses_particle_trails = false; + uses_z_clip_scale = false; int depth_drawi = DEPTH_DRAW_OPAQUE; @@ -140,6 +141,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection; actions.write_flag_pointers["VERTEX"] = &uses_vertex; actions.write_flag_pointers["POSITION"] = &uses_position; + actions.write_flag_pointers["Z_CLIP_SCALE"] = &uses_z_clip_scale; actions.uniforms = &uniforms; @@ -613,6 +615,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["POINT_SIZE"] = "gl_PointSize"; actions.renames["INSTANCE_ID"] = "gl_InstanceIndex"; actions.renames["VERTEX_ID"] = "gl_VertexIndex"; + actions.renames["Z_CLIP_SCALE"] = "z_clip_scale"; actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold"; actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale"; @@ -628,6 +631,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["E"] = String::num(Math::E); actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR"; + actions.renames["IN_SHADOW_PASS"] = "bool(scene_data_block.data.flags & SCENE_DATA_FLAGS_IN_SHADOW_PASS)"; actions.renames["VIEWPORT_SIZE"] = "read_viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; @@ -717,12 +721,13 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; actions.usage_defines["LIGHT_VERTEX"] = "#define LIGHT_VERTEX_USED\n"; - actions.usage_defines["PREMUL_ALPHA_FACTOR"] = "#define PREMUL_ALPHA_USED\n"; + actions.usage_defines["Z_CLIP_SCALE"] = "#define Z_CLIP_SCALE_USED\n"; actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n"; actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n"; actions.usage_defines["ALPHA_ANTIALIASING_EDGE"] = "#define ALPHA_ANTIALIASING_EDGE_USED\n"; actions.usage_defines["ALPHA_TEXTURE_COORDINATE"] = "@ALPHA_ANTIALIASING_EDGE"; + actions.usage_defines["PREMUL_ALPHA_FACTOR"] = "#define PREMUL_ALPHA_USED\n"; actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n"; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 49fe869da62..79f10d4cabc 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -245,6 +245,7 @@ public: bool writes_modelview_or_projection = false; bool uses_world_coordinates = false; bool uses_screen_texture_mipmaps = false; + bool uses_z_clip_scale = false; RS::CullMode cull_mode = RS::CULL_MODE_DISABLED; uint64_t last_pass = 0; @@ -268,7 +269,7 @@ public: _FORCE_INLINE_ bool uses_shared_shadow_material() const { bool backface_culling = cull_mode == RS::CULL_MODE_BACK; - return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe; + return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe && !uses_z_clip_scale; } virtual void set_code(const String &p_Code); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 59e247783c6..785f0a89fee 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -485,14 +485,14 @@ void SceneShaderForwardMobile::init(const String p_defines) { const String base_define = ubershader ? "\n#define UBERSHADER\n" : ""; shader_versions.push_back(base_define + ""); // SHADER_VERSION_COLOR_PASS shader_versions.push_back(base_define + "\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS - shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here... - shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_SHADOW_PASS_DP + shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here... + shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS_DP shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL // Multiview versions of our shaders. shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW - shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW + shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW } Vector immutable_samplers; @@ -540,6 +540,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["POINT_SIZE"] = "gl_PointSize"; actions.renames["INSTANCE_ID"] = "gl_InstanceIndex"; actions.renames["VERTEX_ID"] = "gl_VertexIndex"; + actions.renames["Z_CLIP_SCALE"] = "z_clip_scale"; actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold"; actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale"; @@ -555,6 +556,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["E"] = String::num(Math::E); actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR"; + actions.renames["IN_SHADOW_PASS"] = "IN_SHADOW_PASS"; actions.renames["VIEWPORT_SIZE"] = "read_viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; @@ -644,6 +646,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; actions.usage_defines["LIGHT_VERTEX"] = "#define LIGHT_VERTEX_USED\n"; + actions.usage_defines["Z_CLIP_SCALE"] = "#define Z_CLIP_SCALE_USED\n"; actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n"; actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n"; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index c42bbe02517..7f2a9d2ecdc 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -400,6 +400,10 @@ void vertex_shader(vec3 vertex_input, #endif #endif +#ifdef Z_CLIP_SCALE_USED + float z_clip_scale = 1.0; +#endif + float roughness = 1.0; mat4 modelview = scene_data.view_matrix * model_matrix; @@ -644,14 +648,14 @@ void vertex_shader(vec3 vertex_input, #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING) #ifdef MODE_RENDER_DEPTH - if (scene_data.pancake_shadows) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS)) { if (gl_Position.z >= 0.9999) { gl_Position.z = 0.9999; } } #endif #ifdef MODE_RENDER_MATERIAL - if (scene_data.material_uv2_mode) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_UV2_MATERIAL)) { vec2 uv_dest_attrib; if (uv_scale != vec4(0.0)) { uv_dest_attrib = (uv2_attrib.xy - 0.5) * uv_scale.zw; @@ -665,6 +669,12 @@ void vertex_shader(vec3 vertex_input, gl_Position.w = 1.0; } #endif + +#ifdef Z_CLIP_SCALE_USED + if (!bool(scene_data_block.data.flags & SCENE_DATA_FLAGS_IN_SHADOW_PASS)) { + gl_Position.z = mix(gl_Position.w, gl_Position.z, z_clip_scale); + } +#endif } void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position, vec3 p_compressed_aabb_size, @@ -1381,7 +1391,7 @@ void fragment_shader(in SceneData scene_data) { // to maximize VGPR usage // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. - if (scene_data.fog_enabled) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) { fog = fog_process(vertex); } @@ -1391,7 +1401,7 @@ void fragment_shader(in SceneData scene_data) { #else vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z); #endif - if (scene_data.fog_enabled) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) { //must use the full blending equation here to blend fogs vec4 res; float sa = 1.0 - volumetric_fog.a; @@ -1543,7 +1553,7 @@ void fragment_shader(in SceneData scene_data) { /////////////////////// LIGHTING ////////////////////////////// #ifdef NORMAL_USED - if (scene_data.roughness_limiter_enabled) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER)) { //https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf float roughness2 = roughness * roughness; vec3 dndu = dFdx(normal), dndv = dFdy(normal); @@ -1574,7 +1584,7 @@ void fragment_shader(in SceneData scene_data) { vec3 indirect_normal = normal; #endif - if (scene_data.use_reflection_cubemap) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP)) { #ifdef LIGHT_ANISOTROPY_USED // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; @@ -1614,10 +1624,10 @@ void fragment_shader(in SceneData scene_data) { #ifndef USE_LIGHTMAP //lightmap overrides everything - if (scene_data.use_ambient_light) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT)) { ambient_light = scene_data.ambient_light_color_energy.rgb; - if (scene_data.use_ambient_cubemap) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP)) { vec3 ambient_dir = scene_data.radiance_inverse_xform * indirect_normal; #ifdef USE_RADIANCE_CUBEMAP_ARRAY vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb; @@ -1635,7 +1645,7 @@ void fragment_shader(in SceneData scene_data) { #ifdef LIGHT_CLEARCOAT_USED - if (scene_data.use_reflection_cubemap) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP)) { float NoV = max(dot(geo_normal, view), 0.0001); // We want to use geometric normal, not normal_map vec3 ref_vec = reflect(-view, geo_normal); ref_vec = mix(ref_vec, geo_normal, clearcoat_roughness * clearcoat_roughness); diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index d3836b38571..ce916f72f12 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -10,6 +10,12 @@ #define SHADER_IS_SRGB false #define SHADER_SPACE_FAR 0.0 +#ifdef SHADOW_PASS +#define IN_SHADOW_PASS true +#else +#define IN_SHADOW_PASS false +#endif + /* INPUT ATTRIBS */ // Always contains vertex position in XYZ, can contain tangent angle in W. @@ -377,6 +383,10 @@ void main() { #endif #endif +#ifdef Z_CLIP_SCALE_USED + float z_clip_scale = 1.0; +#endif + float roughness = 1.0; mat4 modelview = scene_data.view_matrix * model_matrix; @@ -559,15 +569,19 @@ void main() { gl_Position = projection_matrix * vec4(vertex_interp, 1.0); #endif // OVERRIDE_POSITION +#if defined(Z_CLIP_SCALE_USED) && !defined(SHADOW_PASS) + gl_Position.z = mix(gl_Position.w, gl_Position.z, z_clip_scale); +#endif + #ifdef MODE_RENDER_DEPTH - if (scene_data.pancake_shadows) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS)) { if (gl_Position.z >= 0.9999) { gl_Position.z = 0.9999; } } #endif // MODE_RENDER_DEPTH #ifdef MODE_RENDER_MATERIAL - if (scene_data.material_uv2_mode) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_UV2_MATERIAL)) { vec2 uv_dest_attrib; if (uv_scale != vec4(0.0)) { uv_dest_attrib = (uv2_attrib.xy - 0.5) * uv_scale.zw; @@ -591,6 +605,12 @@ void main() { #define SHADER_IS_SRGB false #define SHADER_SPACE_FAR 0.0 +#ifdef SHADOW_PASS +#define IN_SHADOW_PASS true +#else +#define IN_SHADOW_PASS false +#endif + /* Include our forward mobile UBOs definitions etc. */ #include "scene_forward_mobile_inc.glsl" @@ -1122,7 +1142,7 @@ void main() { // to maximize VGPR usage // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. - if (!sc_disable_fog() && scene_data.fog_enabled) { + if (!sc_disable_fog() && bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) { fog = fog_process(vertex); } @@ -1287,7 +1307,7 @@ void main() { #ifndef USE_LIGHTMAP //lightmap overrides everything - if (scene_data.use_ambient_light) { + if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT)) { ambient_light = scene_data.ambient_light_color_energy.rgb; if (sc_scene_use_ambient_cubemap()) { diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl index a2fef216f5c..566461e8186 100644 --- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl @@ -3,6 +3,15 @@ // This enables us to use this UBO in our main scene render shaders but also in // effects that need access to this data. +#define SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT (1 << 0) +#define SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP (1 << 1) +#define SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP (1 << 2) +#define SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER (1 << 3) +#define SCENE_DATA_FLAGS_USE_FOG (1 << 4) +#define SCENE_DATA_FLAGS_USE_UV2_MATERIAL (1 << 5) +#define SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS (1 << 6) +#define SCENE_DATA_FLAGS_IN_SHADOW_PASS (1 << 7) + struct SceneData { highp mat4 projection_matrix; highp mat4 inv_projection_matrix; @@ -26,15 +35,6 @@ struct SceneData { highp vec4 penumbra_shadow_kernel[32]; highp vec4 soft_shadow_kernel[32]; - mediump mat3 radiance_inverse_xform; - - mediump vec4 ambient_light_color_energy; - - mediump float ambient_color_sky_mix; - bool use_ambient_light; - bool use_ambient_cubemap; - bool use_reflection_cubemap; - highp vec2 shadow_atlas_pixel_size; highp vec2 directional_shadow_pixel_size; @@ -43,35 +43,34 @@ struct SceneData { highp float z_far; highp float z_near; - bool roughness_limiter_enabled; mediump float roughness_limiter_amount; mediump float roughness_limiter_limit; mediump float opaque_prepass_threshold; + highp uint flags; - bool fog_enabled; - uint fog_mode; + mediump mat3 radiance_inverse_xform; + + mediump vec4 ambient_light_color_energy; + + mediump float ambient_color_sky_mix; highp float fog_density; highp float fog_height; - highp float fog_height_density; + highp float fog_depth_curve; highp float fog_depth_begin; - highp float taa_frame_count; + highp float fog_depth_end; + mediump float fog_sun_scatter; mediump vec3 fog_light_color; - highp float fog_depth_end; - - mediump float fog_sun_scatter; mediump float fog_aerial_perspective; + highp float time; - mediump float reflection_multiplier; // one normally, zero when rendering reflections - + highp float taa_frame_count; vec2 taa_jitter; - bool material_uv2_mode; - float emissive_exposure_normalization; + float emissive_exposure_normalization; float IBL_exposure_normalization; - bool pancake_shadows; uint camera_visible_layers; float pass_alpha_multiplier; }; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp index 2dfb647d5e2..5e4519fbb95 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp @@ -116,7 +116,9 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.z_far = z_far; ubo.z_near = z_near; - ubo.pancake_shadows = p_pancake_shadows; + ubo.flags = 0; + + ubo.flags |= p_pancake_shadows ? SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS : 0; RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel); RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel); @@ -143,18 +145,15 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.directional_light_count = directional_light_count; ubo.dual_paraboloid_side = dual_paraboloid_side; ubo.opaque_prepass_threshold = opaque_prepass_threshold; - ubo.material_uv2_mode = material_uv2_mode; - - ubo.fog_enabled = false; + ubo.flags |= material_uv2_mode ? SCENE_DATA_FLAGS_USE_UV2_MATERIAL : 0; + ubo.flags |= shadow_pass ? SCENE_DATA_FLAGS_IN_SHADOW_PASS : 0; if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - ubo.use_ambient_light = true; + ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT; ubo.ambient_light_color_energy[0] = 1; ubo.ambient_light_color_energy[1] = 1; ubo.ambient_light_color_energy[2] = 1; ubo.ambient_light_color_energy[3] = 1.0; - ubo.use_ambient_cubemap = false; - ubo.use_reflection_cubemap = false; } else if (p_env.is_valid()) { RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env); RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env); @@ -173,8 +172,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier; ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier; ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier; - ubo.use_ambient_light = true; - ubo.use_ambient_cubemap = false; + ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT; } else { float energy = render_scene_render->environment_get_ambient_light_energy(p_env); Color color = render_scene_render->environment_get_ambient_light(p_env); @@ -187,20 +185,19 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p sky_transform = sky_transform.inverse() * cam_transform.basis; RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform); - ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; - ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; + bool use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; + bool use_ambient_light = use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR; + ubo.flags |= use_ambient_cubemap ? SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP : 0; + ubo.flags |= use_ambient_light ? SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT : 0; } //specular RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env); if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { - ubo.use_reflection_cubemap = true; - } else { - ubo.use_reflection_cubemap = false; + ubo.flags |= SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP; } - ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env); - ubo.fog_mode = render_scene_render->environment_get_fog_mode(p_env); + ubo.flags |= render_scene_render->environment_get_fog_enabled(p_env) ? SCENE_DATA_FLAGS_USE_FOG : 0; ubo.fog_density = render_scene_render->environment_get_fog_density(p_env); ubo.fog_height = render_scene_render->environment_get_fog_height(p_env); ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env); @@ -219,10 +216,8 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env); } else { - if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) { - ubo.use_ambient_light = false; - } else { - ubo.use_ambient_light = true; + if (!(p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance))) { + ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT; Color clear_color = p_default_bg_color; clear_color = clear_color.srgb_to_linear(); ubo.ambient_light_color_energy[0] = clear_color.r; @@ -230,9 +225,6 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.ambient_light_color_energy[2] = clear_color.b; ubo.ambient_light_color_energy[3] = 1.0; } - - ubo.use_ambient_cubemap = false; - ubo.use_reflection_cubemap = false; } if (p_camera_attributes.is_valid()) { @@ -255,7 +247,8 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p ubo.IBL_exposure_normalization = 1.0; } - ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active(); + bool roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active(); + ubo.flags |= roughness_limiter_enabled ? SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER : 0; ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount(); ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit(); diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h index 687d8c133a1..7c03713fbd5 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -75,6 +75,7 @@ public: float opaque_prepass_threshold = 0.0; bool material_uv2_mode = false; float emissive_exposure_normalization = 0.0; + bool shadow_pass = false; Size2 shadow_atlas_pixel_size; Size2 directional_shadow_pixel_size; @@ -96,6 +97,18 @@ public: private: RID uniform_buffer; // loaded into this uniform buffer (supplied externally) + enum SceneDataFlags { + SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT = 1 << 0, + SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP = 1 << 1, + SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP = 1 << 2, + SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER = 1 << 3, + SCENE_DATA_FLAGS_USE_FOG = 1 << 4, + SCENE_DATA_FLAGS_USE_UV2_MATERIAL = 1 << 5, + SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS = 1 << 6, + SCENE_DATA_FLAGS_IN_SHADOW_PASS = 1 << 7, // Only used by Forward+ renderer. + SCENE_DATA_FLAGS_MAX + }; + // This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code struct UBO { float projection_matrix[16]; @@ -117,15 +130,6 @@ private: float penumbra_shadow_kernel[128]; float soft_shadow_kernel[128]; - float radiance_inverse_xform[12]; - - float ambient_light_color_energy[4]; - - float ambient_color_sky_mix; - uint32_t use_ambient_light; - uint32_t use_ambient_cubemap; - uint32_t use_reflection_cubemap; - float shadow_atlas_pixel_size[2]; float directional_shadow_pixel_size[2]; @@ -134,36 +138,34 @@ private: float z_far; float z_near; - uint32_t roughness_limiter_enabled; float roughness_limiter_amount; float roughness_limiter_limit; float opaque_prepass_threshold; + uint32_t flags; - // Fog - uint32_t fog_enabled; - uint32_t fog_mode; + float radiance_inverse_xform[12]; + + float ambient_light_color_energy[4]; + + float ambient_color_sky_mix; float fog_density; float fog_height; - float fog_height_density; + float fog_depth_curve; float fog_depth_begin; - float taa_frame_count; // Used to add break up samples over multiple frames. Value is an integer from 0 to taa_phase_count -1. + float fog_depth_end; + float fog_sun_scatter; float fog_light_color[3]; - float fog_depth_end; - - float fog_sun_scatter; float fog_aerial_perspective; + float time; - float reflection_multiplier; - + float taa_frame_count; // Used to add break up samples over multiple frames. Value is an integer from 0 to taa_phase_count -1. float taa_jitter[2]; - uint32_t material_uv2_mode; - float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. + float emissive_exposure_normalization; // Needed to normalize emissive when using physical units. float IBL_exposure_normalization; // Adjusts for baked exposure. - uint32_t pancake_shadows; uint32_t camera_visible_layers; float pass_alpha_multiplier; }; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 28be30e7338..fc90b50966f 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -77,6 +77,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constvt(ShaderLanguage::TYPE_FLOAT, { e_scalar }); shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["CLIP_SPACE_FAR"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["IN_SHADOW_PASS"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; @@ -87,6 +88,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["Z_CLIP_SCALE"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX_ID"] = constt(ShaderLanguage::TYPE_INT);