Browse Source

Done with lights and shadows (wonder if i'm missing something..)

Juan Linietsky 8 years ago
parent
commit
a7078a4be9

+ 1 - 1
drivers/gles3/rasterizer_gles3.cpp

@@ -125,6 +125,7 @@ void RasterizerGLES3::begin_frame(){
 
 	storage->update_dirty_shaders();
 	storage->update_dirty_materials();
+	scene->iteration();
 
 }
 
@@ -258,7 +259,6 @@ void RasterizerGLES3::register_config() {
 	GLOBAL_DEF("rendering/gles3/use_nearest_mipmap_filter",false);
 	GLOBAL_DEF("rendering/gles3/anisotropic_filter_level",4.0);
 
-
 }
 
 RasterizerGLES3::RasterizerGLES3()

File diff suppressed because it is too large
+ 364 - 355
drivers/gles3/rasterizer_scene_gles3.cpp


+ 59 - 32
drivers/gles3/rasterizer_scene_gles3.h

@@ -8,6 +8,15 @@
 class RasterizerSceneGLES3 : public RasterizerScene {
 public:
 
+	enum ShadowFilterMode {
+		SHADOW_FILTER_NEAREST,
+		SHADOW_FILTER_PCF5,
+		SHADOW_FILTER_PCF13,
+	};
+
+
+	ShadowFilterMode shadow_filter_mode;
+
 	uint64_t shadow_atlas_realloc_tolerance_msec;
 
 
@@ -27,6 +36,7 @@ public:
 	struct State {
 
 
+
 		bool texscreen_copied;
 		int current_blend_mode;
 		float current_line_width;
@@ -73,6 +83,22 @@ public:
 		GLuint skybox_verts;
 		GLuint skybox_array;
 
+		GLuint directional_ubo;
+
+		GLuint spot_array_ubo;
+		GLuint omni_array_ubo;
+
+		uint32_t ubo_light_size;
+		uint8_t *spot_array_tmp;
+		uint8_t *omni_array_tmp;
+
+		int max_ubo_lights;
+		int max_forward_lights_per_object;
+
+		int spot_light_count;
+		int omni_light_count;
+		int directional_light_count;
+
 		bool cull_front;
 
 	} state;
@@ -204,6 +230,22 @@ public:
 
 	/* LIGHT INSTANCE */
 
+	struct LightDataUBO {
+
+		float light_pos_inv_radius[4];
+		float light_direction_attenuation[4];
+		float light_color_energy[4];
+		float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
+		float light_clamp[4];
+		float light_shadow_color[4];
+		float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
+		float shadow_matrix2[16];
+		float shadow_matrix3[16];
+		float shadow_matrix4[16];
+		float shadow_split_offsets[4];
+
+	};
+
 	struct LightInstance : public RID_Data {
 
 		struct ShadowTransform {
@@ -214,20 +256,6 @@ public:
 			float split;
 		};
 
-		struct LightDataUBO {
-
-			float light_pos_inv_radius[4];
-			float light_direction_attenuation[4];
-			float light_color_energy[4];
-			float light_params[4]; //cone attenuation, specular, shadow darkening,
-			float light_clamp[4]; //cone attenuation, specular, shadow darkening,
-			float shadow_split_offsets[4];
-			float shadow_matrix1[16];
-			float shadow_matrix2[16];
-			float shadow_matrix3[16];
-			float shadow_matrix4[16];
-
-		} light_ubo_data;
 
 
 		ShadowTransform shadow_transform[4];
@@ -241,8 +269,6 @@ public:
 		Vector3 spot_vector;
 		float linear_att;
 
-		GLuint light_ubo;
-
 		uint64_t shadow_pass;
 		uint64_t last_scene_pass;
 		uint64_t last_scene_shadow_pass;
@@ -280,14 +306,16 @@ public:
 			SORT_FLAG_INSTANCING=2,
 			MAX_DIRECTIONAL_LIGHTS=16,
 			MAX_LIGHTS=4096,
-			SORT_KEY_DEPTH_LAYER_SHIFT=58,
-			SORT_KEY_LIGHT_TYPE_SHIFT=54, //type is most important
-			SORT_KEY_LIGHT_INDEX_SHIFT=38, //type is most important
-			SORT_KEY_LIGHT_INDEX_UNSHADED=uint64_t(0xF) << SORT_KEY_LIGHT_TYPE_SHIFT, //type is most important
-			SORT_KEY_LIGHT_MASK=(uint64_t(0xFFFFF) << SORT_KEY_LIGHT_INDEX_SHIFT), //type is most important
-			SORT_KEY_MATERIAL_INDEX_SHIFT=22,
-			SORT_KEY_GEOMETRY_INDEX_SHIFT=6,
-			SORT_KEY_GEOMETRY_TYPE_SHIFT=2,
+
+
+			SORT_KEY_DEPTH_LAYER_SHIFT=60,
+			SORT_KEY_UNSHADED_FLAG=uint64_t(1)<<59,
+			SORT_KEY_NO_DIRECTIONAL_FLAG=uint64_t(1)<<58,
+			SORT_KEY_SHADING_SHIFT=58,
+			SORT_KEY_SHADING_MASK=3,
+			SORT_KEY_MATERIAL_INDEX_SHIFT=40,
+			SORT_KEY_GEOMETRY_INDEX_SHIFT=20,
+			SORT_KEY_GEOMETRY_TYPE_SHIFT=15,
 			SORT_KEY_SKELETON_FLAG=2,
 			SORT_KEY_MIRROR_FLAG=1
 
@@ -302,8 +330,6 @@ public:
 			RasterizerStorageGLES3::Material *material;
 			RasterizerStorageGLES3::GeometryOwner *owner;
 			uint64_t sort_key;
-			bool *additive_ptr;
-			bool additive;
 
 		};
 
@@ -314,6 +340,7 @@ public:
 		int element_count;
 		int alpha_element_count;
 
+
 		void clear() {
 
 			element_count=0;
@@ -399,12 +426,10 @@ public:
 	};
 
 
+	LightInstance *directional_light;
+	LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
 
-	LightInstance *directional_light_instances[RenderList::MAX_DIRECTIONAL_LIGHTS];
-	int directional_light_instance_count;
 
-	LightInstance *light_instances[RenderList::MAX_LIGHTS];
-	int light_instance_count;
 
 	RenderList render_list;
 
@@ -414,9 +439,9 @@ public:
 	_FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection);
 	_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
 	_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
-	_FORCE_INLINE_ void _setup_light(LightInstance *p_light);
+	_FORCE_INLINE_ void _setup_light(RenderList::Element *e);
 
-	void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, RasterizerStorageGLES3::Texture *p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow);
+	void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, RasterizerStorageGLES3::Texture *p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add);
 
 
 	_FORCE_INLINE_ void _add_geometry(  RasterizerStorageGLES3::Geometry* p_geometry,  InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner,int p_material,bool p_shadow);
