Ver código fonte

Merge remote-tracking branch 'upstream/master'

Maximillian 10 anos atrás
pai
commit
5c5519e2c8
40 arquivos alterados com 398 adições e 153 exclusões
  1. 27 29
      drivers/gles2/rasterizer_gles2.cpp
  2. 2 1
      drivers/gles2/rasterizer_gles2.h
  3. 50 0
      scene/gui/graph_edit.cpp
  4. 4 0
      scene/gui/graph_edit.h
  5. 5 2
      scene/resources/shader.cpp
  6. 213 73
      scene/resources/shader_graph.cpp
  7. 5 1
      scene/resources/shader_graph.h
  8. BIN
      tools/editor/icons/icon_graph_comment.png
  9. BIN
      tools/editor/icons/icon_graph_cube_uniform.png
  10. BIN
      tools/editor/icons/icon_graph_input.png
  11. BIN
      tools/editor/icons/icon_graph_rgb.png
  12. BIN
      tools/editor/icons/icon_graph_rgb_op.png
  13. BIN
      tools/editor/icons/icon_graph_rgb_uniform.png
  14. BIN
      tools/editor/icons/icon_graph_scalar.png
  15. BIN
      tools/editor/icons/icon_graph_scalar_interp.png
  16. BIN
      tools/editor/icons/icon_graph_scalar_op.png
  17. BIN
      tools/editor/icons/icon_graph_scalar_uniform.png
  18. BIN
      tools/editor/icons/icon_graph_scalars_to_vec.png
  19. BIN
      tools/editor/icons/icon_graph_texscreen.png
  20. BIN
      tools/editor/icons/icon_graph_texture_uniform.png
  21. BIN
      tools/editor/icons/icon_graph_time.png
  22. BIN
      tools/editor/icons/icon_graph_vec_dp.png
  23. BIN
      tools/editor/icons/icon_graph_vec_interp.png
  24. BIN
      tools/editor/icons/icon_graph_vec_length.png
  25. BIN
      tools/editor/icons/icon_graph_vec_op.png
  26. BIN
      tools/editor/icons/icon_graph_vec_scalar_op.png
  27. BIN
      tools/editor/icons/icon_graph_vec_to_scalars.png
  28. BIN
      tools/editor/icons/icon_graph_vecs_to_xform.png
  29. BIN
      tools/editor/icons/icon_graph_vector.png
  30. BIN
      tools/editor/icons/icon_graph_vector_uniform.png
  31. BIN
      tools/editor/icons/icon_graph_xform.png
  32. BIN
      tools/editor/icons/icon_graph_xform_mult.png
  33. BIN
      tools/editor/icons/icon_graph_xform_scalar_func.png
  34. BIN
      tools/editor/icons/icon_graph_xform_to_vecs.png
  35. BIN
      tools/editor/icons/icon_graph_xform_uniform.png
  36. BIN
      tools/editor/icons/icon_graph_xform_vec_func.png
  37. BIN
      tools/editor/icons/icon_graph_xform_vec_imult.png
  38. BIN
      tools/editor/icons/icon_graph_xform_vec_mult.png
  39. 90 47
      tools/editor/plugins/shader_graph_editor_plugin.cpp
  40. 2 0
      tools/editor/plugins/shader_graph_editor_plugin.h

+ 27 - 29
drivers/gles2/rasterizer_gles2.cpp

@@ -1545,13 +1545,15 @@ void RasterizerGLES2::shader_set_default_texture_param(RID p_shader, const Strin
 
 	Shader *shader=shader_owner.get(p_shader);
 	ERR_FAIL_COND(!shader);
-	ERR_FAIL_COND(!texture_owner.owns(p_texture));
+	ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture));
 
 	if (p_texture.is_valid())
 		shader->default_textures[p_name]=p_texture;
 	else
 		shader->default_textures.erase(p_name);
 
+	_shader_make_dirty(shader);
+
 }
 
 RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
