Browse Source

Merge branch 'master' into x11-window-management

hurikhan 10 years ago
parent
commit
6b6c526048

+ 151 - 4
drivers/gles2/rasterizer_gles2.cpp

@@ -1411,6 +1411,9 @@ void RasterizerGLES2::shader_set_mode(RID p_shader,VS::ShaderMode p_mode) {
 			case VS::SHADER_MATERIAL: {
 				material_shader.free_custom_shader(shader->custom_code_id);
 			} break;
+			case VS::SHADER_CANVAS_ITEM: {
+				canvas_shader.free_custom_shader(shader->custom_code_id);
+			} break;
 		}
 
 		shader->custom_code_id=0;
@@ -1422,6 +1425,9 @@ void RasterizerGLES2::shader_set_mode(RID p_shader,VS::ShaderMode p_mode) {
 		case VS::SHADER_MATERIAL: {
 			shader->custom_code_id=material_shader.create_custom_shader();
 		} break;
+		case VS::SHADER_CANVAS_ITEM: {
+			shader->custom_code_id=canvas_shader.create_custom_shader();
+		} break;
 	}
 	_shader_make_dirty(shader);
 
@@ -4434,6 +4440,13 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 		if (err) {
 			return; //invalid
 		}
+	} else if (p_shader->mode==VS::SHADER_CANVAS_ITEM) {
+
+		Error err = shader_precompiler.compile(p_shader->vertex_code,ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX,vertex_code,vertex_globals,vertex_flags,&p_shader->uniforms);
+		if (err) {
+			return; //invalid
+		}
+
 	}
 
 	//print_line("compiled vertex: "+vertex_code);
@@ -4443,9 +4456,16 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 	String fragment_code;
 	String fragment_globals;
 
-	Error err = shader_precompiler.compile(p_shader->fragment_code,(p_shader->mode==VS::SHADER_MATERIAL?ShaderLanguage::SHADER_MATERIAL_FRAGMENT:ShaderLanguage::SHADER_POST_PROCESS),fragment_code,fragment_globals,fragment_flags,&p_shader->uniforms);
-	if (err) {
-		return; //invalid
+	if (p_shader->mode==VS::SHADER_MATERIAL) {
+		Error err = shader_precompiler.compile(p_shader->fragment_code,ShaderLanguage::SHADER_MATERIAL_FRAGMENT,fragment_code,fragment_globals,fragment_flags,&p_shader->uniforms);
+		if (err) {
+			return; //invalid
+		}
+	} else if (p_shader->mode==VS::SHADER_CANVAS_ITEM) {
+		Error err = shader_precompiler.compile(p_shader->fragment_code,ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT,fragment_code,fragment_globals,fragment_flags,&p_shader->uniforms);
+		if (err) {
+			return; //invalid
+		}
 	}
 
 
@@ -4458,6 +4478,11 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 		if (err) {
 			return; //invalid
 		}
+	} else if (p_shader->mode==VS::SHADER_CANVAS_ITEM) {
+		Error err = shader_precompiler.compile(p_shader->light_code,(ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT),light_code,light_globals,light_flags,&p_shader->uniforms);
+		if (err) {
+			return; //invalid
+		}
 	}
 
 	fragment_globals+=light_globals; //both fragment anyway
@@ -4518,7 +4543,33 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 		}
 
 		material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
-	} else {
+	} else if (p_shader->mode==VS::SHADER_CANVAS_ITEM) {
+
+		Vector<const char*> enablers;
+
+		if (light_flags.uses_time || fragment_flags.uses_time || vertex_flags.uses_time) {
+			enablers.push_back("#define USE_TIME\n");
+			uses_time=true;
+		}
+		if (fragment_flags.uses_normal) {
+			enablers.push_back("#define NORMAL_USED\n");
+		}
+		if (light_flags.uses_light) {
+			enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
+		}
+		if (fragment_flags.use_var1_interp || vertex_flags.use_var1_interp)
+			enablers.push_back("#define ENABLE_VAR1_INTERP\n");
+		if (fragment_flags.use_var2_interp || vertex_flags.use_var2_interp)
+			enablers.push_back("#define ENABLE_VAR2_INTERP\n");
+		if (fragment_flags.uses_texscreen) {
+			enablers.push_back("#define ENABLE_TEXSCREEN\n");
+		}
+		if (fragment_flags.uses_screen_uv) {
+			enablers.push_back("#define ENABLE_SCREEN_UV\n");
+		}
+
+		canvas_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
+
 		//postprocess_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names);
 	}
 
@@ -4529,6 +4580,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 	p_shader->has_texscreen=fragment_flags.uses_texscreen;
 	p_shader->has_screen_uv=fragment_flags.uses_screen_uv;
 	p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex;
+	p_shader->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal;
 	p_shader->uses_time=uses_time;
 	p_shader->version++;
 
@@ -7722,6 +7774,7 @@ void RasterizerGLES2::canvas_begin() {
 	canvas_tex=RID();
 	//material_shader.unbind();
 	canvas_shader.unbind();
+	canvas_shader.set_custom_shader(0);
 	canvas_shader.bind();
 	canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0);
 	_set_color_attrib(Color(1,1,1));
@@ -8219,7 +8272,19 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 
 
 	CanvasItem *current_clip=NULL;
+	RID last_shader;
+
+	Transform canvas_transform;
+	canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
+	float csy = 1.0;
+	if (current_rt && current_rt_vflip)
+		csy = -1.0;
 
+	canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) );
+
+
+	canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
+	canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
 
 	while(p_item_list) {
 
@@ -8231,6 +8296,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 			}
 			memdelete(ci->vp_render);
 			ci->vp_render=NULL;
+			last_shader=RID();
 		}
 
 		if (current_clip!=ci->final_clip_owner) {
@@ -8248,10 +8314,89 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 				glDisable(GL_SCISSOR_TEST);
 			}
 		}
+
+
 		//begin rect
