Browse Source

Merge pull request #50186 from reduz/fix-subsurface-scattering

Fix Subsurface Scattering
Rémi Verschelde 4 years ago
parent
commit
df62d9f4f4

+ 0 - 2
doc/classes/BaseMaterial3D.xml

@@ -347,8 +347,6 @@
 		</member>
 		</member>
 		<member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color(1, 1, 1, 1)">
 		<member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color(1, 1, 1, 1)">
 		</member>
 		</member>
-		<member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve" default="1.0">
-		</member>
 		<member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1">
 		<member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1">
 		</member>
 		</member>
 		<member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
 		<member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">

+ 1 - 18
scene/resources/material.cpp

@@ -345,7 +345,6 @@ void BaseMaterial3D::init_shaders() {
 	shader_names->refraction_texture_channel = "refraction_texture_channel";
 	shader_names->refraction_texture_channel = "refraction_texture_channel";
 
 
 	shader_names->transmittance_color = "transmittance_color";
 	shader_names->transmittance_color = "transmittance_color";
-	shader_names->transmittance_curve = "transmittance_curve";
 	shader_names->transmittance_depth = "transmittance_depth";
 	shader_names->transmittance_depth = "transmittance_depth";
 	shader_names->transmittance_boost = "transmittance_boost";
 	shader_names->transmittance_boost = "transmittance_boost";
 
 
@@ -692,7 +691,6 @@ void BaseMaterial3D::_update_shader() {
 		code += "uniform vec4 transmittance_color : hint_color;\n";
 		code += "uniform vec4 transmittance_color : hint_color;\n";
 		code += "uniform float transmittance_depth;\n";
 		code += "uniform float transmittance_depth;\n";
 		code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
 		code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
-		code += "uniform float transmittance_curve;\n";
 		code += "uniform float transmittance_boost;\n";
 		code += "uniform float transmittance_boost;\n";
 	}
 	}
 
 
@@ -1194,7 +1192,6 @@ void BaseMaterial3D::_update_shader() {
 		code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
 		code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
 
 
 		code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
 		code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
-		code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n";
 		code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
 		code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
 	}
 	}
 
 
@@ -1438,15 +1435,6 @@ float BaseMaterial3D::get_transmittance_depth() const {
 	return transmittance_depth;
 	return transmittance_depth;
 }
 }
 
 
-void BaseMaterial3D::set_transmittance_curve(float p_curve) {
-	transmittance_curve = p_curve;
-	RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
-}
-
-float BaseMaterial3D::get_transmittance_curve() const {
-	return transmittance_curve;
-}
-
 void BaseMaterial3D::set_transmittance_boost(float p_boost) {
 void BaseMaterial3D::set_transmittance_boost(float p_boost) {
 	transmittance_boost = p_boost;
 	transmittance_boost = p_boost;
 	RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
 	RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
@@ -1765,7 +1753,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
 		property.usage = PROPERTY_USAGE_NONE;
 		property.usage = PROPERTY_USAGE_NONE;
 	}
 	}
 
 
-	if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) {
+	if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture")) {
 		property.usage = PROPERTY_USAGE_NONE;
 		property.usage = PROPERTY_USAGE_NONE;
 	}
 	}
 
 
@@ -2269,9 +2257,6 @@ void BaseMaterial3D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth);
 	ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth);
 	ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth);
 	ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth);
 
 
-	ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve);
-	ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve);
-
 	ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost);
 	ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost);
 	ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost);
 	ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost);
 
 
@@ -2506,7 +2491,6 @@ void BaseMaterial3D::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color");
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color");
 	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE);
 	ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE);
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth");
-	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost");
 
 
 	ADD_GROUP("Back Lighting", "backlight_");
 	ADD_GROUP("Back Lighting", "backlight_");
@@ -2723,7 +2707,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
 	set_backlight(Color(0, 0, 0));
 	set_backlight(Color(0, 0, 0));
 	set_transmittance_color(Color(1, 1, 1, 1));
 	set_transmittance_color(Color(1, 1, 1, 1));
 	set_transmittance_depth(0.1);
 	set_transmittance_depth(0.1);
-	set_transmittance_curve(1.0);
 	set_transmittance_boost(0.0);
 	set_transmittance_boost(0.0);
 	set_refraction(0.05);
 	set_refraction(0.05);
 	set_point_size(1);
 	set_point_size(1);

+ 0 - 5
scene/resources/material.h

@@ -389,7 +389,6 @@ private:
 		StringName heightmap_scale;
 		StringName heightmap_scale;
 		StringName subsurface_scattering_strength;
 		StringName subsurface_scattering_strength;
 		StringName transmittance_color;
 		StringName transmittance_color;
-		StringName transmittance_curve;
 		StringName transmittance_depth;
 		StringName transmittance_depth;
 		StringName transmittance_boost;
 		StringName transmittance_boost;
 		StringName backlight;
 		StringName backlight;
@@ -458,7 +457,6 @@ private:
 	float transmittance_amount;
 	float transmittance_amount;
 	Color transmittance_color;
 	Color transmittance_color;
 	float transmittance_depth;
 	float transmittance_depth;