@@ -1606,6 +1608,7 @@ void RasterizerGLES2::material_set_param(RID p_material, const StringName& p_par
 			material->shader_version=0; //get default!
 		} else {
 			E->get().value=p_value;
+			E->get().inuse=true;
 		}
 	} else {
 
@@ -1613,6 +1616,7 @@ void RasterizerGLES2::material_set_param(RID p_material, const StringName& p_par
 		ud.index=-1;
 		ud.value=p_value;
 		ud.istexture=p_value.get_type()==Variant::_RID; /// cache it being texture
+		ud.inuse=true;
 		material->shader_params[p_param]=ud; //may be got at some point, or erased
 
 	}
@@ -1644,7 +1648,7 @@ Variant RasterizerGLES2::material_get_param(RID p_material, const StringName& p_
 	}
 
 
-	if (material->shader_params.has(p_param))
+	if (material->shader_params.has(p_param) && material->shader_params[p_param].inuse)
 		return material->shader_params[p_param].value;
 	else
 		return Variant();
@@ -4876,31 +4880,46 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_
 
 		Material::UniformData ud;
 
-		bool keep=true;
+		bool keep=true; //keep material value
+		bool has_old = old_mparams.has(E->key());
+		bool old_inuse=has_old && old_mparams[E->key()].inuse;
 
-		if (!old_mparams.has(E->key()))
+		if (!has_old || !old_inuse)
 			keep=false;
 		else if (old_mparams[E->key()].value.get_type()!=E->value().default_value.get_type()) {
-
-			if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) {
+			//type changed between old and new
+			/*if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) {
 				if (E->value().default_value.get_type()!=Variant::_RID) //hackfor textures
 					keep=false;
 			} else if (!old_mparams[E->key()].value.is_num() || !E->value().default_value.get_type())
+				keep=false;*/
+
+			//value is invalid because type differs and default is not null
+			if (E->value().default_value.get_type()!=Variant::NIL)
 				keep=false;
 		}
 
+		ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP);
+
 		if (keep) {
 			ud.value=old_mparams[E->key()].value;
+
 			//print_line("KEEP: "+String(E->key()));
 		} else {
-			ud.value=E->value().default_value;
+			if (ud.istexture && p_material->shader_cache->default_textures.has(E->key()))
+				ud.value=p_material->shader_cache->default_textures[E->key()];
+			else
+				ud.value=E->value().default_value;
+			old_inuse=false; //if reverted to default, obviously did not work
+
 			//print_line("NEW: "+String(E->key())+" because: hasold-"+itos(old_mparams.has(E->key())));
 			//if (old_mparams.has(E->key()))
 			//	print_line(" told "+Variant::get_type_name(old_mparams[E->key()].value.get_type())+" tnew "+Variant::get_type_name(E->value().default_value.get_type()));
 		}
 
-		ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP);
+
 		ud.index=idx++;
+		ud.inuse=old_inuse;
 		mparams[E->key()]=ud;
 	}
 
@@ -5021,23 +5040,8 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
 						E->get().value=RID(); //nullify, invalid texture
 						rid=RID();
 					}
-				} else {
-
-
-				}
-
-				if (!rid.is_valid()) {
-					//use from default textures
-					Map<StringName,RID>::Element *F=p_material->shader_cache->default_textures.find(E->key());
-					if (F) {
-						t=texture_owner.get(F->get());
-						if (!t) {
-							p_material->shader_cache->default_textures.erase(E->key());
-						}
-					}
 				}
 
-
 				glActiveTexture(GL_TEXTURE0+texcoord);
 				glUniform1i(loc,texcoord); //TODO - this could happen automatically on compile...
 				if (t) {
@@ -5061,12 +5065,6 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
 
 		}
 
-		for (Map<StringName,RID>::Element *E=p_material->shader_cache->default_textures.front();E;E=E->next()) {
-			if (p_material->shader_params.has(E->key()))
-				continue;
-
-
-		}
 
 		if (p_material->shader_cache->has_texscreen && framebuffer.active) {
 			material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));

+ 2 - 1
drivers/gles2/rasterizer_gles2.h

@@ -241,8 +241,9 @@ class RasterizerGLES2 : public Rasterizer {
 
 		struct UniformData {
 
+			bool inuse;
 			bool istexture;
-			Variant value;
+			Variant value;			
 			int index;
 		};
 

+ 50 - 0
scene/gui/graph_edit.cpp

@@ -265,6 +265,37 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) {
 				Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos();
 
 				if (pos.distance_to(mpos)<grab_r) {
+
+					if (right_disconnects) {
+						//check disconnect
+						for (List<Connection>::Element*E=connections.front();E;E=E->next()) {
+
+							if (E->get().to==gn->get_name() && E->get().to_port==j) {
+
+								Node*fr = get_node(String(E->get().from));
+								if (fr && fr->cast_to<GraphNode>()) {
+
+									connecting_from=E->get().from;
+									connecting_index=E->get().from_port;
+									connecting_out=true;
+									connecting_type=fr->cast_to<GraphNode>()->get_connection_output_type(E->get().from_port);
+									connecting_color=fr->cast_to<GraphNode>()->get_connection_output_color(E->get().from_port);
+									connecting_target=false;
+									connecting_to=pos;
+
+									emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port);
+									fr = get_node(String(connecting_from)); //maybe it was erased
+									if (fr && fr->cast_to<GraphNode>()) {
+										connecting=true;
+									}
+									return;
+								}
+
+							}
+						}
+					}
+
+
 					connecting=true;
 					connecting_from=gn->get_name();
 					connecting_index=j;
@@ -474,11 +505,26 @@ void GraphEdit::clear_connections() {
 }
 
 
+void GraphEdit::set_right_disconnects(bool p_enable) {
+
+	right_disconnects=p_enable;
+}
+
+bool GraphEdit::is_right_disconnects_enabled() const{
+
+	return right_disconnects;
+}
+
+
 void GraphEdit::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node);
 	ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected);
 	ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node);
+
+	ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects);
+	ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled);
+
 	ObjectTypeDB::bind_method(_MD("_graph_node_moved"),&GraphEdit::_graph_node_moved);
 	ObjectTypeDB::bind_method(_MD("_graph_node_raised"),&GraphEdit::_graph_node_raised);
 
@@ -489,9 +535,12 @@ void GraphEdit::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event);
 
 	ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot")));
+	ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot")));
 
 }
 
