Browse Source

Changes to Light
-=-=-=-=-=-=-=-=

-Changed material unshaded property for an enum, which supports light-only shading
-Added a "Mix" shading mode, useful for using lights as masks
-Added energy parameter to Light2D

Juan Linietsky 10 years ago
parent
commit
9fa1698c74

BIN
demos/2d/light_mask/burano.png


+ 4 - 0
demos/2d/light_mask/engine.cfg

@@ -0,0 +1,4 @@
+[application]
+
+name="Using Lights As Mask"
+main_scene="res://lightmask.scn"

BIN
demos/2d/light_mask/lightmask.scn


BIN
demos/2d/light_mask/splat.png


+ 28 - 14
drivers/gles2/rasterizer_gles2.cpp

@@ -4611,6 +4611,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 		if (fragment_flags.uses_texpixel_size) {
 			enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
 		}
+		if (light_flags.uses_shadow_color) {
+			enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
+		}
 
 		if (vertex_flags.uses_worldvec) {
 			enablers.push_back("#define USE_WORLD_VEC\n");
@@ -9260,7 +9263,9 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
 			_canvas_item_setup_shader_uniforms(material,shader_cache);
 		}
 
-		if (material && material->unshaded) {
+		bool unshaded = material && material->shading_mode==VS::CANVAS_ITEM_SHADING_UNSHADED;
+
+		if (unshaded) {
 			canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,Color(1,1,1,1));
 			reset_modulate=true;
 		} else if (reset_modulate) {
@@ -9317,13 +9322,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
 
 		canvas_opacity = ci->final_opacity;
 
-		_canvas_item_render_commands<false>(ci,current_clip,reclip);
 
-		if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && (!material || !material->unshaded)) {
+		if (unshaded || (p_modulate.a>0.001 && (!material || material->shading_mode!=VS::CANVAS_ITEM_SHADING_ONLY_LIGHT)))
+			_canvas_item_render_commands<false>(ci,current_clip,reclip);
+
+		if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) {
 
 			CanvasLight *light = p_light;
 			bool light_used=false;
-			bool subtract=false;
+			VS::CanvasLightMode mode=VS::CANVAS_LIGHT_MODE_ADD;
 
 
 			while(light) {
@@ -9332,21 +9339,28 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
 
 					//intersects this light
 
-					if (!light_used || subtract!=light->subtract) {
+					if (!light_used || mode!=light->mode) {
 
-						subtract=light->subtract;
+						mode=light->mode;
 
-						if (subtract) {
+						switch(mode) {
 
-							glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
-							glBlendFunc(GL_SRC_ALPHA,GL_ONE);
-
-						} else {
+							case VS::CANVAS_LIGHT_MODE_ADD: {
+								glBlendEquation(GL_FUNC_ADD);
+								glBlendFunc(GL_SRC_ALPHA,GL_ONE);
 
-							glBlendEquation(GL_FUNC_ADD);
-							glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+							} break;
+							case VS::CANVAS_LIGHT_MODE_SUB: {
+								glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+								glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+							} break;
+							case VS::CANVAS_LIGHT_MODE_MIX: {
+								glBlendEquation(GL_FUNC_ADD);
+								glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
+							} break;
 						}
+
 					}
 
 					if (!light_used) {
@@ -9384,7 +9398,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
 
 					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX,light->light_shader_xform);
 					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS,light->light_shader_pos);
-					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,light->color);
+					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR,Color(light->color.r*light->energy,light->color.g*light->energy,light->color.b*light->energy,light->color.a));
 					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT,light->height);
 					canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX,light->xform_cache.affine_inverse());
 

+ 8 - 0
drivers/gles2/shader_compiler_gles2.cpp

@@ -266,6 +266,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 					uses_normal=true;
 				}
 
+				if (vnode->name==vname_shadow) {
+					uses_shadow_color=true;
+				}
 
 			}
 
@@ -616,6 +619,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	uses_texpixel_size=false;
 	uses_worldvec=false;
 	vertex_code_writes_vertex=false;
+	uses_shadow_color=false;
 	uniforms=r_uniforms;
 	flags=&r_flags;
 	r_flags.use_color_interp=false;
@@ -651,6 +655,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	r_flags.uses_normal=uses_normal;
 	r_flags.uses_texpixel_size=uses_texpixel_size;
 	r_flags.uses_worldvec=uses_worldvec;