@@ -424,6 +449,7 @@ public:
 	void _draw_skybox(RID p_skybox, const CameraMatrix& p_projection, const Transform& p_transform, bool p_vflip, float p_scale);
 
 	void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform& p_cam_transform);
+	void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transform);
 	void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix& p_camera_projection, RID p_shadow_atlas);
 	void _copy_screen();
 	void _copy_to_front_buffer(Environment *env);
@@ -439,6 +465,7 @@ public:
 
 	virtual void set_scene_pass(uint64_t p_pass);
 
+	void iteration();
 	void initialize();
 	void finalize();
 	RasterizerSceneGLES3();

+ 28 - 13
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -3169,7 +3169,6 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
 	light->param[VS::LIGHT_PARAM_RANGE]=1.0;
 	light->param[VS::LIGHT_PARAM_SPOT_ANGLE]=45;
 	light->param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE]=0;
-	light->param[VS::LIGHT_PARAM_SHADOW_DARKNESS]=0;
 	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET]=0.1;
 	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET]=0.3;
 	light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET]=0.6;
@@ -3184,6 +3183,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
 	light->directional_shadow_mode=VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
 	light->omni_shadow_mode=VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
 	light->omni_shadow_detail=VS::LIGHT_OMNI_SHADOW_DETAIL_VERTICAL;
+	light->directional_blend_splits=false;
 
 	light->version=0;
 