+
+
 GraphEdit::GraphEdit() {
 	top_layer=NULL;
 	top_layer=memnew(GraphEditFilter(this));
@@ -511,6 +560,7 @@ GraphEdit::GraphEdit() {
 	top_layer->add_child(v_scroll);
 	updating=false;
 	connecting=false;
+	right_disconnects=false;
 
 	h_scroll->connect("value_changed", this,"_scroll_moved");
 	v_scroll->connect("value_changed", this,"_scroll_moved");

+ 4 - 0
scene/gui/graph_edit.h

@@ -51,6 +51,7 @@ private:
 
 
 
+	bool right_disconnects;
 	bool updating;
 	List<Connection> connections;
 
@@ -86,6 +87,9 @@ public:
 
 	void get_connection_list(List<Connection> *r_connections);
 
+	void set_right_disconnects(bool p_enable);
+	bool is_right_disconnects_enabled() const;
+
 
 	GraphEdit();
 };

+ 5 - 2
scene/resources/shader.cpp

@@ -144,10 +144,13 @@ void Shader::_set_code(const Dictionary& p_string) {
 
 void Shader::set_default_texture_param(const StringName& p_param,const Ref<Texture>& p_texture) {
 
-	if (p_texture.is_valid())
+	if (p_texture.is_valid()) {
 		default_textures[p_param]=p_texture;
-	else
+		VS::get_singleton()->shader_set_default_texture_param(shader,p_param,p_texture->get_rid());
+	} else {
 		default_textures.erase(p_param);
+		VS::get_singleton()->shader_set_default_texture_param(shader,p_param,RID());
+	}
 }
 
 Ref<Texture> Shader::get_default_texture_param(const StringName& p_param) const{

+ 213 - 73
scene/resources/shader_graph.cpp

@@ -57,6 +57,84 @@ Array ShaderGraph::_get_connections(ShaderType p_type) const {
 	return arr;
 }
 
+void ShaderGraph::_set_data(const Dictionary &p_data) {
+
+	Dictionary d=p_data;
+	ERR_FAIL_COND(!d.has("shaders"));
+	Array sh=d["shaders"];
+	ERR_FAIL_COND(sh.size()!=3);
+
+	for(int t=0;t<3;t++) {
+		Array data=sh[t];
+		ERR_FAIL_COND((data.size()%6)!=0);
+		shader[t].node_map.clear();
+		for(int i=0;i<data.size();i+=6) {
+
+			Node n;
+			n.id=data[i+0];
+			n.type=NodeType(int(data[i+1]));
+			n.pos=data[i+2];
+			n.param1=data[i+3];
+			n.param2=data[i+4];
+
+			Array conns=data[i+5];
+			ERR_FAIL_COND((conns.size()%3)!=0);
+
+			for(int j=0;j<conns.size();j+=3) {
+
+				SourceSlot ss;
+				int ls=conns[j+0];
+				ss.id=conns[j+1];
+				ss.slot=conns[j+2];
+				n.connections[ls]=ss;
+			}
+			shader[t].node_map[n.id]=n;
+
+		}
+	}
+
+	_update_shader();
+
+}
+
+Dictionary ShaderGraph::_get_data() const {
+
+	Array sh;
+	for(int i=0;i<3;i++) {
+		Array data;
+		int ec = shader[i].node_map.size();
+		data.resize(ec*6);
+		int idx=0;
+		for (Map<int,Node>::Element*E=shader[i].node_map.front();E;E=E->next()) {
+
+			data[idx+0]=E->key();
+			data[idx+1]=E->get().type;
+			data[idx+2]=E->get().pos;
+			data[idx+3]=E->get().param1;
+			data[idx+4]=E->get().param2;
+
+			Array conns;
+			conns.resize(E->get().connections.size()*3);
+			int idx2=0;
+			for(Map<int,SourceSlot>::Element*F=E->get().connections.front();F;F=F->next()) {
+
+				conns[idx2+0]=F->key();
+				conns[idx2+1]=F->get().id;
+				conns[idx2+2]=F->get().slot;
+				idx2+=3;
+			}
+			data[idx+5]=conns;
+			idx+=6;
+		}
+		sh.push_back(data);
+	}
+
+	Dictionary data;
+	data["shaders"]=sh;
+	return data;
+}
+
+
 void ShaderGraph::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader);
@@ -147,6 +225,11 @@ void ShaderGraph::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("node_set_state","shader_type","id","state"),&ShaderGraph::node_set_state);
 	ObjectTypeDB::bind_method(_MD("node_get_state:var","shader_type","id"),&ShaderGraph::node_get_state);
 
+	ObjectTypeDB::bind_method(_MD("_set_data"),&ShaderGraph::_set_data);
+	ObjectTypeDB::bind_method(_MD("_get_data"),&ShaderGraph::_get_data);
+
+	ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR), _SCS("_set_data"),_SCS("_get_data"));
+
 	//void get_connections(ShaderType p_which,List<Connection> *p_connections) const;
 
 
@@ -347,7 +430,7 @@ void ShaderGraph::_bind_methods() {
 }
 
 