+	r_flags.uses_shadow_color=uses_shadow_color;
 	r_code_line=code;
 	r_globals_line=global_code;
 
@@ -827,7 +832,9 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	mode_replace_table[5]["LIGHT_VEC"]="light_vec";
 	mode_replace_table[5]["LIGHT_HEIGHT"]="light_height";
 	mode_replace_table[5]["LIGHT_COLOR"]="light";
+	mode_replace_table[5]["LIGHT_UV"]="light_uv";
 	mode_replace_table[5]["LIGHT"]="light_out";
+	mode_replace_table[5]["SHADOW"]="shadow_color";
 	mode_replace_table[5]["SCREEN_UV"]="screen_uv";
 	mode_replace_table[5]["POINT_COORD"]="gl_PointCoord";
 	mode_replace_table[5]["TIME"]="time";
@@ -857,5 +864,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	vname_normal="NORMAL";
 	vname_texpixel_size="TEXTURE_PIXEL_SIZE";
 	vname_world_vec="WORLD_VERTEX";
+	vname_shadow="SHADOW";
 
 }

+ 3 - 0
drivers/gles2/shader_compiler_gles2.h

@@ -55,6 +55,7 @@ private:
 	bool uses_texpixel_size;
 	bool uses_worldvec;
 	bool vertex_code_writes_vertex;
+	bool uses_shadow_color;
 	Flags *flags;
 
 	StringName vname_discard;
@@ -74,6 +75,7 @@ private:
 	StringName vname_normal;
 	StringName vname_texpixel_size;
 	StringName vname_world_vec;
+	StringName vname_shadow;
 
 	Map<StringName,ShaderLanguage::Uniform> *uniforms;
 
@@ -110,6 +112,7 @@ public:
 		bool uses_normal;
 		bool uses_texpixel_size;
 		bool uses_worldvec;
+		bool uses_shadow_color;
 	};
 
 	Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL);

+ 10 - 2
drivers/gles2/shaders/canvas.glsl

@@ -230,7 +230,11 @@ FRAGMENT_SHADER_CODE
 
 	float att=1.0;
 
-	vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color;	
+	vec2 light_uv = light_uv_interp.xy;
+	vec4 light = texture2D(light_texture,light_uv) * light_color;
+#if defined(USE_LIGHT_SHADOW_COLOR)
+	vec4 shadow_color=vec4(0.0,0.0,0.0,0.0);
+#endif
 
 #if defined(USE_LIGHT_SHADER_CODE)
 //light is written by the light shader
@@ -362,7 +366,11 @@ LIGHT_SHADER_CODE
 
 #endif
 
-		color.rgb*=shadow_attenuation;
+#if defined(USE_LIGHT_SHADOW_COLOR)
+	color=mix(shadow_color,color,shadow_attenuation);
+#else
+	color.rgb*=shadow_attenuation;
+#endif
 //use shadows
 #endif
 	}

+ 19 - 14
scene/2d/canvas_item.cpp