@@ -3207,7 +3207,6 @@ void RasterizerStorageGLES3::light_set_param(RID p_light,VS::LightParam p_param,
 		case VS::LIGHT_PARAM_RANGE:
 		case VS::LIGHT_PARAM_SPOT_ANGLE:
 		case VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
-		case VS::LIGHT_PARAM_SHADOW_DARKNESS:
 		case VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
 		case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
 		case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
@@ -3230,20 +3229,22 @@ void RasterizerStorageGLES3::light_set_shadow(RID p_light,bool p_enabled){
 
 	light->version++;
 	light->instance_change_notify();
-
-
 }
-void RasterizerStorageGLES3::light_set_projector(RID p_light,RID p_texture){
+
+void RasterizerStorageGLES3::light_set_shadow_color(RID p_light,const Color& p_color) {
 
 	Light * light = light_owner.getornull(p_light);
 	ERR_FAIL_COND(!light);
-
+	light->shadow_color=p_color;
 
 }
-void RasterizerStorageGLES3::light_set_attenuation_texure(RID p_light,RID p_texture){
+
+void RasterizerStorageGLES3::light_set_projector(RID p_light,RID p_texture){
 
 	Light * light = light_owner.getornull(p_light);
 	ERR_FAIL_COND(!light);
+
+	light->projector=p_texture;
 }
 
 void RasterizerStorageGLES3::light_set_negative(RID p_light,bool p_enable){
@@ -3263,12 +3264,6 @@ void RasterizerStorageGLES3::light_set_cull_mask(RID p_light,uint32_t p_mask){
 	light->version++;
 	light->instance_change_notify();
 
-}
-void RasterizerStorageGLES3::light_set_shader(RID p_light,RID p_shader){
-
-	Light * light = light_owner.getornull(p_light);
-	ERR_FAIL_COND(!light);
-
 }
 
 void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode) {
@@ -3315,6 +3310,26 @@ void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light,VS::L
 
 }
 
+void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light,bool p_enable) {
+
+	Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND(!light);
+
+	light->directional_blend_splits=p_enable;
+	light->version++;
+	light->instance_change_notify();
+
+}
+
+
+bool RasterizerStorageGLES3::light_directional_get_blend_splits(RID p_light) const {
+
+	const Light * light = light_owner.getornull(p_light);
+	ERR_FAIL_COND_V(!light,false);
+
+	return light->directional_blend_splits;
+}
+
 VS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_shadow_mode(RID p_light) {
 
 	const Light * light = light_owner.getornull(p_light);

+ 8 - 3
drivers/gles3/rasterizer_storage_gles3.h

@@ -634,12 +634,15 @@ public:
 		VS::LightType type;
 		float param[VS::LIGHT_PARAM_MAX];
 		Color color;
+		Color shadow_color;
+		RID projector;
 		bool shadow;
 		bool negative;
 		uint32_t cull_mask;
 		VS::LightOmniShadowMode omni_shadow_mode;
 		VS::LightOmniShadowDetail omni_shadow_detail;
 		VS::LightDirectionalShadowMode directional_shadow_mode;
+		bool directional_blend_splits;
 		uint64_t version;
 	};
 
@@ -650,17 +653,19 @@ public:
 	virtual void light_set_color(RID p_light,const Color& p_color);
 	virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value);
 	virtual void light_set_shadow(RID p_light,bool p_enabled);
+	virtual void light_set_shadow_color(RID p_light,const Color& p_color);
 	virtual void light_set_projector(RID p_light,RID p_texture);
-	virtual void light_set_attenuation_texure(RID p_light,RID p_texture);
 	virtual void light_set_negative(RID p_light,bool p_enable);
 	virtual void light_set_cull_mask(RID p_light,uint32_t p_mask);
-	virtual void light_set_shader(RID p_light,RID p_shader);
 
-	virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode);
 
+	virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode);
 	virtual void light_omni_set_shadow_detail(RID p_light,VS::LightOmniShadowDetail p_detail);
 
 	virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode);
+	virtual void light_directional_set_blend_splits(RID p_light,bool p_enable);
+	virtual bool light_directional_get_blend_splits(RID p_light) const;
+
 	virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
 	virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
 

+ 9 - 0
drivers/gles3/shader_gles3.cpp

@@ -228,8 +228,15 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 #endif
 
 
+
 	int define_line_ofs=1;
 
+	for(int i=0;i<custom_defines.size();i++) {
+
+		strings.push_back(custom_defines[i].get_data());
+		define_line_ofs++;
+	}
+
 	for(int j=0;j<conditional_count;j++) {
 		
 		bool enable=((1<<j)&conditional_version.version);
@@ -242,6 +249,8 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
 		}
 
 	}
+
+
 	
 	//keep them around during the function
 	CharString code_string;

+ 6 - 0
drivers/gles3/shader_gles3.h

@@ -175,6 +175,8 @@ private:
 	CharString vertex_code2;
 	CharString vertex_code3;
 
+	Vector<CharString> custom_defines;
+
 	int base_material_tex_index;
 
 	Version * get_current_version();
@@ -357,6 +359,10 @@ public:
 
 	void set_base_material_tex_index(int p_idx);
 
+	void add_custom_define(const String& p_define) {
+		custom_defines.push_back(p_define.utf8());
+	}
+
 	virtual ~ShaderGLES3();
 
 };

+ 167 - 87
drivers/gles3/shaders/scene.glsl