-String ShaderGraph::_find_unique_name(ShaderType p_which, const String& p_base) {
+String ShaderGraph::_find_unique_name(const String& p_base) {
 
 
 
@@ -358,15 +441,19 @@ String ShaderGraph::_find_unique_name(ShaderType p_which, const String& p_base)
 			tocmp+="_"+itos(idx);
 		}
 		bool valid=true;
-		for (Map<int,Node>::Element *E=shader[p_which].node_map.front();E;E=E->next()) {
-			if (E->get().type!=NODE_SCALAR_INPUT && E->get().type!=NODE_VEC_INPUT && E->get().type==NODE_RGB_INPUT && E->get().type==NODE_XFORM_INPUT && E->get().type==NODE_TEXTURE_INPUT && E->get().type==NODE_CUBEMAP_INPUT)
-				continue;
-			String name = E->get().param1;
-			if (name==tocmp) {
-				valid=false;
+		for(int i=0;i<3;i++) {
+			if (!valid)
 				break;
-			}
+			for (Map<int,Node>::Element *E=shader[i].node_map.front();E;E=E->next()) {
+				if (E->get().type!=NODE_SCALAR_INPUT && E->get().type!=NODE_VEC_INPUT && E->get().type==NODE_RGB_INPUT && E->get().type==NODE_XFORM_INPUT && E->get().type==NODE_TEXTURE_INPUT && E->get().type==NODE_CUBEMAP_INPUT)
+					continue;
+				String name = E->get().param1;
+				if (name==tocmp) {
+					valid=false;
+					break;
+				}
 
+			}
 		}
 
 		if (!valid) {
@@ -424,12 +511,12 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) {
 		case NODE_XFORM_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output
 		case NODE_SCALAR_INTERP: {} break; // scalar interpolation (with optional curve)
 		case NODE_VEC_INTERP: {} break; // vec3 interpolation  (with optional curve)
-		case NODE_SCALAR_INPUT: {node.param1=_find_unique_name(p_type,"Scalar"); node.param2=0;} break; // scalar uniform (assignable in material)
-		case NODE_VEC_INPUT: {node.param1=_find_unique_name(p_type,"Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material)
-		case NODE_RGB_INPUT: {node.param1=_find_unique_name(p_type,"Color");node.param2=Color();} break; // color uniform (assignable in material)
-		case NODE_XFORM_INPUT: {node.param1=_find_unique_name(p_type,"XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material)
-		case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name(p_type,"Tex"); } break; // texture input (assignable in material)
-		case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name(p_type,"Cube"); } break; // cubemap input (assignable in material)
+		case NODE_SCALAR_INPUT: {node.param1=_find_unique_name("Scalar"); node.param2=0;} break; // scalar uniform (assignable in material)
+		case NODE_VEC_INPUT: {node.param1=_find_unique_name("Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material)
+		case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material)
+		case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material)
+		case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material)
+		case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material)
 		case NODE_OUTPUT: {} break; // output (shader type dependent)
 		case NODE_COMMENT: {} break; // comment
 		case NODE_TYPE_MAX: {};
@@ -881,8 +968,9 @@ void ShaderGraph::input_node_set_name(ShaderType p_type,int p_id,const String& p
 	ERR_FAIL_COND(!p_name.is_valid_identifier());
 	Node& n = shader[p_type].node_map[p_id];
 	ERR_FAIL_COND(n.type!=NODE_SCALAR_INPUT && n.type!=NODE_VEC_INPUT && n.type==NODE_RGB_INPUT && n.type==NODE_XFORM_INPUT && n.type==NODE_TEXTURE_INPUT && n.type==NODE_CUBEMAP_INPUT);
+
 	n.param1="";
-	n.param1=_find_unique_name(p_type,p_name);
+	n.param1=_find_unique_name(p_name);
 	_request_update();
 
 }
@@ -1097,59 +1185,74 @@ ShaderGraph::~ShaderGraph() {
 
 const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
 	//material vertex in
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","SRC_VERTEX",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","SRC_NORMAL",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","SRC_TANGENT",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"BinormalF","SRC_BINORMALF",SLOT_TYPE_SCALAR,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"WorldMatrix","WORLD_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"InvCameraMatrix","INV_CAMERA_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"ProjectionMatrix","PROJECTION_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"ModelviewMatrix","MODELVIEW_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"InstanceID","INSTANCE_ID",SLOT_TYPE_SCALAR,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Time","TIME",SLOT_TYPE_SCALAR,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","SRC_VERTEX","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","SRC_NORMAL","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","SRC_TANGENT","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"BinormalF","SRC_BINORMALF","",SLOT_TYPE_SCALAR,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","SRC_COLOR","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","SRC_ALPHA","",SLOT_TYPE_SCALAR,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","SRC_UV","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","SRC_UV2","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"WorldMatrix","WORLD_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"InvCameraMatrix","INV_CAMERA_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"ProjectionMatrix","PROJECTION_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"ModelviewMatrix","MODELVIEW_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"InstanceID","INSTANCE_ID","",SLOT_TYPE_SCALAR,SLOT_IN},
+
 	//material vertex out
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","VERTEX",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","NORMAL",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","TANGENT",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Binormal","BINORMAL",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","UV",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","UV2",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","COLOR.rgb",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","COLOR.a",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var1","VAR1.rgb",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var2","VAR2.rgb",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"SpecExp","SPEC_EXP",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"PointSize","POINT_SIZE",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Vertex","VERTEX","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Tangent","TANGENT","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Binormal","BINORMAL","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV","UV",".xy",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"UV2","UV2",".xy",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"SpecExp","SPEC_EXP","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_VERTEX,"PointSize","POINT_SIZE","",SLOT_TYPE_SCALAR,SLOT_OUT},
 	//pixel vertex in
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Vertex","VERTEX",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Position","POSITION",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","IN_NORMAL",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Tangent","TANGENT",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Binormal","BINORMAL",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV","UV",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV2","UV2",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UVScreen","SCREEN_UV",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"PointCoord","POINT_COORD",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Color","COLOR.rgb",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Alpha","COLOR.a",SLOT_TYPE_SCALAR,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"InvCameraMatrix","INV_CAMERA_MATRIX",SLOT_TYPE_XFORM,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Time","TIME",SLOT_TYPE_SCALAR,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var1","VAR1.rgb",SLOT_TYPE_VEC,SLOT_IN},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var2","VAR2.rgb",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Vertex","VERTEX","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Position","POSITION","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","IN_NORMAL","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Tangent","TANGENT","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Binormal","BINORMAL","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV","vec3(UV,0);","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UV2","UV2","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"UVScreen","SCREEN_UV","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"PointCoord","POINT_COORD","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Color","COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Alpha","COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"InvCameraMatrix","INV_CAMERA_MATRIX","",SLOT_TYPE_XFORM,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_IN},
 	//pixel vertex out
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Diffuse","DIFFUSE_OUT",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"DiffuseAlpha","ALPHA_OUT",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Specular","SPECULAR",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"SpecularExp","SPECULAR",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Emission","EMISSION",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Glow","GLOW",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"ShadeParam","SHADE_PARAM",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","NORMAL",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMap","NORMALMAP",SLOT_TYPE_VEC,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMapDepth","NORMALMAP_DEPTH",SLOT_TYPE_SCALAR,SLOT_OUT},
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Discard","DISCARD",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Diffuse","DIFFUSE_OUT","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"DiffuseAlpha","ALPHA_OUT","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Specular","SPECULAR","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"SpecularExp","SPECULAR","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Emission","EMISSION","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Glow","GLOW","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"ShadeParam","SHADE_PARAM","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMap","NORMALMAP","",SLOT_TYPE_VEC,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"NormalMapDepth","NORMALMAP_DEPTH","",SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,"Discard","DISCARD",">0.5",SLOT_TYPE_SCALAR,SLOT_OUT},
+	//light in
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"Normal","NORMAL","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightDir","LIGHT_DIR","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightDiffuse","LIGHT_DIFFUSE","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"LightSpecular","LIGHT_SPECULAR","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"EyeVec","EYE_VEC","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"Diffuse","DIFFUSE","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"Specular","SPECULAR","",SLOT_TYPE_VEC,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"SpecExp","SPECULAR_EXP","",SLOT_TYPE_SCALAR,SLOT_IN},
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"ShadeParam","SHADE_PARAM","",SLOT_TYPE_SCALAR,SLOT_IN},
+	//light out
+	{MODE_MATERIAL,SHADER_TYPE_LIGHT,"Light","LIGHT","",SLOT_TYPE_VEC,SLOT_OUT},
 	//end