+
+		if (ci->shader!=last_shader) {
+
+			Shader *shader = NULL;
+			if (ci->shader.is_valid()) {
+				shader = shader_owner.get(ci->shader);
+				if (shader && !shader->valid) {
+					shader=NULL;
+				}
+			}
+
+			if (shader) {
+				canvas_shader.set_custom_shader(shader->custom_code_id);
+				canvas_shader.bind();
+
+				if (ci->shader_version!=shader->version) {
+					//todo optimize uniforms
+					ci->shader_version=shader->version;
+				}
+				//this can be optimized..
+				int tex_id=1;
+				int idx=0;
+				for(Map<StringName,ShaderLanguage::Uniform>::Element *E=shader->uniforms.front();E;E=E->next()) {
+
+
+					Map<StringName,Variant>::Element *F=ci->shader_param.find(E->key());
+					Variant &v=F?F->get():E->get().default_value;
+					if (v.get_type()==Variant::_RID || v.get_type()==Variant::OBJECT) {
+						int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic..
+
+						glActiveTexture(GL_TEXTURE0+tex_id);
+						RID tex = v;
+						Texture *t=texture_owner.get(tex);
+						if (!t)
+							glBindTexture(GL_TEXTURE_2D,white_tex);
+						else
+							glBindTexture(t->target,t->tex_id);
+
+						glUniform1i(loc,tex_id);
+						tex_id++;
+
+					} else {
+						canvas_shader.set_custom_uniform(idx,v);
+					}
+
+					idx++;
+				}
+
+
+				if (shader->has_texscreen && framebuffer.active) {
+					canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
+					canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,tex_id);
+					glActiveTexture(GL_TEXTURE0+tex_id);
+					glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
+
+				}
+				if (shader->has_screen_uv) {
+					canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height));
+				}
+
+				if (shader->uses_time) {
+					canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0));
+					draw_next_frame=true;
+				}
+					//if uses TIME - draw_next_frame=true
+
+			} else {
+				canvas_shader.set_custom_shader(0);
+				canvas_shader.bind();
+
+			}
+
+			canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
+			last_shader=ci->shader;
+		}
+
 		canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform);
 		canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32());
 
+
 		bool reclip=false;
 
 		if (ci==p_item_list || ci->blend_mode!=canvas_blend_mode) {
@@ -8291,6 +8436,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 		int cc=ci->commands.size();
 		CanvasItem::Command **commands = ci->commands.ptr();
 
+		canvas_opacity = ci->final_opacity;
+
 		for(int i=0;i<cc;i++) {
 
 			CanvasItem::Command *c=commands[i];

+ 3 - 1
drivers/gles2/rasterizer_gles2.h

@@ -191,6 +191,7 @@ class RasterizerGLES2 : public Rasterizer {
 		bool writes_vertex;
 		bool uses_discard;
 		bool uses_time;
+		bool uses_normal;
 
 		Map<StringName,ShaderLanguage::Uniform> uniforms;
 		StringName first_texture;
@@ -214,6 +215,7 @@ class RasterizerGLES2 : public Rasterizer {
 			writes_vertex=false;
 			uses_discard=false;
 			uses_time=false;
+			uses_normal=false;
 		}
 
 
@@ -1199,7 +1201,7 @@ class RasterizerGLES2 : public Rasterizer {
 	RID overdraw_material;
 
 	mutable MaterialShaderGLES2 material_shader;
-	CanvasShaderGLES2 canvas_shader;
+	mutable CanvasShaderGLES2 canvas_shader;
 	BlurShaderGLES2 blur_shader;
 	CopyShaderGLES2 copy_shader;
 

+ 40 - 0
drivers/gles2/shader_compiler_gles2.cpp

@@ -181,6 +181,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 				if (vnode->name==vname_normalmap) {
 					uses_normalmap=true;
 				}
+				if (vnode->name==vname_normal) {
+					uses_normal=true;
+				}
 				if (vnode->name==vname_screen_uv) {
 					uses_screen_uv=true;
 				}
@@ -552,6 +555,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	uses_light=false;
 	uses_time=false;
 	uses_normalmap=false;
+	uses_normal=false;
 	vertex_code_writes_vertex=false;
 	uniforms=r_uniforms;
 	flags=&r_flags;
@@ -562,6 +566,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	r_flags.use_var1_interp=false;
 	r_flags.use_var2_interp=false;
 	r_flags.uses_normalmap=false;
+	r_flags.uses_normal=false;
 
 	String error;
 	int errline,errcol;
@@ -584,6 +589,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	r_flags.uses_light=uses_light;
 	r_flags.uses_time=uses_time;
 	r_flags.uses_normalmap=uses_normalmap;
+	r_flags.uses_normal=uses_normalmap;
 	r_code_line=code;
 	r_globals_line=global_code;
 
@@ -721,6 +727,39 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	mode_replace_table[2]["POINT_COORD"]="gl_PointCoord";
 	mode_replace_table[2]["TIME"]="time";
 
+	mode_replace_table[3]["SRC_VERTEX"]="src_vtx";
+	mode_replace_table[3]["VERTEX"]="outvec.xy";
+	mode_replace_table[3]["UV"]="uv_interp";
+	mode_replace_table[3]["COLOR"]="color_interp";
+	mode_replace_table[3]["VAR1"]="var1_interp";
+	mode_replace_table[3]["VAR2"]="var2_interp";
+	mode_replace_table[3]["POINT_SIZE"]="gl_PointSize";
+	mode_replace_table[3]["WORLD_MATRIX"]="modelview_matrix";
+	mode_replace_table[3]["PROJECTION_MATRIX"]="projection_matrix";
+	mode_replace_table[3]["EXTRA_MATRIX"]="extra_matrix";
+	mode_replace_table[3]["TIME"]="time";
+
+	mode_replace_table[4]["POSITION"]="gl_Position";
+	mode_replace_table[4]["NORMAL"]="normal";
+	mode_replace_table[4]["UV"]="uv_interp";
+	mode_replace_table[4]["COLOR"]="color";
+	mode_replace_table[4]["TEXTURE"]="texture";
+	mode_replace_table[4]["VAR1"]="var1_interp";
+	mode_replace_table[4]["VAR2"]="var2_interp";
+	mode_replace_table[4]["SCREEN_UV"]="screen_uv";
+	mode_replace_table[4]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[4]["TIME"]="time";
+
+	mode_replace_table[5]["COLOR"]="color";
+	mode_replace_table[5]["NORMAL"]="normal";
+	mode_replace_table[5]["LIGHT_DIR"]="light_dir";
+	mode_replace_table[5]["LIGHT_DISTANCE"]="light_distance";
+	mode_replace_table[5]["LIGHT"]="light";
+	mode_replace_table[5]["POINT_COORD"]="gl_PointCoord";
+	mode_replace_table[5]["TIME"]="time";
+
+
+
 	//mode_replace_table[2]["SCREEN_POS"]="SCREEN_POS";
 	//mode_replace_table[2]["SCREEN_TEXEL_SIZE"]="SCREEN_TEXEL_SIZE";
 
@@ -741,5 +780,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	vname_light="LIGHT";
 	vname_time="TIME";
 	vname_normalmap="NORMALMAP";
+	vname_normal="NORMAL";
 
 }

+ 4 - 1
drivers/gles2/shader_compiler_gles2.h

@@ -51,6 +51,7 @@ private:
 	bool uses_time;
 	bool uses_screen_uv;
 	bool uses_normalmap;
+	bool uses_normal;
 	bool vertex_code_writes_vertex;
 	Flags *flags;
 
@@ -68,6 +69,7 @@ private:
 	StringName vname_light;
 	StringName vname_time;
 	StringName vname_normalmap;
+	StringName vname_normal;
 
 	Map<StringName,ShaderLanguage::Uniform> *uniforms;
 
@@ -79,7 +81,7 @@ private:
 
 	String replace_string(const StringName& p_string);
 
-	Map<StringName,StringName> mode_replace_table[3];
+	Map<StringName,StringName> mode_replace_table[9];
 	Map<StringName,StringName> replace_table;
 
 public:
@@ -101,6 +103,7 @@ public:
 		bool use_var2_interp;
 		bool uses_light;
 		bool uses_time;
+		bool uses_normal;
 	};
 
 	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);

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

@@ -18,19 +18,56 @@ attribute highp vec2 uv_attrib; // attrib:4
 varying vec2 uv_interp;
 varying vec4 color_interp;
 
+#if defined(USE_TIME)
+uniform float time;
+#endif
+
+
+#ifdef USE_LIGHTING
+
+uniform highp mat4 light_matrix;
+varying vec4 light_tex_pos;
+
+#endif
+
+#if defined(ENABLE_VAR1_INTERP)
+varying vec4 var1_interp;
+#endif
+
+#if defined(ENABLE_VAR2_INTERP)
+varying vec4 var2_interp;
+#endif
+
 //uniform bool snap_pixels;
 
+VERTEX_SHADER_GLOBALS
+
 void main() {
 
 	color_interp = color_attrib;
 	uv_interp = uv_attrib;		
 	highp vec4 outvec = vec4(vertex, 1.0);
+{
+	vec2 src_vtx=outvec.xy;
+VERTEX_SHADER_CODE
+
+}
 	outvec = extra_matrix * outvec;
 	outvec = modelview_matrix * outvec;
 #ifdef USE_PIXEL_SNAP
 
-		outvec.xy=floor(outvec.xy+0.5);
+	outvec.xy=floor(outvec.xy+0.5);
+#endif
+
+
+#ifdef USE_LIGHTING
+
+	light_tex_pos.xy = light_matrix * outvec;
+	light_tex_pos.zw=outvec.xy - light_matrix[4].xy; //likely wrong
+
 #endif
+
+
 	gl_Position = projection_matrix * outvec;
 }
 
@@ -54,17 +91,106 @@ varying vec4 color_interp;
 
 #endif
 
+#if defined(ENABLE_SCREEN_UV)
+
+uniform vec2 screen_uv_mult;
+
+#endif
+
+#if defined(ENABLE_TEXSCREEN)
+
+uniform vec2 texscreen_screen_mult;
+uniform sampler2D texscreen_tex;
+
+#endif
+
+
+#if defined(ENABLE_VAR1_INTERP)
+varying vec4 var1_interp;
+#endif
+
+#if defined(ENABLE_VAR2_INTERP)
+varying vec4 var2_interp;
+#endif
+
+#if defined(USE_TIME)
+uniform float time;
+#endif
+
+
+#ifdef USE_LIGHTING
+
+uniform sampler2D light_texture;
+varying vec4 light_tex_pos;
+
+#ifdef USE_SHADOWS
+
+uniform sampler2D shadow_texture;
+uniform float shadow_attenuation;
+
+#endif
+
+#endif
+
+FRAGMENT_SHADER_GLOBALS
+
+
 void main() {
 
 	vec4 color = color_interp;
-	
+#if defined(NORMAL_USED)
+	vec3 normal = vec3(0,0,1);
+#endif
+
 	color *= texture2D( texture,  uv_interp );
+#if defined(ENABLE_SCREEN_UV)
+	vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
+#endif
 
+{
+FRAGMENT_SHADER_CODE
+}
 #ifdef DEBUG_ENCODED_32
 	highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1)  );
 	color = vec4(vec3(enc32),1.0);
 #endif
 