@@ -68,24 +68,26 @@ layout(std140) uniform SceneData { //ubo:0
 
 uniform highp mat4 world_transform;
 
-#ifdef USE_FORWARD_LIGHTING
+#ifdef USE_LIGHT_DIRECTIONAL
 
-layout(std140) uniform LightData { //ubo:3
+layout(std140) uniform DirectionalLightData { //ubo:3
 
 	highp vec4 light_pos_inv_radius;
 	mediump vec4 light_direction_attenuation;
 	mediump vec4 light_color_energy;
-	mediump vec4 light_params; //cone attenuation, specular, shadow darkening,
+	mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
 	mediump vec4 light_clamp;
-	mediump vec4 shadow_split_offsets;
+	mediump vec4 shadow_color;
 	highp mat4 shadow_matrix1;
 	highp mat4 shadow_matrix2;
 	highp mat4 shadow_matrix3;
 	highp mat4 shadow_matrix4;
+	mediump vec4 shadow_split_offsets;
 };
 
 #endif
 
+
 /* Varyings */
 
 out highp vec3 vertex_interp;
@@ -343,30 +345,71 @@ layout(std140) uniform SceneData {
 
 };
 
+//directional light data
 
-#ifdef USE_FORWARD_LIGHTING
+#ifdef USE_LIGHT_DIRECTIONAL
 
-layout(std140) uniform LightData {
+layout(std140) uniform DirectionalLightData {
 
 	highp vec4 light_pos_inv_radius;
 	mediump vec4 light_direction_attenuation;
 	mediump vec4 light_color_energy;
-	mediump vec4 light_params; //cone attenuation, specular, shadow darkening, shadow enabled
+	mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
 	mediump vec4 light_clamp;
-	mediump vec4 shadow_split_offsets;
+	mediump vec4 shadow_color;
 	highp mat4 shadow_matrix1;
 	highp mat4 shadow_matrix2;
 	highp mat4 shadow_matrix3;
 	highp mat4 shadow_matrix4;
+	mediump vec4 shadow_split_offsets;
 };
 
+
+uniform highp sampler2DShadow directional_shadow; //texunit:-4
+
 #endif
 
+//omni and spot
+
+struct LightData {
+
+	highp vec4 light_pos_inv_radius;
+	mediump vec4 light_direction_attenuation;
+	mediump vec4 light_color_energy;
+	mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
+	mediump vec4 light_clamp;
+	mediump vec4 shadow_color;
+	highp mat4 shadow_matrix;
+
+};
+
+
+layout(std140) uniform OmniLightData { //ubo:4
+
+	LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
+};
+
+layout(std140) uniform SpotLightData { //ubo:5
+
+	LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
+};
+
 
-uniform highp sampler2DShadow directional_shadow; //texunit:-4
 uniform highp sampler2DShadow shadow_atlas; //texunit:-3
 
 
+#ifdef USE_FORWARD_LIGHTING
+
+uniform int omni_light_indices[MAX_FORWARD_LIGHTS];
+uniform int omni_light_count;
+
+uniform int spot_light_indices[MAX_FORWARD_LIGHTS];
+uniform int spot_light_count;
+
+#endif
+
+
+
 #ifdef USE_MULTIPLE_RENDER_TARGETS
 
 layout(location=0) out vec4 diffuse_buffer;
@@ -415,18 +458,51 @@ float specularGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0)
     return dotNL * D * F * vis;
 }
 
-void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 diffuse_color, vec3 specular_color, float roughness, float attenuation, inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float roughness, inout vec3 diffuse, inout vec3 specular) {
 
-	diffuse += max(0.0,dot(normal,light_vec)) * diffuse_color * attenuation;
+	diffuse += max(0.0,dot(normal,light_vec)) * light_color * diffuse_color;
 	//specular += specular_ggx( roughness, max(0.0,dot(normal,eye_vec)) ) * specular_color * attenuation;
 	float s = roughness > 0.0 ? specularGGX(normal,eye_vec,light_vec,roughness,1.0) : 0.0;
-	specular += s * specular_color * attenuation;
+	specular += s * light_color * specular_color;
 }
 
 
 float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 pos, float depth, vec4 clamp_rect) {
 
+#ifdef SHADOW_MODE_PCF_13
+
+	float avg=textureProj(shadow,vec4(pos,depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x*2.0,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x*2.0,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y*2.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y*2.0),depth,1.0));
+	return avg*(1.0/13.0);
+
+#endif
+
+#ifdef SHADOW_MODE_PCF_5
+
+	float avg=textureProj(shadow,vec4(pos,depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0));
+	avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0));
+	return avg*(1.0/5.0);
+#endif
+
+#if !defined(SHADOW_MODE_PCF_5) && !defined(SHADOW_MODE_PCF_13)
+
 	return textureProj(shadow,vec4(pos,depth,1.0));