-	float transmittance_curve;
 	float transmittance_boost;
 	float transmittance_boost;
 
 
 	Color backlight;
 	Color backlight;
@@ -602,9 +600,6 @@ public:
 	void set_transmittance_depth(float p_depth);
 	void set_transmittance_depth(float p_depth);
 	float get_transmittance_depth() const;
 	float get_transmittance_depth() const;
 
 
-	void set_transmittance_curve(float p_curve);
-	float get_transmittance_curve() const;
-
 	void set_transmittance_boost(float p_boost);
 	void set_transmittance_boost(float p_boost);
 	float get_transmittance_boost() const;
 	float get_transmittance_boost() const;
 
 

+ 19 - 0
servers/rendering/renderer_rd/effects_rd.cpp

@@ -1377,6 +1377,24 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI
 	RD::get_singleton()->compute_list_end(p_barrier);
 	RD::get_singleton()->compute_list_end(p_barrier);
 }
 }
 
 
+void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+	ResolvePushConstant push_constant;
+	push_constant.screen_size[0] = p_screen_size.x;
+	push_constant.screen_size[1] = p_screen_size.y;
+	push_constant.samples = p_samples;
+
+	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1);
+
+	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
+
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
+
+	RD::get_singleton()->compute_list_end(p_barrier);
+}
+
 void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
 void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
 	Sort::PushConstant push_constant;
 	Sort::PushConstant push_constant;
 	push_constant.total_elements = p_size;
 	push_constant.total_elements = p_size;
@@ -1879,6 +1897,7 @@ EffectsRD::EffectsRD() {
 		Vector<String> resolve_modes;
 		Vector<String> resolve_modes;
 		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
 		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
 		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
 		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
+		resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
 
 
 		resolve.shader.initialize(resolve_modes);
 		resolve.shader.initialize(resolve_modes);
 
 

+ 2 - 0
servers/rendering/renderer_rd/effects_rd.h

@@ -581,6 +581,7 @@ class EffectsRD {
 	enum ResolveMode {
 	enum ResolveMode {
 		RESOLVE_MODE_GI,
 		RESOLVE_MODE_GI,
 		RESOLVE_MODE_GI_VOXEL_GI,
 		RESOLVE_MODE_GI_VOXEL_GI,
+		RESOLVE_MODE_DEPTH,
 		RESOLVE_MODE_MAX
 		RESOLVE_MODE_MAX
 	};
 	};
 
 
@@ -746,6 +747,7 @@ public:
 	void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
 	void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
 
 
 	void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
 	void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+	void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
 
 
 	void sort_buffer(RID p_uniform_set, int p_size);
 	void sort_buffer(RID p_uniform_set, int p_size);
 
 

+ 4 - 4
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -1150,6 +1150,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
 		render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
 		render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
 	}
 	}
 	RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
 	RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
+	static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
 
 
 	//first of all, make a new render pass
 	//first of all, make a new render pass
 	//fill up ubo
 	//fill up ubo
@@ -1390,10 +1391,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
 				if (needs_pre_resolve) {
 				if (needs_pre_resolve) {
 					RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
 					RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
 				}
 				}
-				static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
-				storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]);
+				storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
 			} else if (finish_depth) {
 			} else if (finish_depth) {
-				RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
+				storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
 			}
 			}
 			RD::get_singleton()->draw_command_end_label();
 			RD::get_singleton()->draw_command_end_label();
 		}
 		}
@@ -1497,7 +1497,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
 	}
 	}
 
 
 	if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
 	if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
-		RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
+		storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
 	}
 	}
 
 
 	if (using_separate_specular) {
 	if (using_separate_specular) {

+ 0 - 3
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp

@@ -320,8 +320,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
 					} else {
 					} else {
 						//specular write
 						//specular write
 						blend_state = blend_state_opaque_specular;
 						blend_state = blend_state_opaque_specular;
-						depth_stencil.enable_depth_test = false;
-						depth_stencil.enable_depth_write = false;
 					}
 					}
 				}
 				}
 
 
@@ -631,7 +629,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
 		actions.renames["SSS_STRENGTH"] = "sss_strength";
 		actions.renames["SSS_STRENGTH"] = "sss_strength";
 		actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
 		actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
 		actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
 		actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
-		actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
 		actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
 		actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
 		actions.renames["BACKLIGHT"] = "backlight";
 		actions.renames["BACKLIGHT"] = "backlight";
 		actions.renames["AO"] = "ao";
 		actions.renames["AO"] = "ao";

+ 0 - 1
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

@@ -621,7 +621,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
 		actions.renames["SSS_STRENGTH"] = "sss_strength";
 		actions.renames["SSS_STRENGTH"] = "sss_strength";
 		actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
 		actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
 		actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
 		actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
-		actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
 		actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
 		actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
 		actions.renames["BACKLIGHT"] = "backlight";
 		actions.renames["BACKLIGHT"] = "backlight";
 		actions.renames["AO"] = "ao";
 		actions.renames["AO"] = "ao";

