Переглянути джерело

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
clayjohn 1 рік тому
батько
коміт
9a1def8da1

+ 20 - 1
doc/classes/BaseMaterial3D.xml

@@ -229,6 +229,10 @@
 		<member name="fixed_size" type="bool" setter="set_flag" getter="get_flag" default="false">
 			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.
 		</member>
+		<member name="fov_override" type="float" setter="set_fov_override" getter="get_fov_override" default="75.0">
+			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.
+		</member>
 		<member name="grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled" default="false">
 			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 @@
 		<member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0">
 			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].
 		</member>
+		<member name="use_fov_override" type="bool" setter="set_flag" getter="get_flag" default="false">
+			If [code]true[/code] use [member fov_override] to override the [Camera3D]'s field of view angle.
+		</member>
 		<member name="use_particle_trails" type="bool" setter="set_flag" getter="get_flag" default="false">
 			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.
 		</member>
@@ -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].
 		</member>
+		<member name="use_z_clip_scale" type="bool" setter="set_flag" getter="get_flag" default="false">
+			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.
+		</member>
 		<member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" default="Vector3(0, 0, 0)">
 			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.
 		</member>
@@ -453,6 +463,9 @@
 		<member name="vertex_color_use_as_albedo" type="bool" setter="set_flag" getter="get_flag" default="false">
 			If [code]true[/code], the vertex color is used as albedo color.
 		</member>
+		<member name="z_clip_scale" type="float" setter="set_z_clip_scale" getter="get_z_clip_scale" default="1.0">
+			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.
+		</member>
 	</members>
 	<constants>
 		<constant name="TEXTURE_ALBEDO" value="0" enum="TextureParam">
@@ -727,7 +740,13 @@
 		<constant name="FLAG_DISABLE_SPECULAR_OCCLUSION" value="22" enum="Flags">
 			Disables specular occlusion.
 		</constant>
-		<constant name="FLAG_MAX" value="23" enum="Flags">
+		<constant name="FLAG_USE_Z_CLIP_SCALE" value="23" enum="Flags">
+			Enables using [member z_clip_scale].
+		</constant>
+		<constant name="FLAG_USE_FOV_OVERRIDE" value="24" enum="Flags">
+			Enables using [member fov_override].
+		</constant>
+		<constant name="FLAG_MAX" value="25" enum="Flags">
 			Represents the size of the [enum Flags] enum.
 		</constant>
 		<constant name="DIFFUSE_BURLEY" value="0" enum="DiffuseMode">

+ 22 - 0
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 */

+ 3 - 0
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";

+ 73 - 2
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<uint64_t, Ref<StandardMaterial3D>> 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<Material> 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;
 

+ 12 - 0
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<Texture2D> 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();

+ 2 - 0
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;

+ 6 - 1
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";

+ 2 - 1
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);

+ 6 - 3
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<RD::PipelineImmutableSampler> 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";

+ 19 - 9
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);

+ 24 - 4
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()) {

+ 21 - 22
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;
-
-	mediump vec3 fog_light_color;
 	highp float fog_depth_end;
-
 	mediump float fog_sun_scatter;
+
+	mediump vec3 fog_light_color;
 	mediump float fog_aerial_perspective;
-	highp float time;
-	mediump float reflection_multiplier; // one normally, zero when rendering reflections
 
+	highp float time;
+	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;
 };

+ 17 - 24
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();
 

+ 25 - 23
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;
+
+		float radiance_inverse_xform[12];
 
-		// Fog
-		uint32_t fog_enabled;
-		uint32_t fog_mode;
+		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_light_color[3];
 		float fog_depth_end;
-
 		float fog_sun_scatter;
+
+		float fog_light_color[3];
 		float fog_aerial_perspective;
-		float time;
-		float reflection_multiplier;
 
+		float time;
+		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;
 	};

+ 2 - 0
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);