+#endif
+
 }
 
 #ifdef RENDER_SHADOW_DUAL_PARABOLOID
@@ -435,6 +511,73 @@ in highp float dp_clip;
 
 #endif
 
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) {
+
+	vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
+	float normalized_distance = length( light_rel_vec )*omni_lights[idx].light_pos_inv_radius.w;
+	vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w ));
+
+	if (omni_lights[idx].light_params.w>0.5) {
+		//there is a shadowmap
+
+		highp vec3 splane=(omni_lights[idx].shadow_matrix * vec4(vertex,1.0)).xyz;
+		float shadow_len=length(splane);
+		splane=normalize(splane);
+		vec4 clamp_rect=omni_lights[idx].light_clamp;
+
+		if (splane.z>=0.0) {
+
+			splane.z+=1.0;
+
+			clamp_rect.y+=clamp_rect.w;
+
+		} else {
+
+			splane.z=1.0 - splane.z;
+
+			//if (clamp_rect.z<clamp_rect.w) {
+			//	clamp_rect.x+=clamp_rect.z;
+			//} else {
+			//	clamp_rect.y+=clamp_rect.w;
+			//}
+
+		}
+
+		splane.xy/=splane.z;
+		splane.xy=splane.xy * 0.5 + 0.5;
+		splane.z = shadow_len * omni_lights[idx].light_pos_inv_radius.w;
+
+		splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw;
+
+		light_attenuation*=mix(omni_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect));
+	}
+
+	light_compute(normal,normalize(light_rel_vec),eye_vec,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
+
+}
+
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) {
+
+	vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
+	float normalized_distance = length( light_rel_vec )*spot_lights[idx].light_pos_inv_radius.w;
+	vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), spot_lights[idx].light_direction_attenuation.w ));
+	vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz;
+	float spot_cutoff=spot_lights[idx].light_params.y;
+	float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff);
+	float rim = (1.0 - scos) / (1.0 - spot_cutoff);
+	light_attenuation *= 1.0 - pow( rim, spot_lights[idx].light_params.x);
+
+	if (spot_lights[idx].light_params.w>0.5) {
+		//there is a shadowmap
+		highp vec4 splane=(spot_lights[idx].shadow_matrix * vec4(vertex,1.0));
+		splane.xyz/=splane.w;
+		light_attenuation*=mix(spot_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp));
+	}
+
+	light_compute(normal,normalize(light_rel_vec),eye_vec,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
+
+}
+
 void main() {
 
 #ifdef RENDER_SHADOW_DUAL_PARABOLOID
@@ -561,9 +704,9 @@ FRAGMENT_SHADER_CODE
 #endif
 
 
-#ifdef USE_FORWARD_DIRECTIONAL
+#ifdef USE_LIGHT_DIRECTIONAL
 
-	float light_attenuation=1.0;
+	vec3 light_attenuation=vec3(1.0);
 
 #ifdef LIGHT_DIRECTIONAL_SHADOW
 
@@ -589,7 +732,6 @@ FRAGMENT_SHADER_CODE
 
 			highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
 			pssm_coord=splane.xyz/splane.w;
-			ambient_light=vec3(1.0,0.4,0.4);
 
 
 #if defined(LIGHT_USE_PSSM_BLEND)
@@ -603,7 +745,6 @@ FRAGMENT_SHADER_CODE
 
 			highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0));
 			pssm_coord=splane.xyz/splane.w;
-			ambient_light=vec3(0.4,1.0,0.4);
 
 #if defined(LIGHT_USE_PSSM_BLEND)
 			splane=(shadow_matrix3 * vec4(vertex,1.0));
@@ -619,7 +760,6 @@ FRAGMENT_SHADER_CODE
 
 			highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0));
 			pssm_coord=splane.xyz/splane.w;
-			ambient_light=vec3(0.4,0.4,1.0);
 
 #if defined(LIGHT_USE_PSSM_BLEND)
 			splane=(shadow_matrix4 * vec4(vertex,1.0));
@@ -678,12 +818,12 @@ FRAGMENT_SHADER_CODE
 
 
 	//one one sample
-	light_attenuation=sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp);
+	light_attenuation=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp));
 
 
 #if defined(LIGHT_USE_PSSM_BLEND)
 	if (use_blend) {
-		float light_attenuation2=sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp);
+		vec3 light_attenuation2=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp));
 		light_attenuation=mix(light_attenuation,light_attenuation2,pssm_blend);
 	}
 #endif
@@ -692,84 +832,24 @@ FRAGMENT_SHADER_CODE
 
 #endif //LIGHT_DIRECTIONAL_SHADOW
 