+ 16 - 0
servers/rendering/renderer_rd/shaders/resolve.glsl

@@ -6,6 +6,11 @@
 
 
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 
 
+#ifdef MODE_RESOLVE_DEPTH
+layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
+layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth;
+#endif
+
 #ifdef MODE_RESOLVE_GI
 #ifdef MODE_RESOLVE_GI
 layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
 layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
 layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness;
 layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness;
@@ -34,6 +39,17 @@ void main() {
 		return;
 		return;
 	}
 	}
 
 
+#ifdef MODE_RESOLVE_DEPTH
+
+	float depth_avg = 0.0;
+	for (int i = 0; i < params.sample_count; i++) {
+		depth_avg += texelFetch(source_depth, pos, i).r;
+	}
+	depth_avg /= float(params.sample_count);
+	imageStore(dest_depth, pos, vec4(depth_avg));
+
+#endif
+
 #ifdef MODE_RESOLVE_GI
 #ifdef MODE_RESOLVE_GI
 
 
 	float best_depth = 1e20;
 	float best_depth = 1e20;

+ 210 - 269
servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl

@@ -547,9 +547,8 @@ void main() {
 	vec3 view = -normalize(vertex_interp);
 	vec3 view = -normalize(vertex_interp);
 	vec3 albedo = vec3(1.0);
 	vec3 albedo = vec3(1.0);
 	vec3 backlight = vec3(0.0);
 	vec3 backlight = vec3(0.0);
-	vec4 transmittance_color = vec4(0.0);
+	vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0);
 	float transmittance_depth = 0.0;
 	float transmittance_depth = 0.0;
-	float transmittance_curve = 1.0;
 	float transmittance_boost = 0.0;
 	float transmittance_boost = 0.0;
 	float metallic = 0.0;
 	float metallic = 0.0;
 	float specular = 0.5;
 	float specular = 0.5;
@@ -634,12 +633,8 @@ void main() {
 	}
 	}
 
 
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
-#ifdef SSS_MODE_SKIN
-	transmittance_color.a = sss_strength;
-#else
 	transmittance_color.a *= sss_strength;
 	transmittance_color.a *= sss_strength;
 #endif
 #endif
-#endif
 
 
 #ifndef USE_SHADOW_TO_OPACITY
 #ifndef USE_SHADOW_TO_OPACITY
 
 
@@ -1423,57 +1418,18 @@ void main() {
 					BIAS_FUNC(v, 0)
 					BIAS_FUNC(v, 0)
 
 
 					pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
 					pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
-					{
-						vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
-						vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
-						trans_coord /= trans_coord.w;
-
-						float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-						shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
-						float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
-
-						transmittance_z = z - shadow_z;
-					}
-#endif
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
 					vec4 v = vec4(vertex, 1.0);
 					vec4 v = vec4(vertex, 1.0);
 
 
 					BIAS_FUNC(v, 1)
 					BIAS_FUNC(v, 1)
 
 
 					pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
 					pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
-					{
-						vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
-						vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
-						trans_coord /= trans_coord.w;
-
-						float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-						shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
-						float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
-
-						transmittance_z = z - shadow_z;
-					}
-#endif
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
 					vec4 v = vec4(vertex, 1.0);
 					vec4 v = vec4(vertex, 1.0);
 
 
 					BIAS_FUNC(v, 2)
 					BIAS_FUNC(v, 2)
 
 
 					pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
 					pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
-					{
-						vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
-						vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
-						trans_coord /= trans_coord.w;
-
-						float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-						shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
-						float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
-
-						transmittance_z = z - shadow_z;
-					}
-#endif
 
 
 				} else {
 				} else {
 					vec4 v = vec4(vertex, 1.0);
 					vec4 v = vec4(vertex, 1.0);
@@ -1481,19 +1437,6 @@ void main() {
 					BIAS_FUNC(v, 3)
 					BIAS_FUNC(v, 3)
 
 
 					pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
 					pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
-					{
-						vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
-						vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
-						trans_coord /= trans_coord.w;
-
-						float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-						shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
-						float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
-
-						transmittance_z = z - shadow_z;
-					}
-#endif
 				}
 				}
 
 
 				pssm_coord /= pssm_coord.w;
 				pssm_coord /= pssm_coord.w;