+#ifdef USE_LIGHTING
+
+	float att=1.0;
+
+	vec3 light = texture2D(light_texture,light_tex_pos).rgb;
+#ifdef USE_SHADOWS
+	//this might not be that great on mobile?
+	float light_dist = length(light_texture.zw);
+	float light_angle = atan2(light_texture.x,light_texture.z) + 1.0 * 0.5;
+	float shadow_dist = texture2D(shadow_texture,vec2(light_angle,0));
+	if (light_dist>shadow_dist) {
+		light*=shadow_attenuation;
+	}
+//use shadows
+#endif
+
+#if defined(USE_LIGHT_SHADER_CODE)
+//light is written by the light shader
+{
+	vec2 light_dir = normalize(light_tex_pos.zw);
+	float light_distance = length(light_tex_pos.zw);
+LIGHT_SHADER_CODE
+}
+#else
+
+#if defined(NORMAL_USED)
+	vec2 light_normal = normalize(light_tex_pos.zw);
+	light = color.rgb * light * max(dot(light_normal,normal),0);
+#endif
+
+	color.rgb=light;
+//light shader code
+#endif
+
+//use lighting
+#endif
 //	color.rgb*=color.a;
 	gl_FragColor = color;
 

+ 1 - 1
platform/windows/os_windows.cpp