-	light_compute(normal,-light_direction_attenuation.xyz,eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
-
-
-#endif //USE_FORWARD_DIRECTIONAL
-
+	light_compute(normal,-light_direction_attenuation.xyz,eye_vec,light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
 
-#ifdef USE_FORWARD_OMNI
 
-	vec3 light_rel_vec = light_pos_inv_radius.xyz-vertex;
-	float normalized_distance = length( light_rel_vec )*light_pos_inv_radius.w;
-	float light_attenuation = pow( max(1.0 - normalized_distance, 0.0), light_direction_attenuation.w );
+#endif //#USE_LIGHT_DIRECTIONAL
 
-	if (light_params.w>0.5) {
-		//there is a shadowmap
-
-		highp vec3 splane=(shadow_matrix1 * vec4(vertex,1.0)).xyz;
-		float shadow_len=length(splane);
-		splane=normalize(splane);
-		vec4 clamp_rect=light_clamp;
-
-		if (splane.z>=0.0) {
-
-			splane.z+=1.0;
 
-			clamp_rect.y+=clamp_rect.w;
-
-		} else {
-
-			splane.z=1.0 - splane.z;
-
-			//if (clamp_rect.z<clamp_rect.w) {
-			//	clamp_rect.x+=clamp_rect.z;
-			//} else {
-			//	clamp_rect.y+=clamp_rect.w;
-			//}
-
-		}
-
-		splane.xy/=splane.z;
-		splane.xy=splane.xy * 0.5 + 0.5;
-		splane.z = shadow_len * light_pos_inv_radius.w;
-
-		splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw;
+#ifdef USE_FORWARD_LIGHTING
 
-		light_attenuation*=sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect);
+	for(int i=0;i<omni_light_count;i++) {
+		light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light);
 	}
 
-	light_compute(normal,normalize(light_rel_vec),eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
-
-
-#endif //USE_FORWARD_OMNI
-
-#ifdef USE_FORWARD_SPOT
-
-	vec3 light_rel_vec = light_pos_inv_radius.xyz-vertex;
-	float normalized_distance = length( light_rel_vec )*light_pos_inv_radius.w;
-	float light_attenuation = pow( max(1.0 - normalized_distance, 0.0), light_direction_attenuation.w );
-	vec3 spot_dir = light_direction_attenuation.xyz;
-	float spot_cutoff=light_params.y;
-	float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff);
-	float rim = (1.0 - scos) / (1.0 - spot_cutoff);
-	light_attenuation *= 1.0 - pow( rim, light_params.x);
-
-	if (light_params.w>0.5) {
-		//there is a shadowmap
-
-		highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
-		splane.xyz/=splane.w;
-	//	splane.xy=splane.xy*0.5+0.5;
-
-		//splane.xy=light_clamp.xy+splane.xy*light_clamp.zw;
-		light_attenuation*=sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,light_clamp);
-
+	for(int i=0;i<spot_light_count;i++) {
+		light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light);
 	}
 