@@ -1562,8 +1505,8 @@ void main() {
 					trans_coord /= trans_coord.w;
 					trans_coord /= trans_coord.w;
 
 
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-					shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
-					float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
+					shadow_z *= directional_lights.data[i].shadow_z_range.x;
+					float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x;
 
 
 					transmittance_z = z - shadow_z;
 					transmittance_z = z - shadow_z;
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
@@ -1572,8 +1515,8 @@ void main() {
 					trans_coord /= trans_coord.w;
 					trans_coord /= trans_coord.w;
 
 
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-					shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
-					float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
+					shadow_z *= directional_lights.data[i].shadow_z_range.y;
+					float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y;
 
 
 					transmittance_z = z - shadow_z;
 					transmittance_z = z - shadow_z;
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
 				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
@@ -1582,8 +1525,8 @@ void main() {
 					trans_coord /= trans_coord.w;
 					trans_coord /= trans_coord.w;
 
 
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-					shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
-					float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
+					shadow_z *= directional_lights.data[i].shadow_z_range.z;
+					float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
 
 
 					transmittance_z = z - shadow_z;
 					transmittance_z = z - shadow_z;
 
 
@@ -1593,221 +1536,219 @@ void main() {
 					trans_coord /= trans_coord.w;
 					trans_coord /= trans_coord.w;
 
 
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
 					float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
-					shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
-					float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
+					shadow_z *= directional_lights.data[i].shadow_z_range.w;
+					float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w;
 
 
 					transmittance_z = z - shadow_z;
 					transmittance_z = z - shadow_z;
 				}
 				}
+			}
 #endif
 #endif
 
 
-				float shadow = 1.0;
+			float shadow = 1.0;
 
 
-				if (i < 4) {
-					shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
-				} else {
-					shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
-				}
+			if (i < 4) {
+				shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
+			} else {
+				shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
+			}
 
 
-				blur_shadow(shadow);
+			blur_shadow(shadow);
 
 
-				light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
+			light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
-						backlight,
+					backlight,
 #endif
 #endif
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
-						transmittance_color,
-						transmittance_depth,
-						transmittance_curve,
-						transmittance_boost,
-						transmittance_z,
+					transmittance_color,
+					transmittance_depth,
+					transmittance_boost,
+					transmittance_z,
 #endif
 #endif
 #ifdef LIGHT_RIM_USED
 #ifdef LIGHT_RIM_USED
-						rim, rim_tint, albedo,
+					rim, rim_tint, albedo,
 #endif
 #endif
 #ifdef LIGHT_CLEARCOAT_USED
 #ifdef LIGHT_CLEARCOAT_USED
-						clearcoat, clearcoat_gloss,
+					clearcoat, clearcoat_gloss,
 #endif
 #endif
 #ifdef LIGHT_ANISOTROPY_USED
 #ifdef LIGHT_ANISOTROPY_USED
-						binormal, tangent, anisotropy,
+					binormal, tangent, anisotropy,
 #endif
 #endif
 #ifdef USE_SOFT_SHADOW
 #ifdef USE_SOFT_SHADOW
-						directional_lights.data[i].size,
+					directional_lights.data[i].size,
 #endif
 #endif
 #ifdef USE_SHADOW_TO_OPACITY
 #ifdef USE_SHADOW_TO_OPACITY
-						alpha,
+					alpha,
 #endif
 #endif
-						diffuse_light,
-						specular_light);
-			}
+					diffuse_light,
+					specular_light);
 		}
 		}
+	}
 
 
-		{ //omni lights
+	{ //omni lights
 
 
-			uint cluster_omni_offset = cluster_offset;
+		uint cluster_omni_offset = cluster_offset;
 
 
-			uint item_min;
-			uint item_max;
-			uint item_from;
-			uint item_to;
+		uint item_min;
+		uint item_max;
+		uint item_from;
+		uint item_to;
 
 
-			cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-			item_from = subgroupBroadcastFirst(subgroupMin(item_from));
-			item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+		item_to = subgroupBroadcastFirst(subgroupMax(item_to));
 #endif
 #endif
 
 
-			for (uint i = item_from; i < item_to; i++) {
-				uint mask = cluster_buffer.data[cluster_omni_offset + i];
-				mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+		for (uint i = item_from; i < item_to; i++) {
+			uint mask = cluster_buffer.data[cluster_omni_offset + i];
+			mask &= cluster_get_range_clip_mask(i, item_min, item_max);
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-				uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+			uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
 #else
 #else
 			uint merged_mask = mask;
 			uint merged_mask = mask;
 #endif
 #endif
 
 
-				while (merged_mask != 0) {
-					uint bit = findMSB(merged_mask);
-					merged_mask &= ~(1 << bit);
+			while (merged_mask != 0) {
+				uint bit = findMSB(merged_mask);
+				merged_mask &= ~(1 << bit);
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-					if (((1 << bit) & mask) == 0) { //do not process if not originally here
-						continue;
-					}
+				if (((1 << bit) & mask) == 0) { //do not process if not originally here
+					continue;
+				}
 #endif
 #endif
-					uint light_index = 32 * i + bit;
+				uint light_index = 32 * i + bit;
 
 
-					if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
-						continue; //not masked
-					}
+				if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+					continue; //not masked
+				}
 
 
-					if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
-						continue; // Statically baked light and object uses lightmap, skip
-					}
+				if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+					continue; // Statically baked light and object uses lightmap, skip
+				}
 
 
-					float shadow = light_process_omni_shadow(light_index, vertex, view);
+				float shadow = light_process_omni_shadow(light_index, vertex, view);
 
 
-					shadow = blur_shadow(shadow);
+				shadow = blur_shadow(shadow);
 
 
-					light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
+				light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
-							backlight,
+						backlight,
 #endif
 #endif
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
-							transmittance_color,
-							transmittance_depth,
-							transmittance_curve,
-							transmittance_boost,
+						transmittance_color,
+						transmittance_depth,
+						transmittance_boost,
 #endif
 #endif
 #ifdef LIGHT_RIM_USED
 #ifdef LIGHT_RIM_USED
-							rim,
-							rim_tint,
-							albedo,
+						rim,
+						rim_tint,
+						albedo,
 #endif
 #endif
 #ifdef LIGHT_CLEARCOAT_USED
 #ifdef LIGHT_CLEARCOAT_USED
-							clearcoat, clearcoat_gloss,
+						clearcoat, clearcoat_gloss,
 #endif
 #endif
 #ifdef LIGHT_ANISOTROPY_USED
 #ifdef LIGHT_ANISOTROPY_USED
-							tangent, binormal, anisotropy,
+						tangent, binormal, anisotropy,
 #endif
 #endif
 #ifdef USE_SHADOW_TO_OPACITY
 #ifdef USE_SHADOW_TO_OPACITY
-							alpha,
+						alpha,
 #endif
 #endif
-							diffuse_light, specular_light);
-				}
+						diffuse_light, specular_light);
 			}
 			}
 		}
 		}