@@ -134,7 +134,7 @@ int OS_Windows::get_video_driver_count() const {
 }
 const char * OS_Windows::get_video_driver_name(int p_driver) const {
 
-	return p_driver=="GLES2";
+	return "GLES2";
 }
 
 OS::VideoMode OS_Windows::get_default_video_mode() const {

+ 85 - 1
scene/2d/canvas_item.cpp

@@ -720,6 +720,84 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{
 	return behind;
 }
 
+void CanvasItem::set_shader(const Ref<Shader>& p_shader) {
+
+	ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM);
+
+#ifdef TOOLS_ENABLED
+
+	if (shader.is_valid()) {
+		shader->disconnect("changed",this,"_shader_changed");
+	}
+#endif
+	shader=p_shader;
+
+#ifdef TOOLS_ENABLED
+
+	if (shader.is_valid()) {
+		shader->connect("changed",this,"_shader_changed");
+	}
+#endif
+
+	RID rid;
+	if (shader.is_valid())
+		rid=shader->get_rid();
+	VS::get_singleton()->canvas_item_set_shader(canvas_item,rid);
+	_change_notify(); //properties for shader exposed
+}
+
+Ref<Shader> CanvasItem::get_shader() const{
+
+	return shader;
+}
+
+void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) {
+
+	VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value);
+}
+
+Variant CanvasItem::get_shader_param(const StringName& p_param) const {
+
+	return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param);
+}
+
+bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) {
+
+	if (shader.is_valid()) {
+		StringName pr = shader->remap_param(p_name);
+		if (pr) {
+			set_shader_param(pr,p_value);
+			return true;
+		}
+	}
+	return false;
+}
+
+bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{
+
+	if (shader.is_valid()) {
+		StringName pr = shader->remap_param(p_name);
+		if (pr) {
+			r_ret=get_shader_param(pr);
+			return true;
+		}
+	}
+	return false;
+
+}
+void CanvasItem::_get_property_list( List<PropertyInfo> *p_list) const{
+
+	if (shader.is_valid()) {
+		shader->get_param_list(p_list);
+	}
+}
+
+#ifdef TOOLS_ENABLED
+void CanvasItem::_shader_changed() {
+
+	_change_notify();
+}
+#endif
 
 void CanvasItem::_bind_methods() {
 
@@ -761,7 +839,9 @@ void CanvasItem::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top);
 	ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
-
+#ifdef TOOLS_ENABLED
+	ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed);
+#endif
 	//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
 
 	ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0));
@@ -786,6 +866,9 @@ void CanvasItem::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d);
 	//ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport);
 
+	ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader);
+	ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader);
+
 	BIND_VMETHOD(MethodInfo("_draw"));
 
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/visible"), _SCS("_set_visible_"),_SCS("_is_visible_") );
@@ -795,6 +878,7 @@ void CanvasItem::_bind_methods() {
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
 
 	ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
+	ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") );
 	//exporting these two things doesn't really make much sense i think
 	//ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") );
 	//ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled"));

+ 13 - 2
scene/2d/canvas_item.h

@@ -32,6 +32,7 @@
 #include "scene/main/node.h"
 #include "scene/resources/texture.h"
 #include "scene/main/scene_main_loop.h"
+#include "scene/resources/shader.h"
 
 class CanvasLayer;
 class Viewport;
@@ -80,6 +81,8 @@ private:
 	bool block_transform_notify;
 	bool behind;
 
+	Ref<Shader> shader;
+
 	mutable Matrix32 global_transform;
 	mutable bool global_invalid;
 
@@ -99,8 +102,9 @@ private:
 	void _queue_sort_children();
 	void _sort_children();
 
-
-
+#ifdef TOOLS_ENABLED
+	void _shader_changed();
+#endif
 	void _notify_transform(CanvasItem *p_node);
 
 	void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
@@ -108,6 +112,9 @@ private:
 
 protected:
 
+	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;
 
 
 	_FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
@@ -204,7 +211,11 @@ public:
 	RID get_canvas() const;
 	Ref<World2D> get_world_2d() const;
 
+	void set_shader(const Ref<Shader>& p_shader);
+	Ref<Shader> get_shader() const;
 
+	void set_shader_param(const StringName& p_param,const Variant& p_value);
+	Variant get_shader_param(const StringName& p_param) const;
 
 	CanvasItem();
 	~CanvasItem();

+ 1 - 2
scene/register_scene_types.cpp

@@ -500,14 +500,13 @@ void register_scene_types() {
 	ObjectTypeDB::register_type<Mesh>();
 	ObjectTypeDB::register_virtual_type<Material>();
 	ObjectTypeDB::register_type<FixedMaterial>();
-	//ObjectTypeDB::register_type<ParticleSystemMaterial>();
-	//ObjectTypeDB::register_type<UnshadedMaterial>();
 	ObjectTypeDB::register_type<ShaderMaterial>();
 	ObjectTypeDB::register_type<RoomBounds>();
 	ObjectTypeDB::register_virtual_type<Shader>();
 	ObjectTypeDB::register_virtual_type<ShaderGraph>();
 	ObjectTypeDB::register_type<MaterialShaderGraph>();
 	ObjectTypeDB::register_type<MaterialShader>();
+	ObjectTypeDB::register_type<CanvasItemShader>();
 	ObjectTypeDB::add_compatibility_type("Shader","MaterialShader");
 	ObjectTypeDB::add_compatibility_type("ParticleSystemMaterial","FixedMaterial");
 	ObjectTypeDB::add_compatibility_type("UnshadedMaterial","FixedMaterial");

+ 21 - 120
scene/resources/material.cpp

@@ -467,10 +467,20 @@ bool ShaderMaterial::_set(const StringName& p_name, const Variant& p_value) {
 		return true;
 	} else {
 
-		String n = p_name;
-		if (n.begins_with("param/")) {
-			VisualServer::get_singleton()->material_set_param(material,String(n.ptr()+6),p_value);
-			return true;
+		if (shader.is_valid()) {
+
+
+			StringName pr = shader->remap_param(p_name);
+			if (!pr) {
+				String n = p_name;
+				if (n.find("param/")==0) { //backwards compatibility
+					pr = n.substr(6,n.length());
+				}
+			}
+			if (pr) {
+				VisualServer::get_singleton()->material_set_param(material,pr,p_value);
+				return true;
+			}
 		}
 	}
 
@@ -486,10 +496,13 @@ bool ShaderMaterial::_get(const StringName& p_name,Variant &r_ret) const {
 		return true;
 	} else {
 
-		String n = p_name;
-		if (n.begins_with("param/")) {
-			r_ret=VisualServer::get_singleton()->material_get_param(material,String(n.ptr()+6));
-			return true;
+		if (shader.is_valid()) {
+
+			StringName pr = shader->remap_param(p_name);
+			if (pr) {
+				r_ret=VisualServer::get_singleton()->material_get_param(material,pr);
+				return true;
+			}
 		}
 
 	}
@@ -583,115 +596,3 @@ ShaderMaterial::ShaderMaterial() :Material(VisualServer::get_singleton()->materi
 
 
 /////////////////////////////////
-
-void ParticleSystemMaterial::_bind_methods() {
-
-	ObjectTypeDB::bind_method(_MD("set_texture","texture"),&ParticleSystemMaterial::set_texture);
-	ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&ParticleSystemMaterial::get_texture);
-
-	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture" ), _SCS("set_texture"), _SCS("get_texture"));
-
-}
-
-void ParticleSystemMaterial::set_texture(const Ref<Texture>& p_texture) {
-	texture=p_texture;
-	RID rid;
-	if (texture.is_valid())
-		rid=texture->get_rid();
-
-	VS::get_singleton()->fixed_material_set_texture(material,VS::FIXED_MATERIAL_PARAM_DIFFUSE,rid);
-}
-
-Ref<Texture> ParticleSystemMaterial::get_texture() const {
-
-	return texture;
-}
-
-
-ParticleSystemMaterial::ParticleSystemMaterial() :Material(VisualServer::get_singleton()->fixed_material_create()){
-
-	set_flag(FLAG_DOUBLE_SIDED,true);
-	set_flag(FLAG_UNSHADED,true);
-	set_depth_draw_mode(DEPTH_DRAW_NEVER);
-	VisualServer::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
-	VisualServer::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
-	set_flag(FLAG_COLOR_ARRAY_SRGB,true);
-
-}
-
-ParticleSystemMaterial::~ParticleSystemMaterial() {
-
-
-}
-
-//////////////////////////////
-
-
-
-void UnshadedMaterial::_bind_methods() {
-
-	ObjectTypeDB::bind_method(_MD("set_texture","texture"),&UnshadedMaterial::set_texture);
-	ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&UnshadedMaterial::get_texture);
-
-	ObjectTypeDB::bind_method(_MD("set_use_alpha","enable"),&UnshadedMaterial::set_use_alpha);
-	ObjectTypeDB::bind_method(_MD("is_using_alpha"),&UnshadedMaterial::is_using_alpha);
-
-	ObjectTypeDB::bind_method(_MD("set_use_color_array","enable"),&UnshadedMaterial::set_use_color_array);
-	ObjectTypeDB::bind_method(_MD("is_using_color_array"),&UnshadedMaterial::is_using_color_array);
-
-	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture" ), _SCS("set_texture"), _SCS("get_texture"));
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "alpha" ), _SCS("set_use_alpha"), _SCS("is_using_alpha"));
-	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "color_array" ), _SCS("set_use_color_array"), _SCS("is_using_color_array"));
-
-}
-
-void UnshadedMaterial::set_texture(const Ref<Texture>& p_texture) {
-	RID rid;
-	if (texture.is_valid())
-		rid=texture->get_rid();
-
-	VS::get_singleton()->fixed_material_set_texture(material,VS::FIXED_MATERIAL_PARAM_DIFFUSE,rid);
-}
-Ref<Texture> UnshadedMaterial::get_texture() const {
-
-	return texture;
-}
-
-void UnshadedMaterial::set_use_alpha(bool p_use_alpha) {
-
-	alpha=p_use_alpha;
-	VS::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_ALPHA,p_use_alpha);
-	//set_depth_draw_mode();
-	//set_hint(HINT,p_use_alpha);
-
-}
-
-bool UnshadedMaterial::is_using_alpha() const{
-
-	return alpha;
-}
-
-void UnshadedMaterial::set_use_color_array(bool p_use_color_array){
-
-	color_array=p_use_color_array;
-	VS::get_singleton()->fixed_material_set_flag(material,VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,p_use_color_array);
-
-}
-
-bool UnshadedMaterial::is_using_color_array() const{
-
-	return color_array;
-}
-
-UnshadedMaterial::UnshadedMaterial() :Material(VisualServer::get_singleton()->fixed_material_create()){
-
-	set_flag(FLAG_UNSHADED,true);
-	set_use_alpha(true);
-	set_flag(FLAG_COLOR_ARRAY_SRGB,true);
-
-}
-
-UnshadedMaterial::~UnshadedMaterial() {
-
-
-}