@@ -42,8 +42,8 @@ bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value)
 	if (p_name==SceneStringNames::get_singleton()->shader_shader) {
 		set_shader(p_value);
 		return true;
-	} else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) {
-		set_unshaded(p_value);
+	} else if (p_name==SceneStringNames::get_singleton()->shading_mode) {
+		set_shading_mode(ShadingMode(p_value.operator int()));
 		return true;
 	} else {
 
@@ -74,10 +74,10 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const {
 
 		r_ret=get_shader();
 		return true;
-	} else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) {
+	} else if (p_name==SceneStringNames::get_singleton()->shading_mode) {
 
 
-		r_ret=unshaded;
+		r_ret=shading_mode;
 		return true;
 	} else {
 
@@ -100,7 +100,7 @@ bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const {
 void CanvasItemMaterial::_get_property_list( List<PropertyInfo> *p_list) const {
 
 	p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "shader/unshaded") );
+	p_list->push_back( PropertyInfo( Variant::INT, "shader/shading_mode",PROPERTY_HINT_ENUM,"Normal,Unshaded,Light Only") );
 
 	if (!shader.is_null()) {
 
@@ -161,25 +161,30 @@ RID CanvasItemMaterial::get_rid() const {
 	return material;
 }
 
-void CanvasItemMaterial::set_unshaded(bool p_unshaded) {
+void CanvasItemMaterial::set_shading_mode(ShadingMode p_mode) {
 
-	unshaded=p_unshaded;
-	VS::get_singleton()->canvas_item_material_set_unshaded(material,p_unshaded);
+	shading_mode=p_mode;
+	VS::get_singleton()->canvas_item_material_set_shading_mode(material,VS::CanvasItemShadingMode(p_mode));
 }
 
-bool CanvasItemMaterial::is_unshaded() const{
-
-	return unshaded;
+CanvasItemMaterial::ShadingMode CanvasItemMaterial::get_shading_mode() const {
+	return shading_mode;
 }
 
+
 void CanvasItemMaterial::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"),&CanvasItemMaterial::set_shader);
 	ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader);
 	ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param);
 	ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param);
-	ObjectTypeDB::bind_method(_MD("set_unshaded","unshaded"),&CanvasItemMaterial::set_unshaded);
-	ObjectTypeDB::bind_method(_MD("is_unshaded"),&CanvasItemMaterial::is_unshaded);
+	ObjectTypeDB::bind_method(_MD("set_shading_mode","mode"),&CanvasItemMaterial::set_shading_mode);
+	ObjectTypeDB::bind_method(_MD("get_shading_mode"),&CanvasItemMaterial::get_shading_mode);
+
+	BIND_CONSTANT( SHADING_NORMAL );
+	BIND_CONSTANT( SHADING_UNSHADED );
+	BIND_CONSTANT( SHADING_ONLY_LIGHT );
+
 
 }
 
@@ -202,7 +207,7 @@ void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p
 CanvasItemMaterial::CanvasItemMaterial() {
 
 	material=VS::get_singleton()->canvas_item_material_create();
-	unshaded=false;
+	shading_mode=SHADING_NORMAL;
 }
 
 CanvasItemMaterial::~CanvasItemMaterial(){

+ 12 - 3
scene/2d/canvas_item.h

@@ -45,10 +45,17 @@ class CanvasItemMaterial : public Resource{
 	OBJ_TYPE(CanvasItemMaterial,Resource);
 	RID material;
 	Ref<Shader> shader;
-	bool unshaded;
+public:
+	enum ShadingMode {
+		SHADING_NORMAL,
+		SHADING_UNSHADED,
+		SHADING_ONLY_LIGHT,
+	};
 
 protected:
 
+	ShadingMode shading_mode;
+
 	bool _set(const StringName& p_name, const Variant& p_value);
 	bool _get(const StringName& p_name,Variant &r_ret) const;
 	void _get_property_list( List<PropertyInfo> *p_list) const;
@@ -66,14 +73,16 @@ public:
 	void set_shader_param(const StringName& p_param,const Variant& p_value);
 	Variant get_shader_param(const StringName& p_param) const;
 
-	void set_unshaded(bool p_unshaded);
-	bool is_unshaded() const;
+	void set_shading_mode(ShadingMode p_mode);
+	ShadingMode get_shading_mode() const;
 
 	virtual RID get_rid() const;
 	CanvasItemMaterial();
 	~CanvasItemMaterial();
 };
 
+VARIANT_ENUM_CAST( CanvasItemMaterial::ShadingMode );
+
 
 class CanvasItem : public Node {
 

+ 33 - 9
scene/2d/light_2d.cpp

@@ -96,6 +96,21 @@ float Light2D::get_height() const {
 	return height;
 }
 
+void Light2D::set_energy( float p_energy) {
+
+	energy=p_energy;
+	VS::get_singleton()->canvas_light_set_energy(canvas_light,energy);
+
+}
+
+
+float Light2D::get_energy() const {
+
+	return energy;
+}
+
+
+
 void Light2D::set_texture_scale( float p_scale) {
 
 	_scale=p_scale;
@@ -178,15 +193,15 @@ int Light2D::get_item_shadow_mask() const {
 	return item_shadow_mask;
 }
 
-void Light2D::set_subtract_mode( bool p_enable ) {
+void Light2D::set_mode( Mode p_mode ) {
 
-	subtract_mode=p_enable;
-	VS::get_singleton()->canvas_light_set_subtract_mode(canvas_light,p_enable);
+	mode=p_mode;
+	VS::get_singleton()->canvas_light_set_mode(canvas_light,VS::CanvasLightMode(p_mode));
 }
 
-bool Light2D::get_subtract_mode() const {
+Light2D::Mode Light2D::get_mode() const {
 
-	return subtract_mode;
+	return mode;
 }
 
 void Light2D::set_shadow_enabled( bool p_enabled) {
@@ -260,6 +275,9 @@ void Light2D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_height","height"),&Light2D::set_height);
 	ObjectTypeDB::bind_method(_MD("get_height"),&Light2D::get_height);
 
+	ObjectTypeDB::bind_method(_MD("set_energy","energy"),&Light2D::set_energy);
+	ObjectTypeDB::bind_method(_MD("get_energy"),&Light2D::get_energy);
+
 	ObjectTypeDB::bind_method(_MD("set_texture_scale","texture_scale"),&Light2D::set_texture_scale);
 	ObjectTypeDB::bind_method(_MD("get_texture_scale"),&Light2D::get_texture_scale);
 
@@ -283,8 +301,8 @@ void Light2D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_item_shadow_mask","item_shadow_mask"),&Light2D::set_item_shadow_mask);
 	ObjectTypeDB::bind_method(_MD("get_item_shadow_mask"),&Light2D::get_item_shadow_mask);
 
-	ObjectTypeDB::bind_method(_MD("set_subtract_mode","enable"),&Light2D::set_subtract_mode);
-	ObjectTypeDB::bind_method(_MD("get_subtract_mode"),&Light2D::get_subtract_mode);
+	ObjectTypeDB::bind_method(_MD("set_mode","mode"),&Light2D::set_mode);
+	ObjectTypeDB::bind_method(_MD("get_mode"),&Light2D::get_mode);
 
 	ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled);
 	ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled);
@@ -300,7 +318,8 @@ void Light2D::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"scale",PROPERTY_HINT_RANGE,"0.01,4096,0.01"),_SCS("set_texture_scale"),_SCS("get_texture_scale"));
 	ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
-	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode"));
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"energy"),_SCS("set_energy"),_SCS("get_energy"));
+	ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Add,Sub,Mix"),_SCS("set_mode"),_SCS("get_mode"));
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max"));
@@ -312,6 +331,10 @@ void Light2D::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier"));
 	ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_mask"),_SCS("get_item_shadow_mask"));
 