+	}
 
 
-		{ //spot lights
+	{ //spot lights
 
 
-			uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
+		uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
 
 
-			uint item_min;
-			uint item_max;
-			uint item_from;
-			uint item_to;
+		uint item_min;
+		uint item_max;
+		uint item_from;
+		uint item_to;
 
 
-			cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-			item_from = subgroupBroadcastFirst(subgroupMin(item_from));
-			item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+		item_to = subgroupBroadcastFirst(subgroupMax(item_to));
 #endif
 #endif
 
 
-			for (uint i = item_from; i < item_to; i++) {
-				uint mask = cluster_buffer.data[cluster_spot_offset + i];
-				mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+		for (uint i = item_from; i < item_to; i++) {
+			uint mask = cluster_buffer.data[cluster_spot_offset + i];
+			mask &= cluster_get_range_clip_mask(i, item_min, item_max);
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-				uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+			uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
 #else
 #else
 			uint merged_mask = mask;
 			uint merged_mask = mask;
 #endif
 #endif
 
 
-				while (merged_mask != 0) {
-					uint bit = findMSB(merged_mask);
-					merged_mask &= ~(1 << bit);
+			while (merged_mask != 0) {
+				uint bit = findMSB(merged_mask);
+				merged_mask &= ~(1 << bit);
 #ifdef USE_SUBGROUPS
 #ifdef USE_SUBGROUPS
-					if (((1 << bit) & mask) == 0) { //do not process if not originally here
-						continue;
-					}
+				if (((1 << bit) & mask) == 0) { //do not process if not originally here
+					continue;
+				}
 #endif
 #endif
 
 
-					uint light_index = 32 * i + bit;
+				uint light_index = 32 * i + bit;
 
 
-					if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
-						continue; //not masked
-					}
+				if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+					continue; //not masked
+				}
 
 
-					if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
-						continue; // Statically baked light and object uses lightmap, skip
-					}
+				if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+					continue; // Statically baked light and object uses lightmap, skip
+				}
 
 
-					float shadow = light_process_spot_shadow(light_index, vertex, view);
+				float shadow = light_process_spot_shadow(light_index, vertex, view);
 
 
-					shadow = blur_shadow(shadow);
+				shadow = blur_shadow(shadow);
 
 
-					light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
+				light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
-							backlight,
+						backlight,
 #endif
 #endif
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
-							transmittance_color,
-							transmittance_depth,
-							transmittance_curve,
-							transmittance_boost,
+						transmittance_color,
+						transmittance_depth,
+						transmittance_boost,
 #endif
 #endif
 #ifdef LIGHT_RIM_USED
 #ifdef LIGHT_RIM_USED
-							rim,
-							rim_tint,
-							albedo,
+						rim,
+						rim_tint,
+						albedo,
 #endif
 #endif
 #ifdef LIGHT_CLEARCOAT_USED
 #ifdef LIGHT_CLEARCOAT_USED
-							clearcoat, clearcoat_gloss,
+						clearcoat, clearcoat_gloss,
 #endif
 #endif
 #ifdef LIGHT_ANISOTROPY_USED
 #ifdef LIGHT_ANISOTROPY_USED
-							tangent, binormal, anisotropy,
+						tangent, binormal, anisotropy,
 #endif
 #endif
 #ifdef USE_SHADOW_TO_OPACITY
 #ifdef USE_SHADOW_TO_OPACITY
-							alpha,
+						alpha,
 #endif
 #endif
-							diffuse_light, specular_light);
-				}
+						diffuse_light, specular_light);
 			}
 			}
 		}
 		}
+	}
 
 
 #ifdef USE_SHADOW_TO_OPACITY
 #ifdef USE_SHADOW_TO_OPACITY
-		alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
+	alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
 
 
 #if defined(ALPHA_SCISSOR_USED)
 #if defined(ALPHA_SCISSOR_USED)
