diff options
Diffstat (limited to 'scene/resources/shader_graph.cpp')
-rw-r--r-- | scene/resources/shader_graph.cpp | 212 |
1 files changed, 179 insertions, 33 deletions
diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 4c81724841..8b2f318ec0 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -27,8 +27,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "shader_graph.h" - - +#include "scene/scene_string_names.h" +//todo +//-RGB ops +//-mostrar error de conexion Array ShaderGraph::_get_node_list(ShaderType p_type) const { @@ -135,6 +137,13 @@ Dictionary ShaderGraph::_get_data() const { } + +ShaderGraph::GraphError ShaderGraph::get_graph_error(ShaderType p_type) const { + + ERR_FAIL_INDEX_V(p_type,3,GRAPH_OK); + return shader[p_type].error; +} + void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader); @@ -178,9 +187,9 @@ void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("vec_scalar_op_node_set_op","shader_type","id","op"),&ShaderGraph::vec_scalar_op_node_set_op); ObjectTypeDB::bind_method(_MD("vec_scalar_op_node_get_op","shader_type","id"),&ShaderGraph::vec_scalar_op_node_get_op); - ObjectTypeDB::bind_method(_MD("rgb_op_node_set_op","shader_type","id","op","c"),&ShaderGraph::rgb_op_node_set_op); + ObjectTypeDB::bind_method(_MD("rgb_op_node_set_op","shader_type","id","op"),&ShaderGraph::rgb_op_node_set_op); ObjectTypeDB::bind_method(_MD("rgb_op_node_get_op","shader_type","id"),&ShaderGraph::rgb_op_node_get_op); - ObjectTypeDB::bind_method(_MD("rgb_op_node_get_c","shader_type","id"),&ShaderGraph::rgb_op_node_get_c); + ObjectTypeDB::bind_method(_MD("xform_vec_mult_node_set_no_translation","shader_type","id","disable"),&ShaderGraph::xform_vec_mult_node_set_no_translation); ObjectTypeDB::bind_method(_MD("xform_vec_mult_node_get_no_translation","shader_type","id"),&ShaderGraph::xform_vec_mult_node_get_no_translation); @@ -354,6 +363,8 @@ void ShaderGraph::_bind_methods() { BIND_CONSTANT( VEC_FUNC_HSV2RGB ); BIND_CONSTANT( VEC_MAX_FUNC ); + ADD_SIGNAL(MethodInfo("updated")); + #if 0 ObjectTypeDB::bind_method(_MD("node_add"),&ShaderGraph::node_add ); @@ -566,7 +577,7 @@ void ShaderGraph::node_remove(ShaderType p_type,int p_id) { } shader[p_type].node_map.erase(p_id); - print_line("erased node, amount left: "+itos(shader[p_type].node_map.size())); + _request_update(); } @@ -632,7 +643,6 @@ bool ShaderGraph::is_node_connected(ShaderType p_type,int p_src_id,int p_src_slo void ShaderGraph::disconnect_node(ShaderType p_type,int p_src_id,int p_src_slot, int p_dst_id,int p_dst_slot) { ERR_FAIL_INDEX(p_type,3); - print_line("** dsisconnect"); SourceSlot ts; ts.id=p_src_id; ts.slot=p_src_slot; @@ -869,14 +879,14 @@ ShaderGraph::VecScalarOp ShaderGraph::vec_scalar_op_node_get_op(ShaderType p_typ } -void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp p_op,float p_c){ +void ShaderGraph::rgb_op_node_set_op(ShaderType p_type,float p_id,RGBOp p_op){ ERR_FAIL_INDEX(p_type,3); ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); Node& n = shader[p_type].node_map[p_id]; ERR_FAIL_COND(n.type!=NODE_RGB_OP); n.param1=p_op; - n.param2=p_c; + _request_update(); } @@ -890,15 +900,7 @@ ShaderGraph::RGBOp ShaderGraph::rgb_op_node_get_op(ShaderType p_type,float p_id) return RGBOp(op); } -float ShaderGraph::rgb_op_node_get_c(ShaderType p_type,float p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,0); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),0); - const Node& n = shader[p_type].node_map[p_id]; - ERR_FAIL_COND_V(n.type!=NODE_RGB_OP,0); - return n.param2; - -} void ShaderGraph::xform_vec_mult_node_set_no_translation(ShaderType p_type,int p_id,bool p_no_translation){ @@ -926,7 +928,9 @@ void ShaderGraph::scalar_func_node_set_function(ShaderType p_type,int p_id,Scala ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); Node& n = shader[p_type].node_map[p_id]; ERR_FAIL_COND(n.type!=NODE_SCALAR_FUNC); - n.param1=p_func; + int func = p_func; + ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); + n.param1=func; _request_update(); } @@ -946,7 +950,9 @@ void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); Node& n = shader[p_type].node_map[p_id]; ERR_FAIL_COND(n.type!=NODE_VEC_FUNC); - n.param1=p_func; + int func = p_func; + ERR_FAIL_INDEX(func,VEC_MAX_FUNC); + n.param1=func; _request_update(); @@ -1214,7 +1220,7 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={ {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,"Position","POSITION.xyz","",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}, @@ -1284,10 +1290,10 @@ const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= { {NODE_SCALAR_OP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) {NODE_VEC_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // scalar vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) {NODE_VEC_SCALAR_OP,{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) - {NODE_RGB_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) + {NODE_RGB_OP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 vs scalar op (mul,{SLOT_MAX},{SLOT_MAX}}, add,{SLOT_MAX},{SLOT_MAX}}, div,{SLOT_MAX},{SLOT_MAX}}, etc) {NODE_XFORM_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_XFORM,SLOT_MAX},{SLOT_TYPE_XFORM,SLOT_MAX}}, // mat4 x mat4 {NODE_XFORM_VEC_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 mult (with no-translation option) - {NODE_XFORM_VEC_INV_MULT,{SLOT_TYPE_XFORM,SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 inverse mult (with no-translation option) + {NODE_XFORM_VEC_INV_MULT,{SLOT_TYPE_VEC,SLOT_TYPE_XFORM,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // mat4 x vec3 inverse mult (with no-translation option) {NODE_SCALAR_FUNC,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar function (sin,{SLOT_MAX},{SLOT_MAX}}, cos,{SLOT_MAX},{SLOT_MAX}}, etc) {NODE_VEC_FUNC,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vector function (normalize,{SLOT_MAX},{SLOT_MAX}}, negate,{SLOT_MAX},{SLOT_MAX}}, reciprocal,{SLOT_MAX},{SLOT_MAX}}, rgb2hsv,{SLOT_MAX},{SLOT_MAX}}, hsv2rgb,{SLOT_MAX},{SLOT_MAX}}, etc,{SLOT_MAX},{SLOT_MAX}}, etc) {NODE_VEC_LEN,{SLOT_TYPE_VEC,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 length @@ -1418,6 +1424,7 @@ ShaderGraph::SlotType ShaderGraph::get_node_input_slot_type(Mode p_mode, ShaderT if (nsi->type==p_type) { for(int i=0;i<NodeSlotInfo::MAX_INS;i++) { + if (nsi->ins[i]==SLOT_MAX) break; if (i==p_idx) @@ -1666,7 +1673,7 @@ void ShaderGraph::_update_shader() { shader[i].error=GRAPH_OK; - print_line("ShADER: "+code[i]); + } bool all_ok=true; @@ -1679,8 +1686,9 @@ void ShaderGraph::_update_shader() { set_code(code[0],code[1],code[2]); } //do shader here - print_line("UPDATING SHADER"); + _pending_update_shader=false; + emit_signal(SceneStringNames::get_singleton()->updated); } void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<String>& p_inputs,String& code) { @@ -1688,6 +1696,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str const char *typestr[4]={"float","vec3","mat4","texture"}; #define OUTNAME(id,slot) (String(typestr[get_node_output_slot_type(get_mode(),p_type,p_node->type,slot)])+" "+("nd"+itos(id)+"sl"+itos(slot))) +#define OUTVAR(id,slot) ("nd"+itos(id)+"sl"+itos(slot)) switch(p_node->type) { @@ -1766,16 +1775,94 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str int op = p_node->param1; String optxt; switch(op) { - case VEC_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; - case VEC_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; - case VEC_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; + case VEC_SCALAR_OP_MUL: optxt = p_inputs[0]+"*"+p_inputs[1]+";"; break; + case VEC_SCALAR_OP_DIV: optxt = p_inputs[0]+"/"+p_inputs[1]+";"; break; + case VEC_SCALAR_OP_POW: optxt = "pow("+p_inputs[0]+","+p_inputs[1]+");"; break; } code+=OUTNAME(p_node->id,0)+"="+optxt+"\n"; }break; case NODE_RGB_OP: { + int op = p_node->param1; + static const char*axisn[3]={"x","y","z"}; + switch(op) { + case RGB_OP_SCREEN: { + + code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")*(vec3(1.0)-"+p_inputs[1]+");\n"; + } break; + case RGB_OP_DIFFERENCE: { + + code += OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"; + + } break; + case RGB_OP_DARKEN: { + + code += OUTNAME(p_node->id,0)+"=min("+p_inputs[0]+","+p_inputs[1]+");\n"; + } break; + case RGB_OP_LIGHTEN: { + + code += OUTNAME(p_node->id,0)+"=max("+p_inputs[0]+","+p_inputs[1]+");\n"; + + } break; + case RGB_OP_OVERLAY: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 2.0 * base * blend;\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base);\n"; + code += "\t}\n"; + code += "}\n"; + } + } break; + case RGB_OP_DODGE: { + + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+")/(vec3(1.0)-"+p_inputs[1]+");\n"; + + } break; + case RGB_OP_BURN: { + + code += OUTNAME(p_node->id,0)+"=vec3(1.0)-(vec3(1.0)-"+p_inputs[0]+")/("+p_inputs[1]+");\n"; + } break; + case RGB_OP_SOFT_LIGHT: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (blend+0.5));\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-(blend-0.5)));\n"; + code += "\t}\n"; + code += "}\n"; + } + + } break; + case RGB_OP_HARD_LIGHT: { + + code += OUTNAME(p_node->id,0)+";\n"; + for(int i=0;i<3;i++) { + code += "{\n"; + code += "\tfloat base="+p_inputs[0]+"."+axisn[i]+";\n"; + code += "\tfloat blend="+p_inputs[1]+"."+axisn[i]+";\n"; + code += "\tif (base < 0.5) {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (base * (2*blend));\n"; + code += "\t} else {\n"; + code += "\t\t"+OUTVAR(p_node->id,0)+"."+axisn[i]+" = (1 - (1-base) * (1-2*(blend-0.5)));\n"; + code += "\t}\n"; + code += "}\n"; + } + + } break; + } }break; case NODE_XFORM_MULT: { @@ -1786,26 +1873,85 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector<Str bool no_translation = p_node->param1; if (no_translation) { - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",0);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",0)).xyz;\n"; } else { - code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+"*vec4("+p_inputs[1]+",1);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[0]+"*vec4("+p_inputs[1]+",1)).xyz;\n"; } }break; case NODE_XFORM_VEC_INV_MULT: { bool no_translation = p_node->param1; if (no_translation) { - code += OUTNAME(p_node->id,0)+"="+p_inputs[1]+"*vec4("+p_inputs[0]+",0);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",0)).xyz;\n"; } else { - code += OUTNAME(p_node->id,0)+"="+p_inputs[1]+"*vec4("+p_inputs[0]+",1);\n"; + code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",1)).xyz;\n"; } }break; case NODE_SCALAR_FUNC: { - - - }break; + static const char*scalar_func_id[SCALAR_MAX_FUNC]={ + "sin($)", + "cos($)", + "tan($)", + "asin($)", + "acos($)", + "atan($)", + "sinh($)", + "cosh($)", + "tanh($)", + "log($)", + "exp($)", + "sqrt($)", + "abs($)", + "sign($)", + "floor($)", + "round($)", + "ceil($)", + "frac($)", + "min(max($,0),1)", + "-($)", + }; + + int func = p_node->param1; + ERR_FAIL_INDEX(func,SCALAR_MAX_FUNC); + code += OUTNAME(p_node->id,0)+"="+String(scalar_func_id[func]).replace("$",p_inputs[0])+";\n"; + + } break; case NODE_VEC_FUNC: { + static const char*vec_func_id[VEC_MAX_FUNC]={ + "normalize($)", + "max(min($,vec3(1,1,1)),vec3(0,0,0))", + "-($)", + "1.0/($)", + "", + "", + }; + + + int func = p_node->param1; + ERR_FAIL_INDEX(func,VEC_MAX_FUNC); + if (func==VEC_FUNC_RGB2HSV) { + code += OUTNAME(p_node->id,0)+";\n"; + code+="{\n"; + code+="\tvec3 c = "+p_inputs[0]+";\n"; + code+="\tvec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n"; + code+="\tvec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n"; + code+="\tvec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n"; + code+="\tfloat d = q.x - min(q.w, q.y);\n"; + code+="\tfloat e = 1.0e-10;\n"; + code+="\t"+OUTVAR(p_node->id,0)+"=vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; + code+="}\n"; + } else if (func==VEC_FUNC_HSV2RGB) { + code += OUTNAME(p_node->id,0)+";\n";; + code+="{\n"; + code+="\tvec3 c = "+p_inputs[0]+";\n"; + code+="\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"; + code+="\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"; + code+="\t"+OUTVAR(p_node->id,0)+"=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"; + code+="}\n"; + } else { + code += OUTNAME(p_node->id,0)+"="+String(vec_func_id[func]).replace("$",p_inputs[0])+";\n"; + } }break; case NODE_VEC_LEN: { |