+	BIND_CONSTANT( MODE_ADD );
+	BIND_CONSTANT( MODE_SUB );
+	BIND_CONSTANT( MODE_MIX );
+
 
 }
 
@@ -329,9 +352,10 @@ Light2D::Light2D() {
 	layer_max=0;
 	item_mask=1;
 	item_shadow_mask=1;
-	subtract_mode=false;
+	mode=MODE_ADD;
 	shadow_buffer_size=2048;
 	shadow_esm_multiplier=80;
+	energy=1.0;
 
 }
 

+ 15 - 3
scene/2d/light_2d.h

@@ -6,6 +6,13 @@
 class Light2D : public Node2D {
 
 	OBJ_TYPE(Light2D,Node2D);
+public:
+	enum Mode {
+		MODE_ADD,
+		MODE_SUB,
+		MODE_MIX,
+	};
+
 private:
 	RID canvas_light;
 	bool enabled;
@@ -13,6 +20,7 @@ private:
 	Color color;
 	float height;
 	float _scale;
+	float energy;
 	int z_min;
 	int z_max;
 	int layer_min;
@@ -21,7 +29,7 @@ private:
 	int item_shadow_mask;
 	int shadow_buffer_size;
 	float shadow_esm_multiplier;
-	bool subtract_mode;
+	Mode mode;
 	Ref<Texture> texture;
 	Vector2 texture_offset;
 
@@ -51,6 +59,9 @@ public:
 	void set_height( float p_height);
 	float get_height() const;
 
+	void set_energy( float p_energy);
+	float get_energy() const;
+
 	void set_texture_scale( float p_scale);
 	float get_texture_scale() const;
 
@@ -72,8 +83,8 @@ public:
 	void set_item_shadow_mask( int p_mask);
 	int get_item_shadow_mask() const;
 
-	void set_subtract_mode( bool p_enable );
-	bool get_subtract_mode() const;
+	void set_mode( Mode p_mode );
+	Mode get_mode() const;
 
 	void set_shadow_enabled( bool p_enabled);
 	bool is_shadow_enabled() const;
@@ -90,5 +101,6 @@ public:
 	~Light2D();
 };
 