-		if (alpha < alpha_scissor) {
-			discard;
-		}
+	if (alpha < alpha_scissor) {
+		discard;
+	}
 #endif // ALPHA_SCISSOR_USED
 #endif // ALPHA_SCISSOR_USED
 
 
 #ifdef USE_OPAQUE_PREPASS
 #ifdef USE_OPAQUE_PREPASS
 
 
-		if (alpha < opaque_prepass_threshold) {
-			discard;
-		}
+	if (alpha < opaque_prepass_threshold) {
+		discard;
+	}
 
 
 #endif // USE_OPAQUE_PREPASS
 #endif // USE_OPAQUE_PREPASS
 
 
@@ -1819,126 +1760,126 @@ void main() {
 
 
 #ifdef MODE_RENDER_SDF
 #ifdef MODE_RENDER_SDF
 
 
-		{
-			vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
-			ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
-
-			uint albedo16 = 0x1; //solid flag
-			albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
-			albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
-			albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
-
-			imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
-
-			uint facing_bits = 0;
-			const vec3 aniso_dir[6] = vec3[](
-					vec3(1, 0, 0),
-					vec3(0, 1, 0),
-					vec3(0, 0, 1),
-					vec3(-1, 0, 0),
-					vec3(0, -1, 0),
-					vec3(0, 0, -1));
-
-			vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
-
-			float closest_dist = -1e20;
-
-			for (uint i = 0; i < 6; i++) {
-				float d = dot(cam_normal, aniso_dir[i]);
-				if (d > closest_dist) {
-					closest_dist = d;
-					facing_bits = (1 << i);
-				}
+	{
+		vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
+		ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
+
+		uint albedo16 = 0x1; //solid flag
+		albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
+		albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
+		albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
+
+		imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
+
+		uint facing_bits = 0;
+		const vec3 aniso_dir[6] = vec3[](
+				vec3(1, 0, 0),
+				vec3(0, 1, 0),
+				vec3(0, 0, 1),
+				vec3(-1, 0, 0),
+				vec3(0, -1, 0),
+				vec3(0, 0, -1));
+
+		vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
+
+		float closest_dist = -1e20;
+
+		for (uint i = 0; i < 6; i++) {
+			float d = dot(cam_normal, aniso_dir[i]);
+			if (d > closest_dist) {
+				closest_dist = d;
+				facing_bits = (1 << i);
 			}
 			}
+		}
 
 
-			imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
+		imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
 
 
-			if (length(emission) > 0.001) {
-				float lumas[6];
-				vec3 light_total = vec3(0);
+		if (length(emission) > 0.001) {
+			float lumas[6];
+			vec3 light_total = vec3(0);
 
 
-				for (int i = 0; i < 6; i++) {
-					float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
-					vec3 light = emission * strength;
-					light_total += light;
-					lumas[i] = max(light.r, max(light.g, light.b));
-				}
+			for (int i = 0; i < 6; i++) {
+				float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
+				vec3 light = emission * strength;
+				light_total += light;
+				lumas[i] = max(light.r, max(light.g, light.b));
+			}
 
 
-				float luma_total = max(light_total.r, max(light_total.g, light_total.b));
+			float luma_total = max(light_total.r, max(light_total.g, light_total.b));
 
 
-				uint light_aniso = 0;
+			uint light_aniso = 0;
 
 
-				for (int i = 0; i < 6; i++) {
-					light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
-				}
+			for (int i = 0; i < 6; i++) {
+				light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
+			}
 
 
-				//compress to RGBE9995 to save space
+			//compress to RGBE9995 to save space
 
 
-				const float pow2to9 = 512.0f;
-				const float B = 15.0f;
-				const float N = 9.0f;
-				const float LN2 = 0.6931471805599453094172321215;
+			const float pow2to9 = 512.0f;
+			const float B = 15.0f;
+			const float N = 9.0f;
+			const float LN2 = 0.6931471805599453094172321215;
 
 
-				float cRed = clamp(light_total.r, 0.0, 65408.0);
-				float cGreen = clamp(light_total.g, 0.0, 65408.0);
-				float cBlue = clamp(light_total.b, 0.0, 65408.0);
+			float cRed = clamp(light_total.r, 0.0, 65408.0);
+			float cGreen = clamp(light_total.g, 0.0, 65408.0);
+			float cBlue = clamp(light_total.b, 0.0, 65408.0);
 
 
-				float cMax = max(cRed, max(cGreen, cBlue));
+			float cMax = max(cRed, max(cGreen, cBlue));
 
 
-				float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
+			float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
 
 
-				float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
+			float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
 
 
-				float exps = expp + 1.0f;
+			float exps = expp + 1.0f;
 
 
-				if (0.0 <= sMax && sMax < pow2to9) {
-					exps = expp;
-				}
+			if (0.0 <= sMax && sMax < pow2to9) {
+				exps = expp;
+			}
 
 
-				float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
-				float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
-				float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
-				//store as 8985 to have 2 extra neighbour bits
-				uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
+			float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+			float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+			float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+			//store as 8985 to have 2 extra neighbour bits
+			uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
 
 
-				imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
-				imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
-			}
+			imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
+			imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
 		}
 		}
+	}
 
 
 #endif
 #endif
 
 
 #ifdef MODE_RENDER_MATERIAL
 #ifdef MODE_RENDER_MATERIAL
 
 
-		albedo_output_buffer.rgb = albedo;
-		albedo_output_buffer.a = alpha;
+	albedo_output_buffer.rgb = albedo;
+	albedo_output_buffer.a = alpha;
 
 
-		normal_output_buffer.rgb = normal * 0.5 + 0.5;
-		normal_output_buffer.a = 0.0;
-		depth_output_buffer.r = -vertex.z;
+	normal_output_buffer.rgb = normal * 0.5 + 0.5;
+	normal_output_buffer.a = 0.0;
+	depth_output_buffer.r = -vertex.z;
 
 
-		orm_output_buffer.r = ao;
-		orm_output_buffer.g = roughness;
-		orm_output_buffer.b = metallic;
-		orm_output_buffer.a = sss_strength;
+	orm_output_buffer.r = ao;
+	orm_output_buffer.g = roughness;
+	orm_output_buffer.b = metallic;
+	orm_output_buffer.a = sss_strength;
 
 
-		emission_output_buffer.rgb = emission;
-		emission_output_buffer.a = 0.0;
+	emission_output_buffer.rgb = emission;
+	emission_output_buffer.a = 0.0;
 #endif
 #endif
 
 
 #ifdef MODE_RENDER_NORMAL_ROUGHNESS
 #ifdef MODE_RENDER_NORMAL_ROUGHNESS
-		normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
+	normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
 
 
 #ifdef MODE_RENDER_VOXEL_GI
 #ifdef MODE_RENDER_VOXEL_GI
-		if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
-			uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
-			uint index2 = instances.data[instance_index].gi_offset >> 16;
-			voxel_gi_buffer.x = index1 & 0xFF;
-			voxel_gi_buffer.y = index2 & 0xFF;
-		} else {
-			voxel_gi_buffer.x = 0xFF;
-			voxel_gi_buffer.y = 0xFF;
-		}
+	if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
+		uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
+		uint index2 = instances.data[instance_index].gi_offset >> 16;
+		voxel_gi_buffer.x = index1 & 0xFF;
+		voxel_gi_buffer.y = index2 & 0xFF;
+	} else {
+		voxel_gi_buffer.x = 0xFF;
+		voxel_gi_buffer.y = 0xFF;
+	}
 #endif
 #endif
 
 
 #endif //MODE_RENDER_NORMAL_ROUGHNESS
 #endif //MODE_RENDER_NORMAL_ROUGHNESS