-	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,NULL,NULL,SLOT_TYPE_SCALAR,SLOT_OUT},
+	{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,NULL,NULL,NULL,SLOT_TYPE_SCALAR,SLOT_OUT},
 
 };
 
@@ -1174,7 +1277,7 @@ const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= {
 
 		{NODE_SCALAR_CONST,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, //scalar constant
 		{NODE_VEC_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, //vec3 constant
-		{NODE_RGB_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, //rgb constant (shows a color picker instead)
+		{NODE_RGB_CONST,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, //rgb constant (shows a color picker instead)
 		{NODE_XFORM_CONST,{SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // 4x4 matrix constant
 		{NODE_TIME,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // time in seconds
 		{NODE_SCREEN_TEX,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // screen texture sampler (takes UV) (only usable in fragment shader)
@@ -1381,6 +1484,14 @@ void ShaderGraph::_update_shader() {
 
 	String code[3];
 
+	List<StringName> names;
+	get_default_texture_param_list(&names);
+
+	for (List<StringName>::Element *E=names.front();E;E=E->next()) {
+		set_default_texture_param(E->get(),Ref<Texture>());
+	}
+
+
 	for(int i=0;i<3;i++) {
 
 		int idx=0;
@@ -1437,11 +1548,13 @@ void ShaderGraph::_update_shader() {
 		bool failed=false;
 
 		if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) {
-			code[i]+="vec3 DIFFUSE_OUT=vec3(0,0,0);";
-			code[i]+="float ALPHA_OUT=0;";
+			code[i]+="vec3 DIFFUSE_OUT=vec3(0,0,0);\n";
+			code[i]+="float ALPHA_OUT=0;\n";
 		}
 
+
 		Map<String,String> inputs_xlate;
+		Map<String,String> input_names_xlate;
 		Set<String> inputs_used;
 
 		for(int j=0;j<order.size();j++) {
@@ -1458,6 +1571,7 @@ void ShaderGraph::_update_shader() {
 
 						String vname=("nd"+itos(n->id)+"sl"+itos(idx));
 						inputs_xlate[vname]=String(typestr[iop->slot_type])+" "+vname+"="+iop->variable+";\n";
+						input_names_xlate[vname]=iop->variable;
 						idx++;
 					}
 					iop++;
@@ -1476,7 +1590,7 @@ void ShaderGraph::_update_shader() {
 							String iname=("nd"+itos(n->connections[idx].id)+"sl"+itos(n->connections[idx].slot));
 							if (node_get_type(ShaderType(i),n->connections[idx].id)==NODE_INPUT)
 								inputs_used.insert(iname);
-							code[i]+=String(iop->variable)+"="+iname+";\n";
+							code[i]+=String(iop->variable)+"="+iname+String(iop->postfix)+";\n";
 							if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL && String(iop->name)=="DiffuseAlpha")
 								use_alpha=true;
 						}
@@ -1488,8 +1602,7 @@ void ShaderGraph::_update_shader() {
 				if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) {
 
 					if (use_alpha) {
-						code[i]+="DIFFUSE_ALPHA.rgb=DIFFUSE_OUT;\n";
-						code[i]+="DIFFUSE_ALPHA.a=ALPHA_OUT;\n";
+						code[i]+="DIFFUSE_ALPHA=vec4(DIFFUSE_OUT,ALPHA_OUT);\n";
 					} else {
 						code[i]+="DIFFUSE=DIFFUSE_OUT;\n";
 					}
@@ -1506,13 +1619,19 @@ void ShaderGraph::_update_shader() {
 					}
 					String iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot);
 					inputs.push_back(iname);
-					if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT)
+					if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) {
 						inputs_used.insert(iname);
+					}
 
 				}
 
 				if (failed)
 					break;
+
+				if (n->type==NODE_TEXTURE_INPUT || n->type==NODE_CUBEMAP_INPUT) {
+
+					set_default_texture_param(n->param1,n->param2);
+				}
 				_add_node_code(ShaderType(i),n,inputs,code[i]);
 			}
 
@@ -1521,11 +1640,31 @@ void ShaderGraph::_update_shader() {
 		if (failed)
 			continue;
 
+
 		for(Set<String>::Element *E=inputs_used.front();E;E=E->next()) {
 
 			ERR_CONTINUE( !inputs_xlate.has(E->get()));
 			code[i]=inputs_xlate[E->get()]+code[i];
+			String name=input_names_xlate[E->get()];
+
+			if (i==SHADER_TYPE_VERTEX && get_mode()==MODE_MATERIAL) {
+				if (name==("SRC_COLOR"))
+					code[i]="vec3 SRC_COLOR=COLOR.rgb;\n"+code[i];
+				if (name==("SRC_ALPHA"))
+					code[i]="float SRC_ALPHA=COLOR.a;\n"+code[i];
+				if (name==("SRC_UV"))
+					code[i]="vec3 SRC_UV=vec3(UV,0);\n"+code[i];
+				if (name==("SRC_UV2"))
+					code[i]="float SRC_UV2=vec3(UV2,0);\n"+code[i];
+			} else if (i==SHADER_TYPE_FRAGMENT && get_mode()==MODE_MATERIAL) {
+				if (name==("IN_NORMAL"))
+					code[i]="vec3 IN_NORMAL=NORMAL;\n"+code[i];
+			}
+
 		}
+
+
+
 		shader[i].error=GRAPH_OK;
 		print_line("ShADER: "+code[i]);
 	}
@@ -1568,6 +1707,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str
 		case NODE_RGB_CONST: {
 			Color col = p_node->param1;
 			code+=OUTNAME(p_node->id,0)+"=vec3("+rtos(col.r)+","+rtos(col.g)+","+rtos(col.b)+");\n";
+			code+=OUTNAME(p_node->id,1)+"="+rtos(col.a)+";\n";
 		}break;
 		case NODE_XFORM_CONST: {
 
@@ -1744,7 +1884,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str
 		}break;
 		case NODE_TEXTURE_INPUT: {
 			String name = p_node->param1;
-			String rname="_read_tex"+itos(p_node->id);
+			String rname="rt_read_tex"+itos(p_node->id);
 			code +="uniform texture "+name+";";
 			code +="vec4 "+rname+"=tex("+name+","+p_inputs[0]+".xy);\n";
 			code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n";
@@ -1755,7 +1895,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str
 
 			String name = p_node->param1;
 			code +="uniform cubemap "+name+";";
-			String rname="_read_tex"+itos(p_node->id);
+			String rname="rt_read_tex"+itos(p_node->id);
 			code +="vec4 "+rname+"=texcube("+name+","+p_inputs[0]+".xy);\n";
 			code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n";
 			code += OUTNAME(p_node->id,1)+"="+rname+".a;\n";

+ 5 - 1
scene/resources/shader_graph.h

@@ -115,7 +115,7 @@ public:
 
 private:
 
-	String _find_unique_name(ShaderType p_which, const String& p_base);
+	String _find_unique_name(const String& p_base);
 
 	struct SourceSlot {
 
@@ -151,6 +151,7 @@ private:
 		ShaderType shader_type;
 		const char *name;
 		const char *variable;
+		const char *postfix;
 		SlotType slot_type;
 		SlotDir dir;
 	};
@@ -175,6 +176,9 @@ private:
 
 	Array _get_node_list(ShaderType p_type) const;
 	Array _get_connections(ShaderType p_type) const;
+
+	void _set_data(const Dictionary& p_data);
+	Dictionary _get_data() const;
 protected:
 
 	static void _bind_methods();

BIN
tools/editor/icons/icon_graph_comment.png


BIN
tools/editor/icons/icon_graph_cube_uniform.png


BIN
tools/editor/icons/icon_graph_input.png


BIN
tools/editor/icons/icon_graph_rgb.png


BIN
tools/editor/icons/icon_graph_rgb_op.png


BIN
tools/editor/icons/icon_graph_rgb_uniform.png


BIN
tools/editor/icons/icon_graph_scalar.png


BIN
tools/editor/icons/icon_graph_scalar_interp.png


BIN
tools/editor/icons/icon_graph_scalar_op.png


BIN
tools/editor/icons/icon_graph_scalar_uniform.png


BIN
tools/editor/icons/icon_graph_scalars_to_vec.png


BIN
tools/editor/icons/icon_graph_texscreen.png


BIN
tools/editor/icons/icon_graph_texture_uniform.png


BIN
tools/editor/icons/icon_graph_time.png


BIN
tools/editor/icons/icon_graph_vec_dp.png


BIN
tools/editor/icons/icon_graph_vec_interp.png


BIN
tools/editor/icons/icon_graph_vec_length.png


BIN
tools/editor/icons/icon_graph_vec_op.png


BIN
tools/editor/icons/icon_graph_vec_scalar_op.png


BIN
tools/editor/icons/icon_graph_vec_to_scalars.png


BIN
tools/editor/icons/icon_graph_vecs_to_xform.png


BIN
tools/editor/icons/icon_graph_vector.png


BIN
tools/editor/icons/icon_graph_vector_uniform.png


BIN
tools/editor/icons/icon_graph_xform.png


BIN
tools/editor/icons/icon_graph_xform_mult.png


BIN
tools/editor/icons/icon_graph_xform_scalar_func.png


BIN
tools/editor/icons/icon_graph_xform_to_vecs.png


BIN
tools/editor/icons/icon_graph_xform_uniform.png


BIN
tools/editor/icons/icon_graph_xform_vec_func.png


BIN
tools/editor/icons/icon_graph_xform_vec_imult.png


BIN
tools/editor/icons/icon_graph_xform_vec_mult.png


+ 90 - 47
tools/editor/plugins/shader_graph_editor_plugin.cpp

@@ -383,6 +383,41 @@ void ShaderGraphView::_connection_request(const String& p_from, int p_from_slot,
 	ur->commit_action();
 
 
+}
+
+void ShaderGraphView::_disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) {
+
+	UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+
+	int from_idx=-1;
+	int to_idx=-1;
+	for (Map<int,GraphNode*>::Element *E=node_map.front();E;E=E->next()) {
+
+		if (p_from==E->get()->get_name())
+			from_idx=E->key();
+		if (p_to==E->get()->get_name())
+			to_idx=E->key();
+	}
+
+	ERR_FAIL_COND(from_idx==-1);
+	ERR_FAIL_COND(to_idx==-1);
+
+	if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot))
+		return; //nothing to disconnect
+
+	ur->create_action("Disconnect Graph Nodes");
+
+	List<ShaderGraph::Connection> conns;
+
+	graph->get_node_connections(type,&conns);
+	//disconnect/reconnect dependencies
+	ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot);
+	ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot);
+	ur->add_do_method(this,"_update_graph");
+	ur->add_undo_method(this,"_update_graph");
+	ur->commit_action();
+
+
 }
 
 void ShaderGraphView::_node_removed(int p_id) {
@@ -433,8 +468,8 @@ void ShaderGraphView::_create_node(int p_id) {
 	GraphNode *gn = memnew( GraphNode );
 	gn->set_show_close_button(true);
 	Color typecol[4]={
-		Color(0.2,1,0.2),
-		Color(0.7,0.1,1),
+		Color(0.9,0.4,1),
+		Color(0.8,1,0.2),
 		Color(1,0.2,0.2),
 		Color(0,1,1)
 	};
@@ -1262,6 +1297,7 @@ void ShaderGraphView::_bind_methods() {
 	ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node);
 	ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed);
 	ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request);
+	ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request);
 
 	ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed);
 	ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed);