-	light_compute(normal,normalize(light_rel_vec),eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
+#endif
 
-#endif //USE_FORWARD_SPOT
 
 
 

+ 35 - 23
scene/3d/light.cpp

@@ -102,6 +102,17 @@ Color Light::get_color() const{
 	return color;
 }
 
+void Light::set_shadow_color(const Color& p_shadow_color){
+
+	shadow_color=p_shadow_color;
+	VS::get_singleton()->light_set_shadow_color(light,p_shadow_color);
+}
+
+Color Light::get_shadow_color() const{
+
+	return shadow_color;
+}
+
 
 AABB Light::get_aabb() const {
 
@@ -197,18 +208,18 @@ void Light::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_color","color"), &Light::set_color );
 	ObjectTypeDB::bind_method(_MD("get_color"), &Light::get_color );
 
-	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color"), _SCS("set_color"), _SCS("get_color"));
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY);
+	ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"), &Light::set_shadow_color );
+	ObjectTypeDB::bind_method(_MD("get_shadow_color"), &Light::get_shadow_color );
+
+	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_color"), _SCS("get_color"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY);
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative"));
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR);
-	ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask"), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR);
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkness"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_DARKNESS);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/normal_bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias_split_scale"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
-
+	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "shadow/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_shadow_color"), _SCS("get_shadow_color"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
 
 	BIND_CONSTANT( PARAM_ENERGY );
@@ -218,7 +229,6 @@ void Light::_bind_methods() {
 	BIND_CONSTANT( PARAM_SPOT_ANGLE );
 	BIND_CONSTANT( PARAM_SPOT_ATTENUATION );
 	BIND_CONSTANT( PARAM_SHADOW_MAX_DISTANCE );
-	BIND_CONSTANT( PARAM_SHADOW_DARKNESS );
 	BIND_CONSTANT( PARAM_SHADOW_SPLIT_1_OFFSET );
 	BIND_CONSTANT( PARAM_SHADOW_SPLIT_2_OFFSET );
 	BIND_CONSTANT( PARAM_SHADOW_SPLIT_3_OFFSET );
@@ -250,7 +260,6 @@ Light::Light(VisualServer::LightType p_type) {
 	set_param(PARAM_SPOT_ANGLE,45);
 	set_param(PARAM_SPOT_ATTENUATION,1);
 	set_param(PARAM_SHADOW_MAX_DISTANCE,0);
-	set_param(PARAM_SHADOW_DARKNESS,0);
 	set_param(PARAM_SHADOW_SPLIT_1_OFFSET,0.1);
 	set_param(PARAM_SHADOW_SPLIT_2_OFFSET,0.2);
 	set_param(PARAM_SHADOW_SPLIT_3_OFFSET,0.5);
@@ -291,6 +300,7 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
 void DirectionalLight::set_blend_splits(bool p_enable) {
 
 	blend_splits=p_enable;
+	VS::get_singleton()->light_directional_set_blend_splits(light,p_enable);
 }
 
 bool DirectionalLight::is_blend_splits_enabled() const {
@@ -307,11 +317,13 @@ void DirectionalLight::_bind_methods() {
 	ObjectTypeDB::bind_method( _MD("set_blend_splits","enabled"),&DirectionalLight::set_blend_splits);
 	ObjectTypeDB::bind_method( _MD("is_blend_splits_enabled"),&DirectionalLight::is_blend_splits_enabled);
 
-	ADD_PROPERTY( PropertyInfo( Variant::INT, "directional/shadow_mode",PROPERTY_HINT_ENUM,"Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_2"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_3"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET);
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "directional/blend_splits"), _SCS("set_blend_splits"), _SCS("is_blend_splits_enabled"));
+	ADD_PROPERTY( PropertyInfo( Variant::INT, "directional_shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_1",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_2",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_3",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET);
+	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "directional_shadow/blend_splits"), _SCS("set_blend_splits"), _SCS("is_blend_splits_enabled"));
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/normal_bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/bias_split_scale",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE);
 
 	BIND_CONSTANT( SHADOW_ORTHOGONAL );
 	BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
@@ -358,8 +370,8 @@ void OmniLight::_bind_methods() {
 	ObjectTypeDB::bind_method( _MD("set_shadow_detail","detail"),&OmniLight::set_shadow_detail);
 	ObjectTypeDB::bind_method( _MD("get_shadow_detail"),&OmniLight::get_shadow_detail);
 
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
 	ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_mode",PROPERTY_HINT_ENUM,"Dual Paraboloid,Cube"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
 	ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_detail",PROPERTY_HINT_ENUM,"Vertical,Horizontal"), _SCS("set_shadow_detail"), _SCS("get_shadow_detail"));
 
@@ -374,10 +386,10 @@ OmniLight::OmniLight() : Light( VisualServer::LIGHT_OMNI ) {
 
 void SpotLight::_bind_methods() {
 
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_angle"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE);
-	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_angle",PROPERTY_HINT_RANGE,"0,180,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE);
+	ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION);
 
 }
 

+ 4 - 1
scene/3d/light.h

@@ -52,7 +52,6 @@ public:
 		PARAM_SPOT_ANGLE = VS::LIGHT_PARAM_SPOT_ANGLE,
 		PARAM_SPOT_ATTENUATION = VS::LIGHT_PARAM_SPOT_ATTENUATION,
 		PARAM_SHADOW_MAX_DISTANCE = VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE,
-		PARAM_SHADOW_DARKNESS = VS::LIGHT_PARAM_SHADOW_DARKNESS,
 		PARAM_SHADOW_SPLIT_1_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
 		PARAM_SHADOW_SPLIT_2_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
 		PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
@@ -66,6 +65,7 @@ private:
 
 	Color color;
 	float param[PARAM_MAX];
+	Color shadow_color;
 	bool shadow;
 	bool negative;
 	uint32_t cull_mask;
@@ -107,6 +107,9 @@ public:
 	void set_color(const Color& p_color);
 	Color get_color() const;
 
+	void set_shadow_color(const Color& p_shadow_color);
+	Color get_shadow_color() const;
+
 
 	virtual AABB get_aabb() const;
 	virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;

+ 5 - 2
servers/visual/rasterizer.h

@@ -78,6 +78,7 @@ public:
 		Transform transform;
 
 		int depth_layer;
+		uint32_t layer_mask;
 
 		//RID sampled_light;
 
@@ -114,6 +115,7 @@ public:
 			billboard=false;
 			billboard_y=false;
 			depth_layer=0;
+			layer_mask=1;
 
 		}
 	};
@@ -295,16 +297,17 @@ public:
 	virtual void light_set_color(RID p_light,const Color& p_color)=0;
 	virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value)=0;
 	virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
+	virtual void light_set_shadow_color(RID p_light,const Color& p_color)=0;
 	virtual void light_set_projector(RID p_light,RID p_texture)=0;
-	virtual void light_set_attenuation_texure(RID p_light,RID p_texture)=0;
 	virtual void light_set_negative(RID p_light,bool p_enable)=0;
 	virtual void light_set_cull_mask(RID p_light,uint32_t p_mask)=0;
-	virtual void light_set_shader(RID p_light,RID p_shader)=0;
 
 	virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode)=0;
 	virtual void light_omni_set_shadow_detail(RID p_light,VS::LightOmniShadowDetail p_detail)=0;
 
 	virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode)=0;