@@ -1996,4 +1937,4 @@ void main() {
 #endif //MODE_MULTIPLE_RENDER_TARGETS
 #endif //MODE_MULTIPLE_RENDER_TARGETS
 
 
 #endif //MODE_RENDER_DEPTH
 #endif //MODE_RENDER_DEPTH
-	}
+}

+ 19 - 23
servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl

@@ -80,7 +80,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 		vec4 transmittance_color,
 		vec4 transmittance_color,
 		float transmittance_depth,
 		float transmittance_depth,
-		float transmittance_curve,
 		float transmittance_boost,
 		float transmittance_boost,
 		float transmittance_z,
 		float transmittance_z,
 #endif
 #endif
@@ -189,9 +188,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
 
 
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 
 
-#ifdef SSS_MODE_SKIN
-
 		{
 		{
+#ifdef SSS_MODE_SKIN
 			float scale = 8.25 / transmittance_depth;
 			float scale = 8.25 / transmittance_depth;
 			float d = scale * abs(transmittance_z);
 			float d = scale * abs(transmittance_z);
 			float dd = -d * d;
 			float dd = -d * d;
@@ -203,19 +201,15 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
 						   vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
 						   vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
 
 
 			diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
 			diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
-		}
 #else
 #else
 
 
-		if (transmittance_depth > 0.0) {
-			float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0);
-
-			fade = pow(max(0.0, 1.0 - fade), transmittance_curve);
-			fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0);
-
-			diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade;
+			float scale = 8.25 / transmittance_depth;
+			float d = scale * abs(transmittance_z);
+			float dd = -d * d;
+			diffuse_light += exp(dd) * transmittance_color.rgb * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
+#endif
 		}
 		}
-
-#endif //SSS_MODE_SKIN
+#else
 
 
 #endif //LIGHT_TRANSMITTANCE_USED
 #endif //LIGHT_TRANSMITTANCE_USED
 	}
 	}
@@ -577,7 +571,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 		vec4 transmittance_color,
 		vec4 transmittance_color,
 		float transmittance_depth,
 		float transmittance_depth,
-		float transmittance_curve,
 		float transmittance_boost,
 		float transmittance_boost,
 #endif
 #endif
 #ifdef LIGHT_RIM_USED
 #ifdef LIGHT_RIM_USED
@@ -617,20 +610,22 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 		//redo shadowmapping, but shrink the model a bit to avoid arctifacts
 		//redo shadowmapping, but shrink the model a bit to avoid arctifacts
 		vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
 		vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
 
 
-		shadow_len = length(splane.xyz);
-		splane = normalize(splane.xyz);
+		float shadow_len = length(splane.xyz);
+		splane.xyz = normalize(splane.xyz);
 
 
 		if (splane.z >= 0.0) {
 		if (splane.z >= 0.0) {
 			splane.z += 1.0;
 			splane.z += 1.0;
-
+			clamp_rect.y += clamp_rect.w;
 		} else {
 		} else {
 			splane.z = 1.0 - splane.z;
 			splane.z = 1.0 - splane.z;
 		}
 		}
 
 
 		splane.xy /= splane.z;
 		splane.xy /= splane.z;
+
 		splane.xy = splane.xy * 0.5 + 0.5;
 		splane.xy = splane.xy * 0.5 + 0.5;
 		splane.z = shadow_len * omni_lights.data[idx].inv_radius;
 		splane.z = shadow_len * omni_lights.data[idx].inv_radius;
 		splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
 		splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+		//		splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data.shadow_atlas_pixel_size );
 		splane.w = 1.0; //needed? i think it should be 1 already
 		splane.w = 1.0; //needed? i think it should be 1 already
 
 
 		float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
 		float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
@@ -704,7 +699,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 			transmittance_color,
 			transmittance_color,
 			transmittance_depth,
 			transmittance_depth,
-			transmittance_curve,
 			transmittance_boost,
 			transmittance_boost,
 			transmittance_z,
 			transmittance_z,
 #endif
 #endif
@@ -829,7 +823,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 		vec4 transmittance_color,
 		vec4 transmittance_color,
 		float transmittance_depth,
 		float transmittance_depth,
-		float transmittance_curve,
 		float transmittance_boost,
 		float transmittance_boost,
 #endif
 #endif
 #ifdef LIGHT_RIM_USED
 #ifdef LIGHT_RIM_USED
@@ -876,13 +869,17 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 	float transmittance_z = transmittance_depth;
 	float transmittance_z = transmittance_depth;
 	transmittance_color.a *= light_attenuation;
 	transmittance_color.a *= light_attenuation;
 	{
 	{
-		splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
+		vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
 		splane /= splane.w;
 		splane /= splane.w;
 		splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
 		splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
 
 
 		float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
 		float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
-		//reconstruct depth
-		shadow_z /= spot_lights.data[idx].inv_radius;
+
+		shadow_z = shadow_z * 2.0 - 1.0;
+		float z_far = 1.0 / spot_lights.data[idx].inv_radius;
+		float z_near = 0.01;
+		shadow_z = 2.0 * z_near * z_far / (z_far + z_near - shadow_z * (z_far - z_near));
+
 		//distance to light plane
 		//distance to light plane
 		float z = dot(spot_dir, -light_rel_vec);
 		float z = dot(spot_dir, -light_rel_vec);
 		transmittance_z = z - shadow_z;
 		transmittance_z = z - shadow_z;
@@ -898,7 +895,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 			transmittance_color,
 			transmittance_color,
 			transmittance_depth,
 			transmittance_depth,
-			transmittance_curve,
 			transmittance_boost,
 			transmittance_boost,
 			transmittance_z,
 			transmittance_z,
 #endif
 #endif

+ 0 - 4
servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl

@@ -543,7 +543,6 @@ void main() {
 	vec3 backlight = vec3(0.0);
 	vec3 backlight = vec3(0.0);
 	vec4 transmittance_color = vec4(0.0);
 	vec4 transmittance_color = vec4(0.0);
 	float transmittance_depth = 0.0;
 	float transmittance_depth = 0.0;
-	float transmittance_curve = 1.0;
 	float transmittance_boost = 0.0;
 	float transmittance_boost = 0.0;
 	float metallic = 0.0;
 	float metallic = 0.0;
 	float specular = 0.5;
 	float specular = 0.5;
@@ -1293,7 +1292,6 @@ void main() {
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 					transmittance_color,
 					transmittance_color,
 					transmittance_depth,
 					transmittance_depth,
-					transmittance_curve,
 					transmittance_boost,
 					transmittance_boost,
 					transmittance_z,
 					transmittance_z,
 #endif
 #endif
@@ -1344,7 +1342,6 @@ void main() {
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 					transmittance_color,
 					transmittance_color,
 					transmittance_depth,
 					transmittance_depth,
-					transmittance_curve,
 					transmittance_boost,
 					transmittance_boost,
 #endif
 #endif
 */
 */
@@ -1393,7 +1390,6 @@ void main() {
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 					transmittance_color,
 					transmittance_color,
 					transmittance_depth,
 					transmittance_depth,
-					transmittance_curve,
 					transmittance_boost,
 					transmittance_boost,
 #endif
 #endif
 */
 */

+ 0 - 1
servers/rendering/shader_types.cpp

@@ -122,7 +122,6 @@ ShaderTypes::ShaderTypes() {
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
-	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;
 	shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;