+VARIANT_ENUM_CAST(Light2D::Mode);
 
 #endif // LIGHT_2D_H

+ 1 - 0
scene/scene_string_names.cpp

@@ -42,6 +42,7 @@ SceneStringNames::SceneStringNames() {
 	input_event=StaticCString::create("input_event");
 	shader_shader=StaticCString::create("shader/shader");
 	shader_unshaded=StaticCString::create("shader/unshaded");
+	shading_mode=StaticCString::create("shader/shading_mode");
 	enter_tree=StaticCString::create("enter_tree");
 	exit_tree=StaticCString::create("exit_tree");
 	item_rect_changed=StaticCString::create("item_rect_changed");

+ 1 - 0
scene/scene_string_names.h

@@ -57,6 +57,7 @@ public:
 	StringName item_rect_changed;
 	StringName shader_shader;
 	StringName shader_unshaded;
+	StringName shading_mode;
 	StringName enter_tree;
 	StringName exit_tree;
 	StringName size_flags_changed;

+ 6 - 4
servers/visual/rasterizer.h

@@ -577,6 +577,7 @@ public:
 		Color color;
 		Matrix32 xform;
 		float height;
+		float energy;
 		float scale;
 		int z_min;
 		int z_max;
@@ -584,7 +585,7 @@ public:
 		int layer_max;
 		int item_mask;
 		int item_shadow_mask;
-		bool subtract;
+		VS::CanvasLightMode mode;
 		RID texture;
 		Vector2 texture_offset;
 		RID canvas;
@@ -616,8 +617,9 @@ public:
 			layer_max=0;
 			item_mask=1;
 			scale=1.0;
+			energy=1.0;
 			item_shadow_mask=-1;
-			subtract=false;
+			mode=VS::CANVAS_LIGHT_MODE_ADD;
 			texture_cache=NULL;
 			next_ptr=NULL;
 			filter_next_ptr=NULL;
@@ -635,9 +637,9 @@ public:
 		Map<StringName,Variant> shader_param;
 		uint32_t shader_version;
 		Set<CanvasItem*> owners;
-		bool unshaded;
+		VS::CanvasItemShadingMode shading_mode;
 
-		CanvasItemMaterial() {unshaded=false; shader_version=0; }
+		CanvasItemMaterial() {shading_mode=VS::CANVAS_ITEM_SHADING_NORMAL; shader_version=0; }
 	};
 
 	struct CanvasItem {

+ 2 - 0
servers/visual/shader_language.cpp

@@ -1171,7 +1171,9 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={
 	{ "LIGHT_VEC", TYPE_VEC2},
 	{ "LIGHT_HEIGHT", TYPE_FLOAT},
 	{ "LIGHT_COLOR", TYPE_VEC4},
+	{ "LIGHT_UV", TYPE_VEC2},
 	{ "LIGHT", TYPE_VEC4},
+	{ "SHADOW", TYPE_VEC4},
 	{ "POINT_COORD", TYPE_VEC2},
 //	{ "SCREEN_POS", TYPE_VEC2},
 //	{ "SCREEN_TEXEL_SIZE", TYPE_VEC2},

+ 13 - 4
servers/visual/visual_server_raster.cpp

@@ -3977,6 +3977,15 @@ void VisualServerRaster::canvas_light_set_height(RID p_light, float p_height){
 	clight->height=p_height;
 
 }
+
+void VisualServerRaster::canvas_light_set_energy(RID p_light, float p_energy){
+
+	Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
+	ERR_FAIL_COND(!clight);
+	clight->energy=p_energy;
+
+}
+
 void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){
 
 	Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
@@ -4012,12 +4021,12 @@ void VisualServerRaster::canvas_light_set_item_shadow_mask(RID p_light, int p_ma
 }
 
 
-void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) {
+void VisualServerRaster::canvas_light_set_mode(RID p_light, CanvasLightMode p_mode) {
 
 
 	Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
 	ERR_FAIL_COND(!clight);
-	clight->subtract=p_enable;
+	clight->mode=p_mode;
 
 }
 void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){
@@ -4267,12 +4276,12 @@ Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material
 	return material->shader_param[p_param];
 }
 
-void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){
+void VisualServerRaster::canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode) {
 
 	VS_CHANGED;
 	Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
 	ERR_FAIL_COND(!material);
-	material->unshaded=p_unshaded;
+	material->shading_mode=p_mode;
 
 }
 