+	virtual void light_directional_set_blend_splits(RID p_light,bool p_enable)=0;
+	virtual bool light_directional_get_blend_splits(RID p_light) const=0;
 
 	virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light)=0;
 	virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light)=0;

+ 2 - 2
servers/visual/visual_server_raster.h

@@ -757,16 +757,16 @@ public:
 	BIND2(light_set_color,RID,const Color&)
 	BIND3(light_set_param,RID ,LightParam ,float )
 	BIND2(light_set_shadow,RID ,bool )
+	BIND2(light_set_shadow_color,RID ,const Color& )
 	BIND2(light_set_projector,RID,RID )
-	BIND2(light_set_attenuation_texure,RID,RID )
 	BIND2(light_set_negative,RID,bool )
 	BIND2(light_set_cull_mask,RID ,uint32_t )
-	BIND2(light_set_shader,RID ,RID )
 
 	BIND2(light_omni_set_shadow_mode,RID,LightOmniShadowMode)
 	BIND2(light_omni_set_shadow_detail,RID,LightOmniShadowDetail)
 
 	BIND2(light_directional_set_shadow_mode,RID,LightDirectionalShadowMode)
+	BIND2(light_directional_set_blend_splits,RID,bool)
 
 	/* PROBE API */
 

+ 1 - 1
servers/visual/visual_server_scene.cpp

@@ -1165,7 +1165,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance,Camer
 
 			float texture_size=VSG::scene_render->get_directional_light_shadow_size(light->instance);
 
-			bool overlap = false;//rasterizer->light_instance_get_pssm_shadow_overlap(p_light->light_info->instance);
+			bool overlap = VSG::storage->light_directional_get_blend_splits(p_instance->base);
 
 			for (int i=0;i<splits;i++) {
 

+ 0 - 2
servers/visual/visual_server_scene.h

@@ -204,7 +204,6 @@ public:
 		float extra_margin;
 		uint32_t object_ID;
 		bool visible;
-		uint32_t layer_mask;
 
 		float lod_begin;
 		float lod_end;
@@ -253,7 +252,6 @@ public:
 
 			object_ID=0;
 			visible=true;
-			layer_mask=1;
 
 			lod_begin=0;
 			lod_end=0;

+ 2 - 3
servers/visual_server.h

@@ -357,7 +357,6 @@ public:
 		LIGHT_PARAM_SPOT_ANGLE,
 		LIGHT_PARAM_SPOT_ATTENUATION,
 		LIGHT_PARAM_SHADOW_MAX_DISTANCE,
-		LIGHT_PARAM_SHADOW_DARKNESS,
 		LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
 		LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
 		LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
@@ -372,11 +371,10 @@ public:
 	virtual void light_set_color(RID p_light,const Color& p_color)=0;
 	virtual void light_set_param(RID p_light,LightParam p_param,float p_value)=0;
 	virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
+	virtual void light_set_shadow_color(RID p_light,const Color& p_color)=0;
 	virtual void light_set_projector(RID p_light,RID p_texture)=0;
-	virtual void light_set_attenuation_texure(RID p_light,RID p_texture)=0;
 	virtual void light_set_negative(RID p_light,bool p_enable)=0;
 	virtual void light_set_cull_mask(RID p_light,uint32_t p_mask)=0;
-	virtual void light_set_shader(RID p_light,RID p_shader)=0;
 
 	// omni light
 	enum LightOmniShadowMode {
@@ -402,6 +400,7 @@ public:
 	};
 
 	virtual void light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode)=0;
+	virtual void light_directional_set_blend_splits(RID p_light,bool p_enable)=0;
 
 	/* PROBE API */
 

Some files were not shown because too many files changed in this diff