+ 0 - 62
scene/resources/material.h

@@ -253,68 +253,6 @@ public:
 
 
 
-class ParticleSystemMaterial : public Material {
-
-	OBJ_TYPE( ParticleSystemMaterial, Material );
-	REVERSE_GET_PROPERTY_LIST
-
-private:
-
-
-
-	Ref<Texture> texture;
-
-protected:
-
-
-	static void _bind_methods();
-
-public:
-
-	void set_texture(const Ref<Texture>& p_texture);
-	Ref<Texture> get_texture() const;
-
-
-	ParticleSystemMaterial();
-	~ParticleSystemMaterial();
-
-};
-
-///////////////////////////////////////////
-
-
-class UnshadedMaterial : public Material {
-
-	OBJ_TYPE( UnshadedMaterial, Material );
-	REVERSE_GET_PROPERTY_LIST
-
-private:
-
-
-	bool alpha;
-	bool color_array;
-	Ref<Texture> texture;
-
-protected:
-
-
-	static void _bind_methods();
-
-public:
-
-	void set_texture(const Ref<Texture>& p_texture);
-	Ref<Texture> get_texture() const;
-
-	void set_use_alpha(bool p_use_alpha);
-	bool is_using_alpha() const;
-
-	void set_use_color_array(bool p_use_color_array);
-	bool is_using_color_array() const;
-
-	UnshadedMaterial();
-	~UnshadedMaterial();
-
-};
 
 
 #endif

+ 1 - 1
scene/resources/shader.cpp

@@ -84,7 +84,7 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
 	for(List<PropertyInfo>::Element *E=local.front();E;E=E->next()) {
 
 		PropertyInfo pi=E->get();
-		pi.name="param/"+pi.name;
+		pi.name="shader_param/"+pi.name;
 		params_cache[pi.name]=E->get().name;
 		if (p_params) {
 

+ 19 - 0
scene/resources/shader.h

@@ -80,6 +80,16 @@ public:
 	Ref<Texture> get_default_texture_param(const StringName& p_param) const;
 	void get_default_texture_param_list(List<StringName>* r_textures) const;
 
+	_FORCE_INLINE_ StringName remap_param(const StringName& p_param) const {
+		if (params_cache_dirty)
+			get_param_list(NULL);
+
+		const Map<StringName,StringName>::Element *E=params_cache.find(p_param);
+		if (E)
+			return E->get();
+		return StringName();
+	}
+
 	virtual RID get_rid() const;
 
 	Shader(Mode p_mode);
@@ -98,6 +108,15 @@ public:
 	MaterialShader() : Shader(MODE_MATERIAL) {};
 };
 
+class CanvasItemShader : public Shader {
+
+	OBJ_TYPE(CanvasItemShader,Shader);
+
+public:
+
+	CanvasItemShader() : Shader(MODE_CANVAS_ITEM) {};
+};
+
 
 
 class ResourceFormatLoaderShader : public ResourceFormatLoader {

+ 5 - 2
servers/visual/rasterizer.h

@@ -692,6 +692,9 @@ public:
 		mutable bool rect_dirty;
 		mutable Rect2 rect;
 		CanvasItem*next;
+		RID shader;
+		Map<StringName,Variant> shader_param;
+		uint32_t shader_version;
 
 
 		float final_opacity;
@@ -824,8 +827,8 @@ public:
 			return rect;
 		}
 
-		void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL;}
-		CanvasItem() { vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1;  blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; }
+		void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL;  }
+		CanvasItem() { vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1;  blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0;}
 		virtual ~CanvasItem() { clear(); }
 	};
 

+ 97 - 0
servers/visual/shader_language.cpp

@@ -1105,6 +1105,60 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::light_builtins_defs[]={
 
 };
 
+
+
+const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[]={
+
+	{ "SRC_VERTEX", TYPE_VEC2},
+	{ "VERTEX", TYPE_VEC2},
+	{ "UV", TYPE_VEC2},
+	{ "COLOR", TYPE_VEC4},
+	{ "VAR1", TYPE_VEC4},
+	{ "VAR2", TYPE_VEC4},
+	{ "POINT_SIZE", TYPE_FLOAT},
+
+	//builtins
+	{ "WORLD_MATRIX", TYPE_MAT4},
+	{ "PROJECTION_MATRIX", TYPE_MAT4},
+	{ "EXTRA_MATRIX", TYPE_MAT4},
+	{ "MODELVIEW_MATRIX", TYPE_MAT4},
+	{ "TIME", TYPE_FLOAT},
+	{ NULL, TYPE_VOID},
+};
+const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={
+
+	{ "POSITION", TYPE_VEC4},
+	{ "NORMAL", TYPE_VEC3},
+	{ "UV", TYPE_VEC2},
+	{ "COLOR", TYPE_VEC4},
+	{ "TEXTURE", TYPE_TEXTURE},
+	{ "VAR1", TYPE_VEC4},
+	{ "VAR2", TYPE_VEC4},
+	{ "SCREEN_UV", TYPE_VEC2},
+	{ "POINT_COORD", TYPE_VEC2},
+
+//	{ "SCREEN_POS", TYPE_VEC2},
+//	{ "SCREEN_TEXEL_SIZE", TYPE_VEC2},
+	{ "TIME", TYPE_FLOAT},
+	{ NULL, TYPE_VOID}
+
+};
+
+const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={
+
+	{ "COLOR", TYPE_VEC4},
+	{ "NORMAL", TYPE_VEC3},
+	{ "LIGHT_DIR", TYPE_VEC2},
+	{ "LIGHT_DISTANCE", TYPE_FLOAT},
+	{ "LIGHT", TYPE_VEC3},
+	{ "POINT_COORD", TYPE_VEC2},
+//	{ "SCREEN_POS", TYPE_VEC2},
+//	{ "SCREEN_TEXEL_SIZE", TYPE_VEC2},
+	{ "TIME", TYPE_FLOAT},
+	{ NULL, TYPE_VOID}
+
+};
+
 const ShaderLanguage::BuiltinsDef ShaderLanguage::postprocess_fragment_builtins_defs[]={
 
 	{ "IN_COLOR", TYPE_VEC3},
@@ -2471,6 +2525,27 @@ Error ShaderLanguage::parse(const Vector<Token>& p_tokens,ShaderType p_type,Comp
 				idx++;
 			}
 		} break;
+		case SHADER_CANVAS_ITEM_VERTEX: {
+			int idx=0;
+			while (ci_vertex_builtins_defs[idx].name) {
+				parser.program->builtin_variables[ci_vertex_builtins_defs[idx].name]=ci_vertex_builtins_defs[idx].type;
+				idx++;
+			}
+		} break;
+		case SHADER_CANVAS_ITEM_FRAGMENT: {
+			int idx=0;
+			while (ci_fragment_builtins_defs[idx].name) {
+				parser.program->builtin_variables[ci_fragment_builtins_defs[idx].name]=ci_fragment_builtins_defs[idx].type;
+				idx++;
+			}
+		} break;
+		case SHADER_CANVAS_ITEM_LIGHT: {
+			int idx=0;
+			while (ci_light_builtins_defs[idx].name) {
+				parser.program->builtin_variables[ci_light_builtins_defs[idx].name]=ci_light_builtins_defs[idx].type;
+				idx++;
+			}
+		} break;
 		case SHADER_POST_PROCESS: {
 			int idx=0;
 			while (postprocess_fragment_builtins_defs[idx].name) {
@@ -2568,6 +2643,28 @@ void ShaderLanguage::get_keyword_list(ShaderType p_type, List<String> *p_keyword
 				idx++;
 			}
 		} break;
+		case SHADER_CANVAS_ITEM_VERTEX: {
+			idx=0;
+			while (ci_vertex_builtins_defs[idx].name) {
+				p_keywords->push_back(ci_vertex_builtins_defs[idx].name);
+				idx++;
+			}
+		} break;
+		case SHADER_CANVAS_ITEM_FRAGMENT: {
+			idx=0;
+			while (ci_fragment_builtins_defs[idx].name) {
+				p_keywords->push_back(ci_fragment_builtins_defs[idx].name);
+				idx++;
+			}
+		} break;
+		case SHADER_CANVAS_ITEM_LIGHT: {
+			idx=0;
+			while (ci_light_builtins_defs[idx].name) {
+				p_keywords->push_back(ci_light_builtins_defs[idx].name);
+				idx++;
+			}
+		} break;
+
 		case SHADER_POST_PROCESS: {
 			idx=0;
 			while (postprocess_fragment_builtins_defs[idx].name) {

+ 9 - 0
servers/visual/shader_language.h

@@ -105,6 +105,9 @@ public:
 		SHADER_MATERIAL_VERTEX,
 		SHADER_MATERIAL_FRAGMENT,
 		SHADER_MATERIAL_LIGHT,
+		SHADER_CANVAS_ITEM_VERTEX,
+		SHADER_CANVAS_ITEM_FRAGMENT,
+		SHADER_CANVAS_ITEM_LIGHT,
 		SHADER_POST_PROCESS,
 	};
 
@@ -376,6 +379,12 @@ private:
 	static const BuiltinsDef vertex_builtins_defs[];
 	static const BuiltinsDef fragment_builtins_defs[];
 	static const BuiltinsDef light_builtins_defs[];
+
+	static const BuiltinsDef ci_vertex_builtins_defs[];
+	static const BuiltinsDef ci_fragment_builtins_defs[];
+	static const BuiltinsDef ci_light_builtins_defs[];
+
+
 	static const BuiltinsDef postprocess_fragment_builtins_defs[];
 
 	static DataType get_token_datatype(TokenType p_type);

+ 36 - 0
servers/visual/visual_server_raster.cpp

@@ -3699,6 +3699,42 @@ void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
 
 }
 
+void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) {
+
+	VS_CHANGED;
+	CanvasItem *canvas_item = canvas_item_owner.get( p_item );
+	ERR_FAIL_COND(!canvas_item);
+	canvas_item->shader=p_shader;
+}
+
+RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{
+
+	CanvasItem *canvas_item = canvas_item_owner.get( p_item );
+	ERR_FAIL_COND_V(!canvas_item,RID());
+	return canvas_item->shader;
+
+}
+
+void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){
+
+	VS_CHANGED;
+	CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
+	ERR_FAIL_COND(!canvas_item);
+	if (p_value.get_type()==Variant::NIL)
+		canvas_item->shader_param.erase(p_param);
+	else
+		canvas_item->shader_param[p_param]=p_value;
+
+}
+Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{
+
+	CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
+	ERR_FAIL_COND_V(!canvas_item,Variant());
+	ERR_FAIL_COND_V(!canvas_item->shader_param.has(p_param),Variant());
+
+	return canvas_item->shader_param[p_param];
+}
+
 
 void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
 

+ 5 - 0
servers/visual/visual_server_raster.h

@@ -1110,6 +1110,11 @@ public:
 	virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
 	virtual void canvas_item_set_z(RID p_item, int p_z);
 
+	virtual void canvas_item_set_shader(RID p_item, RID p_shader);
+	virtual RID canvas_item_get_shader(RID p_item) const;
+
+	virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value);
+	virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const;
 
 	virtual void canvas_item_clear(RID p_item);
 	virtual void canvas_item_raise(RID p_item);

+ 5 - 0
servers/visual/visual_server_wrap_mt.h

@@ -1133,6 +1133,11 @@ public:
 	FUNC2(canvas_item_set_sort_children_by_y,RID,bool);
 	FUNC2(canvas_item_set_z,RID,int);
 
+	FUNC2(canvas_item_set_shader,RID, RID );
+	FUNC1RC(RID,canvas_item_get_shader,RID );
+
+	FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&);
+	FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&);
 
 	FUNC1(canvas_item_clear,RID);
 	FUNC1(canvas_item_raise,RID);

+ 6 - 0
servers/visual_server.h

@@ -989,6 +989,12 @@ public:
 	virtual void canvas_item_clear(RID p_item)=0;
 	virtual void canvas_item_raise(RID p_item)=0;
 
+	virtual void canvas_item_set_shader(RID p_item, RID p_shader)=0;
+	virtual RID canvas_item_get_shader(RID p_item) const=0;
+
+	virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value)=0;
+	virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const=0;
+
 	/* CURSOR */
 	virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians
 	virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor=0)=0;

+ 2 - 1
tools/editor/editor_node.cpp

@@ -4036,7 +4036,8 @@ EditorNode::EditorNode() {
 	add_editor_plugin( memnew( EditorHelpPlugin(this) ) );
 	add_editor_plugin( memnew( AnimationPlayerEditorPlugin(this) ) );
 	add_editor_plugin( memnew( ShaderGraphEditorPlugin(this) ) );
-	add_editor_plugin( memnew( ShaderEditorPlugin(this) ) );
+	add_editor_plugin( memnew( ShaderEditorPlugin(this,true) ) );
+	add_editor_plugin( memnew( ShaderEditorPlugin(this,false) ) );
 	add_editor_plugin( memnew( CameraEditorPlugin(this) ) );
 	add_editor_plugin( memnew( SampleEditorPlugin(this) ) );
 	add_editor_plugin( memnew( SampleLibraryEditorPlugin(this) ) );

+ 6 - 0
tools/editor/editor_plugin.cpp

@@ -73,6 +73,12 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
 		} break;
 		case CONTAINER_CANVAS_EDITOR_SIDE: {
 
+			CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
+
+		} break;
+		case CONTAINER_CANVAS_EDITOR_BOTTOM: {
+
+			CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(p_control);
 
 		} break;
 

+ 2 - 1
tools/editor/editor_plugin.h

@@ -66,7 +66,8 @@ public:
 		CONTAINER_SPATIAL_EDITOR_SIDE,
 		CONTAINER_SPATIAL_EDITOR_BOTTOM,
 		CONTAINER_CANVAS_EDITOR_MENU,
-		CONTAINER_CANVAS_EDITOR_SIDE
+		CONTAINER_CANVAS_EDITOR_SIDE,
+		CONTAINER_CANVAS_EDITOR_BOTTOM
 	};
 
 	//TODO: send a resoucre for editing to the editor node?

+ 10 - 1
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -2688,6 +2688,11 @@ HSplitContainer *CanvasItemEditor::get_palette_split() {
 	return palette_split;
 }
 
+VSplitContainer *CanvasItemEditor::get_bottom_split() {
+
+	return bottom_split;
+}
+
 CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 
 	tool = TOOL_SELECT;
@@ -2702,9 +2707,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 	add_child( hb );
 	hb->set_area_as_parent_rect();
 
+	bottom_split = memnew( VSplitContainer );
+	bottom_split->set_v_size_flags(SIZE_EXPAND_FILL);
+	add_child(bottom_split);
+
 	palette_split = memnew( HSplitContainer);
 	palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
-	add_child(palette_split);
+	bottom_split->add_child(palette_split);
 
 	Control *vp_base = memnew (Control);
 	vp_base->set_v_size_flags(SIZE_EXPAND_FILL);

+ 2 - 1
tools/editor/plugins/canvas_item_editor_plugin.h

@@ -290,8 +290,8 @@ class CanvasItemEditor : public VBoxContainer {
 	void _viewport_input_event(const InputEvent& p_event);
 	void _viewport_draw();
 
-private:
 	HSplitContainer *palette_split;
+	VSplitContainer *bottom_split;
 
 friend class CanvasItemEditorPlugin;
 protected:
@@ -346,6 +346,7 @@ public:
 	void add_control_to_menu_panel(Control *p_control);
 
 	HSplitContainer *get_palette_split();
+	VSplitContainer *get_bottom_split();
 
 	Control *get_viewport_control() { return viewport; }
 

+ 23 - 47
tools/editor/plugins/shader_editor_plugin.cpp

@@ -57,9 +57,9 @@ void ShaderTextEditor::set_edited_shader(const Ref<Shader>& p_shader,ShaderLangu
 
 	_load_theme_settings();
 
-	if (p_type==ShaderLanguage::SHADER_MATERIAL_LIGHT)
+	if (p_type==ShaderLanguage::SHADER_MATERIAL_LIGHT || p_type==ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT)
 		get_text_edit()->set_text(shader->get_light_code());
-	else if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX)
+	else if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX || p_type==ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX)
 		get_text_edit()->set_text(shader->get_vertex_code());
 	else
 		get_text_edit()->set_text(shader->get_fragment_code());
@@ -131,17 +131,12 @@ void ShaderTextEditor::_validate_script() {
 	String errortxt;
 	int line,col;
 
-	String code;
-	if (type==ShaderLanguage::SHADER_MATERIAL_LIGHT)
-		code=get_text_edit()->get_text();
-	else if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX)
-		code=get_text_edit()->get_text();
-	else
-		code=get_text_edit()->get_text();
-
+	String code=get_text_edit()->get_text();
 	//List<StringName> params;
 	//shader->get_param_list(&params);
 
+	print_line("compile: type: "+itos(type)+" code:\n"+code);
+
 	Error err = ShaderLanguage::compile(code,type,NULL,NULL,&errortxt,&line,&col);
 
 	if (err!=OK) {
@@ -233,25 +228,7 @@ void ShaderEditor::_menu_option(int p_option) {
 
 			goto_line_dialog->popup_find_line(current->get_text_edit());
 		} break;
-		case SHADER_POST_PROCESS_MODE:{
-
-			fragment_editor->set_edited_shader(shader,ShaderLanguage::SHADER_POST_PROCESS);
-			fragment_editor->_validate_script();
-			apply_shaders();
-			settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), false);
-			settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), true);
-
-
-		} break;
-		case SHADER_MATERIAL_MODE: {
 
-			fragment_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_FRAGMENT);
-			fragment_editor->_validate_script();
-			apply_shaders();
-			settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), true);
-			settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), false);
-
-		} break;
 	}
 }
 
@@ -408,15 +385,14 @@ void ShaderEditor::edit(const Ref<Shader>& p_shader) {
 	shader=p_shader;
 
 	if (shader->get_mode()==Shader::MODE_MATERIAL) {
+		vertex_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_MATERIAL_VERTEX);
 		fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_MATERIAL_FRAGMENT);
 		light_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_LIGHT);
-		settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), true);
-		settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), false);
-	} else {
+	} else if (shader->get_mode()==Shader::MODE_CANVAS_ITEM) {
 
-		fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_POST_PROCESS);
-		settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), false);
-		settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), true);
+		vertex_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX);
+		fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT);
+		light_editor->set_edited_shader(shader,ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT);
 	}
 
 	vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX);
@@ -495,15 +471,6 @@ ShaderEditor::ShaderEditor() {
 	search_menu->get_popup()->add_item("Goto Line..",SEARCH_GOTO_LINE,KEY_MASK_CMD|KEY_G);
 	search_menu->get_popup()->connect("item_pressed", this,"_menu_option");
 
-	settings_menu = memnew( MenuButton );
-	add_child(settings_menu);
-	settings_menu->set_pos(Point2(90,-1));
-	settings_menu->set_text("Shader");
-	settings_menu->get_popup()->add_check_item("Material Mode",SHADER_MATERIAL_MODE);
-	settings_menu->get_popup()->set_item_checked(settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE),true);
-	settings_menu->get_popup()->add_check_item("Post Process Mode",SHADER_POST_PROCESS_MODE);
-
-	settings_menu->get_popup()->connect("item_pressed", this,"_menu_option");
 
 	tab_container->connect("tab_changed", this,"_tab_changed");
 
@@ -550,7 +517,13 @@ void ShaderEditorPlugin::edit(Object *p_object) {
 
 bool ShaderEditorPlugin::handles(Object *p_object) const {
 
-	return p_object->is_type("Shader");
+	Shader *shader=p_object->cast_to<Shader>();
+	if (!shader)
+		return false;
+	if (_2d)
+		return shader->get_mode()==Shader::MODE_CANVAS_ITEM;
+	else
+		return shader->get_mode()==Shader::MODE_MATERIAL;
 }
 
 void ShaderEditorPlugin::make_visible(bool p_visible) {
@@ -596,12 +569,15 @@ void ShaderEditorPlugin::apply_changes() {
 	shader_editor->apply_shaders();
 }
 
-ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) {
+ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node, bool p_2d) {
 
 	editor=p_node;
 	shader_editor = memnew( ShaderEditor );
-
-	SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor);
+	_2d=p_2d;
+	if (p_2d)
+		add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor);
+	else
+		add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor);
 //	editor->get_viewport()->add_child(shader_editor);
 //	shader_editor->set_area_as_parent_rect();
 

+ 2 - 4
tools/editor/plugins/shader_editor_plugin.h

@@ -79,9 +79,6 @@ class ShaderEditor : public Control {
 		SEARCH_REPLACE,
 		//SEARCH_LOCATE_SYMBOL,
 		SEARCH_GOTO_LINE,
-		SHADER_MATERIAL_MODE,
-		SHADER_POST_PROCESS_MODE,
-		SHADER_SHADE_MODEL_MODE,
 
 	};
 
@@ -134,6 +131,7 @@ class ShaderEditorPlugin : public EditorPlugin {
 
 	OBJ_TYPE( ShaderEditorPlugin, EditorPlugin );
 
+	bool _2d;
 	ShaderEditor *shader_editor;
 	EditorNode *editor;
 public:
@@ -152,7 +150,7 @@ public:
 	virtual void save_external_data();
 	virtual void apply_changes();
 
-	ShaderEditorPlugin(EditorNode *p_node);
+	ShaderEditorPlugin(EditorNode *p_node,bool p_2d);
 	~ShaderEditorPlugin();
 
 };