@@ -1318,6 +1354,22 @@ void ShaderGraphEditor::_add_node(int p_type) {
 
 void ShaderGraphEditor::_notification(int p_what) {
 	if (p_what==NOTIFICATION_ENTER_TREE) {
+
+		for(int i=0;i<ShaderGraph::NODE_TYPE_MAX;i++) {
+
+			if (i==ShaderGraph::NODE_OUTPUT)
+				continue;
+			String nn = node_names[i];
+			String ic = nn.get_slice(":",0);
+			String v = nn.get_slice(":",1);
+			bool addsep=false;
+			if (nn.ends_with(":")) {
+				addsep=true;
+			}
+			menu->get_popup()->add_icon_item(get_icon(ic,"EditorIcons"),v,i);
+			if (addsep)
+				menu->get_popup()->add_separator();
+		}
 		menu->get_popup()->connect("item_pressed",this,"_add_node");
 
 
@@ -1332,38 +1384,38 @@ void ShaderGraphEditor::_bind_methods() {
 
 
 const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={
-	"Input", // all inputs (shader type dependent)
-	"Scalar Constant", //scalar constant
-	"Vector Constant", //vec3 constant
-	"RGB Constant", //rgb constant (shows a color picker instead)
-	"XForm Constant", // 4x4 matrix constant
-	"Time:", // time in seconds
-	"Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader)
-	"Scalar Operator", // scalar vs scalar op (mul", add", div", etc)
-	"Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc)
-	"Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc)
-	"RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc.
-	"XForm Multiply", // mat4 x mat4
-	"XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option)
-	"XForm+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option)
-	"Scalar Function", // scalar function (sin", cos", etc)
-	"Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc)
-	"Vector Length", // vec3 length
-	"Dot Product:", // vec3 . vec3 (dot product -> scalar output)
-	"Vector -> Scalars", // 1 vec3 input", 3 scalar outputs
-	"Scalars -> Vector", // 3 scalar input", 1 vec3 output
-	"XForm -> Vectors", // 3 vec input", 1 xform output
-	"Vectors -> XForm:", // 3 vec input", 1 xform output
-	"Scalar Interpolate", // scalar interpolation (with optional curve)
-	"Vector Interpolate:", // vec3 interpolation  (with optional curve)
-	"Scalar Uniform", // scalar uniform (assignable in material)
-	"Vector Uniform", // vec3 uniform (assignable in material)
-	"RGB Uniform", // color uniform (assignable in material)
-	"XForm Uniform", // mat4 uniform (assignable in material)
-	"Texture Uniform", // texture input (assignable in material)
-	"CubeMap Uniform:", // cubemap input (assignable in material)
+	"GraphInput:Input", // all inputs (shader type dependent)
+	"GraphScalar:Scalar Constant", //scalar constant
+	"GraphVector:Vector Constant", //vec3 constant
+	"GraphRgb:RGB Constant", //rgb constant (shows a color picker instead)
+	"GraphXform:XForm Constant", // 4x4 matrix constant
+	"GraphTime:Time:", // time in seconds
+	"GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader)
+	"GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc)
+	"GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc)
+	"GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc)
+	"GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc.
+	"GraphXformMult:XForm Multiply", // mat4 x mat4
+	"GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option)
+	"GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option)
+	"GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc)
+	"GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc)
+	"GraphVecLength:Vector Length", // vec3 length
+	"GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output)
+	"GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs
+	"GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output
+	"GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output
+	"GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output
+	"GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve)
+	"GraphVecInterp:Vector Interpolate:", // vec3 interpolation  (with optional curve)
+	"GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material)
+	"GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material)
+	"GraphRgbUniform:RGB Uniform", // color uniform (assignable in material)
+	"GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material)
+	"GraphTextureUniform:Texture Uniform", // texture input (assignable in material)
+	"GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material)
 	"Output", // output (shader type dependent)
-	"Comment", // comment
+	"GraphComment:Comment", // comment
 
 
 };
@@ -1374,20 +1426,7 @@ ShaderGraphEditor::ShaderGraphEditor() {
 	menu->set_text("Add..");
 	hbc->add_child(menu);
 	add_child(hbc);
-	for(int i=0;i<ShaderGraph::NODE_TYPE_MAX;i++) {
-
-		if (i==ShaderGraph::NODE_OUTPUT)
-			continue;
-		String v = node_names[i];
-		bool addsep=false;
-		if (v.ends_with(":")) {
-			addsep=true;
-			v=v.substr(0,v.length()-1);
-		}
-		menu->get_popup()->add_item(v,i);
-		if (addsep)
-			menu->get_popup()->add_separator();
-	}
+
 
 	tabs = memnew(TabContainer);
 	tabs->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1404,8 +1443,12 @@ ShaderGraphEditor::ShaderGraphEditor() {
 		graph_edits[i]->get_graph_edit()->set_name(sname[i]);
 		tabs->add_child(graph_edits[i]->get_graph_edit());
 		graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request");
+		graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request");
+		graph_edits[i]->get_graph_edit()->set_right_disconnects(true);
 	}
 
+	tabs->set_current_tab(1);
+
 	set_custom_minimum_size(Size2(100,300));
 }
 

+ 2 - 0
tools/editor/plugins/shader_graph_editor_plugin.h

@@ -66,6 +66,8 @@ class ShaderGraphView : public Node {
 
 
 	void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot);
+	void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot);
+
 	void _node_removed(int p_id);
 	void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id);
 	void _move_node(int p_id,const Vector2& p_to);