+ 5 - 3
servers/visual/visual_server_raster.h

@@ -1170,12 +1170,13 @@ public:
 	virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset);
 	virtual void canvas_light_set_color(RID p_light, const Color& p_color);
 	virtual void canvas_light_set_height(RID p_light, float p_height);
+	virtual void canvas_light_set_energy(RID p_light, float p_energy);
 	virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z);
 	virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer);
 	virtual void canvas_light_set_item_mask(RID p_light, int p_mask);
 	virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask);
 
-	virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable);
+	virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode);
 	virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
 	virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
 	virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier);
@@ -1204,8 +1205,9 @@ public:
 	virtual RID canvas_item_material_create();
 	virtual void canvas_item_material_set_shader(RID p_material, RID p_shader);
 	virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value);
-	virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;
-	virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded);
+	virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;	
+	virtual void canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode);
+
 
 
 	/* CURSOR */

+ 4 - 3
servers/visual/visual_server_wrap_mt.h

@@ -1160,12 +1160,13 @@ public:
 	FUNC2(canvas_light_set_texture_offset,RID,const Vector2&);
 	FUNC2(canvas_light_set_color,RID,const Color&);
 	FUNC2(canvas_light_set_height,RID,float);
+	FUNC2(canvas_light_set_energy,RID,float);
 	FUNC3(canvas_light_set_layer_range,RID,int,int);
 	FUNC3(canvas_light_set_z_range,RID,int,int);
 	FUNC2(canvas_light_set_item_mask,RID,int);
 	FUNC2(canvas_light_set_item_shadow_mask,RID,int);
 
-	FUNC2(canvas_light_set_subtract_mode,RID,bool);
+	FUNC2(canvas_light_set_mode,RID,CanvasLightMode);
 	FUNC2(canvas_light_set_shadow_enabled,RID,bool);
 	FUNC2(canvas_light_set_shadow_buffer_size,RID,int);
 	FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float);
@@ -1191,8 +1192,8 @@ public:
 	FUNC0R(RID,canvas_item_material_create);
 	FUNC2(canvas_item_material_set_shader,RID,RID);
 	FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&);
-	FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);
-	FUNC2(canvas_item_material_set_unshaded,RID,bool);
+	FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);	
+	FUNC2(canvas_item_material_set_shading_mode,RID,CanvasItemShadingMode);
 
 	/* CURSOR */
 	FUNC2(cursor_set_rotation,float , int ); // radians

+ 17 - 2
servers/visual_server.h

@@ -1014,12 +1014,19 @@ public:
 	virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset)=0;
 	virtual void canvas_light_set_color(RID p_light, const Color& p_color)=0;
 	virtual void canvas_light_set_height(RID p_light, float p_height)=0;
+	virtual void canvas_light_set_energy(RID p_light, float p_energy)=0;
 	virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z)=0;
 	virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer)=0;
 	virtual void canvas_light_set_item_mask(RID p_light, int p_mask)=0;
 	virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask)=0;
 
-	virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0;
+	enum CanvasLightMode {
+		CANVAS_LIGHT_MODE_ADD,
+		CANVAS_LIGHT_MODE_SUB,
+		CANVAS_LIGHT_MODE_MIX,
+	};
+
+	virtual void canvas_light_set_mode(RID p_light, CanvasLightMode p_mode)=0;
 	virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0;
 	virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0;
 	virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0;
@@ -1049,7 +1056,15 @@ public:
 	virtual void canvas_item_material_set_shader(RID p_material, RID p_shader)=0;
 	virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value)=0;
 	virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const=0;
-	virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded)=0;
+
+
+	enum CanvasItemShadingMode {
+		CANVAS_ITEM_SHADING_NORMAL,
+		CANVAS_ITEM_SHADING_UNSHADED,
+		CANVAS_ITEM_SHADING_ONLY_LIGHT,
+	};
+
+	virtual void canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode)=0;
 
 	/* CURSOR */
 	virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians