visual_shader_particle_nodes.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671
  1. /**************************************************************************/
  2. /* visual_shader_particle_nodes.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "visual_shader_particle_nodes.h"
  31. #include "scene/resources/image_texture.h"
  32. #include "scene/resources/mesh.h"
  33. // VisualShaderNodeParticleEmitter
  34. int VisualShaderNodeParticleEmitter::get_output_port_count() const {
  35. return 1;
  36. }
  37. VisualShaderNodeParticleEmitter::PortType VisualShaderNodeParticleEmitter::get_output_port_type(int p_port) const {
  38. if (mode_2d) {
  39. return p_port == 0 ? PORT_TYPE_VECTOR_2D : PORT_TYPE_SCALAR;
  40. }
  41. return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
  42. }
  43. String VisualShaderNodeParticleEmitter::get_output_port_name(int p_port) const {
  44. if (p_port == 0) {
  45. return "position";
  46. }
  47. return String();
  48. }
  49. bool VisualShaderNodeParticleEmitter::has_output_port_preview(int p_port) const {
  50. return false;
  51. }
  52. void VisualShaderNodeParticleEmitter::set_mode_2d(bool p_enabled) {
  53. if (mode_2d == p_enabled) {
  54. return;
  55. }
  56. mode_2d = p_enabled;
  57. emit_changed();
  58. }
  59. bool VisualShaderNodeParticleEmitter::is_mode_2d() const {
  60. return mode_2d;
  61. }
  62. Vector<StringName> VisualShaderNodeParticleEmitter::get_editable_properties() const {
  63. Vector<StringName> props;
  64. props.push_back("mode_2d");
  65. return props;
  66. }
  67. HashMap<StringName, String> VisualShaderNodeParticleEmitter::get_editable_properties_names() const {
  68. HashMap<StringName, String> names;
  69. names.insert("mode_2d", RTR("2D Mode"));
  70. return names;
  71. }
  72. bool VisualShaderNodeParticleEmitter::is_show_prop_names() const {
  73. return true;
  74. }
  75. void VisualShaderNodeParticleEmitter::_bind_methods() {
  76. ClassDB::bind_method(D_METHOD("set_mode_2d", "enabled"), &VisualShaderNodeParticleEmitter::set_mode_2d);
  77. ClassDB::bind_method(D_METHOD("is_mode_2d"), &VisualShaderNodeParticleEmitter::is_mode_2d);
  78. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_2d"), "set_mode_2d", "is_mode_2d");
  79. }
  80. VisualShaderNodeParticleEmitter::VisualShaderNodeParticleEmitter() {
  81. }
  82. // VisualShaderNodeParticleSphereEmitter
  83. String VisualShaderNodeParticleSphereEmitter::get_caption() const {
  84. return "SphereEmitter";
  85. }
  86. int VisualShaderNodeParticleSphereEmitter::get_input_port_count() const {
  87. return 2;
  88. }
  89. VisualShaderNodeParticleSphereEmitter::PortType VisualShaderNodeParticleSphereEmitter::get_input_port_type(int p_port) const {
  90. return PORT_TYPE_SCALAR;
  91. }
  92. String VisualShaderNodeParticleSphereEmitter::get_input_port_name(int p_port) const {
  93. if (p_port == 0) {
  94. return "radius";
  95. } else if (p_port == 1) {
  96. return "inner_radius";
  97. }
  98. return String();
  99. }
  100. String VisualShaderNodeParticleSphereEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
  101. String code;
  102. code += "vec2 __get_random_point_in_circle(inout uint seed, float radius, float inner_radius) {\n";
  103. code += " return __get_random_unit_vec2(seed) * __randf_range(seed, inner_radius, radius);\n";
  104. code += "}\n\n";
  105. code += "vec3 __get_random_point_in_sphere(inout uint seed, float radius, float inner_radius) {\n";
  106. code += " return __get_random_unit_vec3(seed) * __randf_range(seed, inner_radius, radius);\n";
  107. code += "}\n\n";
  108. return code;
  109. }
  110. String VisualShaderNodeParticleSphereEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  111. String code;
  112. if (mode_2d) {
  113. code += " " + p_output_vars[0] + " = __get_random_point_in_circle(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
  114. } else {
  115. code += " " + p_output_vars[0] + " = __get_random_point_in_sphere(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
  116. }
  117. return code;
  118. }
  119. VisualShaderNodeParticleSphereEmitter::VisualShaderNodeParticleSphereEmitter() {
  120. set_input_port_default_value(0, 10.0);
  121. set_input_port_default_value(1, 0.0);
  122. }
  123. // VisualShaderNodeParticleBoxEmitter
  124. String VisualShaderNodeParticleBoxEmitter::get_caption() const {
  125. return "BoxEmitter";
  126. }
  127. int VisualShaderNodeParticleBoxEmitter::get_input_port_count() const {
  128. return 1;
  129. }
  130. VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleBoxEmitter::get_input_port_type(int p_port) const {
  131. if (p_port == 0) {
  132. if (mode_2d) {
  133. return PORT_TYPE_VECTOR_2D;
  134. }
  135. return PORT_TYPE_VECTOR_3D;
  136. }
  137. return PORT_TYPE_SCALAR;
  138. }
  139. void VisualShaderNodeParticleBoxEmitter::set_mode_2d(bool p_enabled) {
  140. if (mode_2d == p_enabled) {
  141. return;
  142. }
  143. if (p_enabled) {
  144. set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
  145. } else {
  146. set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
  147. }
  148. mode_2d = p_enabled;
  149. emit_changed();
  150. }
  151. String VisualShaderNodeParticleBoxEmitter::get_input_port_name(int p_port) const {
  152. if (p_port == 0) {
  153. return "extents";
  154. }
  155. return String();
  156. }
  157. String VisualShaderNodeParticleBoxEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
  158. String code;
  159. code += "vec2 __get_random_point_in_box2d(inout uint seed, vec2 extents) {\n";
  160. code += " vec2 half_extents = extents / 2.0;\n";
  161. code += " return vec2(__randf_range(seed, -half_extents.x, half_extents.x), __randf_range(seed, -half_extents.y, half_extents.y));\n";
  162. code += "}\n\n";
  163. code += "vec3 __get_random_point_in_box3d(inout uint seed, vec3 extents) {\n";
  164. code += " vec3 half_extents = extents / 2.0;\n";
  165. code += " return vec3(__randf_range(seed, -half_extents.x, half_extents.x), __randf_range(seed, -half_extents.y, half_extents.y), __randf_range(seed, -half_extents.z, half_extents.z));\n";
  166. code += "}\n\n";
  167. return code;
  168. }
  169. String VisualShaderNodeParticleBoxEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  170. String code;
  171. if (mode_2d) {
  172. code += " " + p_output_vars[0] + " = __get_random_point_in_box2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
  173. } else {
  174. code += " " + p_output_vars[0] + " = __get_random_point_in_box3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ");\n";
  175. }
  176. return code;
  177. }
  178. VisualShaderNodeParticleBoxEmitter::VisualShaderNodeParticleBoxEmitter() {
  179. set_input_port_default_value(0, Vector3(1.0, 1.0, 1.0));
  180. }
  181. // VisualShaderNodeParticleRingEmitter
  182. String VisualShaderNodeParticleRingEmitter::get_caption() const {
  183. return "RingEmitter";
  184. }
  185. int VisualShaderNodeParticleRingEmitter::get_input_port_count() const {
  186. return 3;
  187. }
  188. VisualShaderNodeParticleRingEmitter::PortType VisualShaderNodeParticleRingEmitter::get_input_port_type(int p_port) const {
  189. return PORT_TYPE_SCALAR;
  190. }
  191. String VisualShaderNodeParticleRingEmitter::get_input_port_name(int p_port) const {
  192. if (p_port == 0) {
  193. return "radius";
  194. } else if (p_port == 1) {
  195. return "inner_radius";
  196. } else if (p_port == 2) {
  197. return "height";
  198. }
  199. return String();
  200. }
  201. String VisualShaderNodeParticleRingEmitter::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
  202. String code;
  203. code += "vec2 __get_random_point_on_ring2d(inout uint seed, float radius, float inner_radius) {\n";
  204. code += " float angle = __rand_from_seed(seed) * TAU;\n";
  205. code += " vec2 ring = vec2(sin(angle), cos(angle)) * __randf_range(seed, inner_radius, radius);\n";
  206. code += " return vec2(ring.x, ring.y);\n";
  207. code += "}\n\n";
  208. code += "vec3 __get_random_point_on_ring3d(inout uint seed, float radius, float inner_radius, float height) {\n";
  209. code += " float angle = __rand_from_seed(seed) * TAU;\n";
  210. code += " vec2 ring = vec2(sin(angle), cos(angle)) * __randf_range(seed, inner_radius, radius);\n";
  211. code += " return vec3(ring.x, __randf_range(seed, min(0.0, height), max(0.0, height)), ring.y);\n";
  212. code += "}\n\n";
  213. return code;
  214. }
  215. String VisualShaderNodeParticleRingEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  216. String code;
  217. if (mode_2d) {
  218. code = " " + p_output_vars[0] + " = __get_random_point_on_ring2d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
  219. } else {
  220. code = " " + p_output_vars[0] + " = __get_random_point_on_ring3d(__seed, " + (p_input_vars[0].is_empty() ? (String)get_input_port_default_value(0) : p_input_vars[0]) + ", " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ");\n";
  221. }
  222. return code;
  223. }
  224. VisualShaderNodeParticleRingEmitter::VisualShaderNodeParticleRingEmitter() {
  225. set_input_port_default_value(0, 10.0);
  226. set_input_port_default_value(1, 0.0);
  227. set_input_port_default_value(2, 0.0);
  228. }
  229. // VisualShaderNodeParticleMeshEmitter
  230. String VisualShaderNodeParticleMeshEmitter::get_caption() const {
  231. return "MeshEmitter";
  232. }
  233. int VisualShaderNodeParticleMeshEmitter::get_output_port_count() const {
  234. return 6;
  235. }
  236. VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter::get_output_port_type(int p_port) const {
  237. switch (p_port) {
  238. case 0: // position
  239. if (mode_2d) {
  240. return PORT_TYPE_VECTOR_2D;
  241. }
  242. return PORT_TYPE_VECTOR_3D;
  243. case 1: // normal
  244. if (mode_2d) {
  245. return PORT_TYPE_VECTOR_2D;
  246. }
  247. return PORT_TYPE_VECTOR_3D;
  248. case 2: // color
  249. return PORT_TYPE_VECTOR_3D;
  250. case 3: // alpha
  251. return PORT_TYPE_SCALAR;
  252. case 4: // uv
  253. return PORT_TYPE_VECTOR_2D;
  254. case 5: // uv2
  255. return PORT_TYPE_VECTOR_2D;
  256. }
  257. return PORT_TYPE_SCALAR;
  258. }
  259. String VisualShaderNodeParticleMeshEmitter::get_output_port_name(int p_port) const {
  260. switch (p_port) {
  261. case 0:
  262. return "position";
  263. case 1:
  264. return "normal";
  265. case 2:
  266. return "color";
  267. case 3:
  268. return "alpha";
  269. case 4:
  270. return "uv";
  271. case 5:
  272. return "uv2";
  273. }
  274. return String();
  275. }
  276. int VisualShaderNodeParticleMeshEmitter::get_input_port_count() const {
  277. return 0;
  278. }
  279. VisualShaderNodeParticleBoxEmitter::PortType VisualShaderNodeParticleMeshEmitter::get_input_port_type(int p_port) const {
  280. return PORT_TYPE_SCALAR;
  281. }
  282. String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) const {
  283. return String();
  284. }
  285. String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
  286. String code;
  287. if (is_output_port_connected(0)) { // position
  288. code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
  289. }
  290. if (is_output_port_connected(1)) { // normal
  291. code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
  292. }
  293. if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
  294. code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
  295. }
  296. if (is_output_port_connected(4)) { // uv
  297. code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
  298. }
  299. if (is_output_port_connected(5)) { // uv2
  300. code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
  301. }
  302. return code;
  303. }
  304. String VisualShaderNodeParticleMeshEmitter::_generate_code(VisualShader::Type p_type, int p_id, const String *p_output_vars, int p_index, const String &p_texture_name, PortType p_port_type) const {
  305. String code;
  306. if (is_output_port_connected(p_index)) {
  307. switch (p_port_type) {
  308. case PORT_TYPE_VECTOR_2D: {
  309. code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
  310. } break;
  311. case PORT_TYPE_VECTOR_3D: {
  312. if (mode_2d) {
  313. code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xy;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
  314. } else {
  315. code += vformat(" %s = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0).xyz;\n", p_output_vars[p_index], make_unique_id(p_type, p_id, p_texture_name));
  316. }
  317. } break;
  318. default:
  319. break;
  320. }
  321. }
  322. return code;
  323. }
  324. String VisualShaderNodeParticleMeshEmitter::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  325. String code;
  326. code += " {\n";
  327. code += " int __scalar_ibuff = int(__rand_from_seed(__seed) * 65535.0) % " + itos(position_texture->get_width()) + ";\n";
  328. code += _generate_code(p_type, p_id, p_output_vars, 0, "mesh_vx", VisualShaderNode::PORT_TYPE_VECTOR_3D);
  329. code += _generate_code(p_type, p_id, p_output_vars, 1, "mesh_nm", VisualShaderNode::PORT_TYPE_VECTOR_3D);
  330. if (is_output_port_connected(2) || is_output_port_connected(3)) {
  331. code += vformat(" vec4 __vec4_buff = texelFetch(%s, ivec2(__scalar_ibuff, 0), 0);\n", make_unique_id(p_type, p_id, "mesh_col"));
  332. if (is_output_port_connected(2)) {
  333. code += " " + p_output_vars[2] + " = __vec4_buff.rgb;\n";
  334. }
  335. if (is_output_port_connected(3)) {
  336. code += " " + p_output_vars[3] + " = __vec4_buff.a;\n";
  337. }
  338. }
  339. code += _generate_code(p_type, p_id, p_output_vars, 4, "mesh_uv", VisualShaderNode::PORT_TYPE_VECTOR_2D);
  340. code += _generate_code(p_type, p_id, p_output_vars, 5, "mesh_uv2", VisualShaderNode::PORT_TYPE_VECTOR_2D);
  341. code += " }\n";
  342. return code;
  343. }
  344. Vector<VisualShader::DefaultTextureParam> VisualShaderNodeParticleMeshEmitter::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
  345. Vector<VisualShader::DefaultTextureParam> ret;
  346. if (is_output_port_connected(0)) {
  347. VisualShader::DefaultTextureParam dtp;
  348. dtp.name = make_unique_id(p_type, p_id, "mesh_vx");
  349. dtp.params.push_back(position_texture);
  350. ret.push_back(dtp);
  351. }
  352. if (is_output_port_connected(1)) {
  353. VisualShader::DefaultTextureParam dtp;
  354. dtp.name = make_unique_id(p_type, p_id, "mesh_nm");
  355. dtp.params.push_back(normal_texture);
  356. ret.push_back(dtp);
  357. }
  358. if (is_output_port_connected(2) || is_output_port_connected(3)) {
  359. VisualShader::DefaultTextureParam dtp;
  360. dtp.name = make_unique_id(p_type, p_id, "mesh_col");
  361. dtp.params.push_back(color_texture);
  362. ret.push_back(dtp);
  363. }
  364. if (is_output_port_connected(4)) {
  365. VisualShader::DefaultTextureParam dtp;
  366. dtp.name = make_unique_id(p_type, p_id, "mesh_uv");
  367. dtp.params.push_back(uv_texture);
  368. ret.push_back(dtp);
  369. }
  370. if (is_output_port_connected(5)) {
  371. VisualShader::DefaultTextureParam dtp;
  372. dtp.name = make_unique_id(p_type, p_id, "mesh_uv2");
  373. dtp.params.push_back(uv2_texture);
  374. ret.push_back(dtp);
  375. }
  376. return ret;
  377. }
  378. void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector2> &p_array, Ref<ImageTexture> &r_texture) {
  379. Ref<Image> image;
  380. image.instantiate();
  381. if (p_array.is_empty()) {
  382. image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBF);
  383. } else {
  384. image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBF);
  385. }
  386. for (int i = 0; i < p_array.size(); i++) {
  387. Vector2 v = p_array[i];
  388. image->set_pixel(i, 0, Color(v.x, v.y, 0));
  389. }
  390. if (r_texture->get_width() != p_array.size() || p_array.is_empty()) {
  391. r_texture->set_image(image);
  392. } else {
  393. r_texture->update(image);
  394. }
  395. }
  396. void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Vector3> &p_array, Ref<ImageTexture> &r_texture) {
  397. Ref<Image> image;
  398. image.instantiate();
  399. if (p_array.is_empty()) {
  400. image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBF);
  401. } else {
  402. image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBF);
  403. }
  404. for (int i = 0; i < p_array.size(); i++) {
  405. Vector3 v = p_array[i];
  406. image->set_pixel(i, 0, Color(v.x, v.y, v.z));
  407. }
  408. if (r_texture->get_width() != p_array.size() || p_array.is_empty()) {
  409. r_texture->set_image(image);
  410. } else {
  411. r_texture->update(image);
  412. }
  413. }
  414. void VisualShaderNodeParticleMeshEmitter::_update_texture(const Vector<Color> &p_array, Ref<ImageTexture> &r_texture) {
  415. Ref<Image> image;
  416. image.instantiate();
  417. if (p_array.is_empty()) {
  418. image->initialize_data(1, 1, false, Image::Format::FORMAT_RGBA8);
  419. } else {
  420. image->initialize_data(p_array.size(), 1, false, Image::Format::FORMAT_RGBA8);
  421. }
  422. for (int i = 0; i < p_array.size(); i++) {
  423. image->set_pixel(i, 0, p_array[i]);
  424. }
  425. if (r_texture->get_width() != p_array.size() || p_array.is_empty()) {
  426. r_texture->set_image(image);
  427. } else {
  428. r_texture->update(image);
  429. }
  430. }
  431. void VisualShaderNodeParticleMeshEmitter::_update_textures() {
  432. if (mesh.is_null()) {
  433. return;
  434. }
  435. Vector<Vector3> vertices;
  436. Vector<Vector3> normals;
  437. Vector<Color> colors;
  438. Vector<Vector2> uvs;
  439. Vector<Vector2> uvs2;
  440. const int surface_count = mesh->get_surface_count();
  441. if (use_all_surfaces) {
  442. for (int i = 0; i < surface_count; i++) {
  443. const Array surface_arrays = mesh->surface_get_arrays(i);
  444. const int surface_arrays_size = surface_arrays.size();
  445. // position
  446. if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
  447. Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
  448. for (int j = 0; j < vertex_array.size(); j++) {
  449. vertices.push_back((Vector3)vertex_array[j]);
  450. }
  451. }
  452. // normal
  453. if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
  454. Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
  455. for (int j = 0; j < normal_array.size(); j++) {
  456. normals.push_back((Vector3)normal_array[j]);
  457. }
  458. }
  459. // color
  460. if (surface_arrays_size > Mesh::ARRAY_COLOR) {
  461. Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
  462. for (int j = 0; j < color_array.size(); j++) {
  463. colors.push_back((Color)color_array[j]);
  464. }
  465. }
  466. // uv
  467. if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
  468. Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
  469. for (int j = 0; j < uv_array.size(); j++) {
  470. uvs.push_back((Vector2)uv_array[j]);
  471. }
  472. }
  473. // uv2
  474. if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
  475. Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
  476. for (int j = 0; j < uv2_array.size(); j++) {
  477. uvs2.push_back((Vector2)uv2_array[j]);
  478. }
  479. }
  480. }
  481. } else {
  482. if (surface_index >= 0 && surface_index < surface_count) {
  483. const Array surface_arrays = mesh->surface_get_arrays(surface_index);
  484. const int surface_arrays_size = surface_arrays.size();
  485. // position
  486. if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
  487. Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
  488. for (int i = 0; i < vertex_array.size(); i++) {
  489. vertices.push_back((Vector3)vertex_array[i]);
  490. }
  491. }
  492. // normal
  493. if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
  494. Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
  495. for (int i = 0; i < normal_array.size(); i++) {
  496. normals.push_back((Vector3)normal_array[i]);
  497. }
  498. }
  499. // color
  500. if (surface_arrays_size > Mesh::ARRAY_COLOR) {
  501. Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
  502. for (int i = 0; i < color_array.size(); i++) {
  503. colors.push_back((Color)color_array[i]);
  504. }
  505. }
  506. // uv
  507. if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
  508. Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
  509. for (int j = 0; j < uv_array.size(); j++) {
  510. uvs.push_back((Vector2)uv_array[j]);
  511. }
  512. }
  513. // uv2
  514. if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
  515. Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
  516. for (int j = 0; j < uv2_array.size(); j++) {
  517. uvs2.push_back((Vector2)uv2_array[j]);
  518. }
  519. }
  520. }
  521. }
  522. _update_texture(vertices, position_texture);
  523. _update_texture(normals, normal_texture);
  524. _update_texture(colors, color_texture);
  525. _update_texture(uvs, uv_texture);
  526. _update_texture(uvs2, uv2_texture);
  527. }
  528. void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
  529. if (mesh == p_mesh) {
  530. return;
  531. }
  532. if (mesh.is_valid()) {
  533. mesh->disconnect_changed(callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures));
  534. }
  535. mesh = p_mesh;
  536. if (mesh.is_valid()) {
  537. mesh->connect_changed(callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures));
  538. }
  539. emit_changed();
  540. }
  541. Ref<Mesh> VisualShaderNodeParticleMeshEmitter::get_mesh() const {
  542. return mesh;
  543. }
  544. void VisualShaderNodeParticleMeshEmitter::set_use_all_surfaces(bool p_enabled) {
  545. if (use_all_surfaces == p_enabled) {
  546. return;
  547. }
  548. use_all_surfaces = p_enabled;
  549. emit_changed();
  550. }
  551. bool VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces() const {
  552. return use_all_surfaces;
  553. }
  554. void VisualShaderNodeParticleMeshEmitter::set_surface_index(int p_surface_index) {
  555. if (mesh.is_valid()) {
  556. if (mesh->get_surface_count() > 0) {
  557. p_surface_index = CLAMP(p_surface_index, 0, mesh->get_surface_count() - 1);
  558. } else {
  559. p_surface_index = 0;
  560. }
  561. } else if (p_surface_index < 0) {
  562. p_surface_index = 0;
  563. }
  564. if (surface_index == p_surface_index) {
  565. return;
  566. }
  567. surface_index = p_surface_index;
  568. emit_changed();
  569. }
  570. int VisualShaderNodeParticleMeshEmitter::get_surface_index() const {
  571. return surface_index;
  572. }
  573. Vector<StringName> VisualShaderNodeParticleMeshEmitter::get_editable_properties() const {
  574. Vector<StringName> props = VisualShaderNodeParticleEmitter::get_editable_properties();
  575. props.push_back("mesh");
  576. props.push_back("use_all_surfaces");
  577. if (!use_all_surfaces) {
  578. props.push_back("surface_index");
  579. }
  580. return props;
  581. }
  582. HashMap<StringName, String> VisualShaderNodeParticleMeshEmitter::get_editable_properties_names() const {
  583. HashMap<StringName, String> names = VisualShaderNodeParticleEmitter::get_editable_properties_names();
  584. names.insert("mesh", RTR("Mesh"));
  585. names.insert("use_all_surfaces", RTR("Use All Surfaces"));
  586. if (!use_all_surfaces) {
  587. names.insert("surface_index", RTR("Surface Index"));
  588. }
  589. return names;
  590. }
  591. void VisualShaderNodeParticleMeshEmitter::_bind_methods() {
  592. ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &VisualShaderNodeParticleMeshEmitter::set_mesh);
  593. ClassDB::bind_method(D_METHOD("get_mesh"), &VisualShaderNodeParticleMeshEmitter::get_mesh);
  594. ClassDB::bind_method(D_METHOD("set_use_all_surfaces", "enabled"), &VisualShaderNodeParticleMeshEmitter::set_use_all_surfaces);
  595. ClassDB::bind_method(D_METHOD("is_use_all_surfaces"), &VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces);
  596. ClassDB::bind_method(D_METHOD("set_surface_index", "surface_index"), &VisualShaderNodeParticleMeshEmitter::set_surface_index);
  597. ClassDB::bind_method(D_METHOD("get_surface_index"), &VisualShaderNodeParticleMeshEmitter::get_surface_index);
  598. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
  599. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_all_surfaces"), "set_use_all_surfaces", "is_use_all_surfaces");
  600. ADD_PROPERTY(PropertyInfo(Variant::INT, "surface_index"), "set_surface_index", "get_surface_index");
  601. }
  602. VisualShaderNodeParticleMeshEmitter::VisualShaderNodeParticleMeshEmitter() {
  603. connect_changed(callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures));
  604. position_texture.instantiate();
  605. normal_texture.instantiate();
  606. color_texture.instantiate();
  607. uv_texture.instantiate();
  608. uv2_texture.instantiate();
  609. simple_decl = false;
  610. }
  611. // VisualShaderNodeParticleMultiplyByAxisAngle
  612. void VisualShaderNodeParticleMultiplyByAxisAngle::_bind_methods() {
  613. ClassDB::bind_method(D_METHOD("set_degrees_mode", "enabled"), &VisualShaderNodeParticleMultiplyByAxisAngle::set_degrees_mode);
  614. ClassDB::bind_method(D_METHOD("is_degrees_mode"), &VisualShaderNodeParticleMultiplyByAxisAngle::is_degrees_mode);
  615. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "degrees_mode"), "set_degrees_mode", "is_degrees_mode");
  616. }
  617. String VisualShaderNodeParticleMultiplyByAxisAngle::get_caption() const {
  618. return "MultiplyByAxisAngle";
  619. }
  620. int VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_count() const {
  621. return 3;
  622. }
  623. VisualShaderNodeParticleMultiplyByAxisAngle::PortType VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_type(int p_port) const {
  624. if (p_port == 0 || p_port == 1) { // position, rotation_axis
  625. return PORT_TYPE_VECTOR_3D;
  626. }
  627. return PORT_TYPE_SCALAR; // angle (degrees/radians)
  628. }
  629. String VisualShaderNodeParticleMultiplyByAxisAngle::get_input_port_name(int p_port) const {
  630. if (p_port == 0) {
  631. return "position";
  632. }
  633. if (p_port == 1) {
  634. return "axis";
  635. }
  636. if (p_port == 2) {
  637. if (degrees_mode) {
  638. return "angle (degrees)";
  639. } else {
  640. return "angle (radians)";
  641. }
  642. }
  643. return String();
  644. }
  645. bool VisualShaderNodeParticleMultiplyByAxisAngle::is_show_prop_names() const {
  646. return true;
  647. }
  648. int VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_count() const {
  649. return 1;
  650. }
  651. VisualShaderNodeParticleMultiplyByAxisAngle::PortType VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_type(int p_port) const {
  652. return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
  653. }
  654. String VisualShaderNodeParticleMultiplyByAxisAngle::get_output_port_name(int p_port) const {
  655. return "position";
  656. }
  657. String VisualShaderNodeParticleMultiplyByAxisAngle::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  658. String code;
  659. if (degrees_mode) {
  660. code += " " + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", radians(" + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ")) * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
  661. } else {
  662. code += " " + p_output_vars[0] + " = __build_rotation_mat3(" + (p_input_vars[1].is_empty() ? ("vec3" + (String)get_input_port_default_value(1)) : p_input_vars[1]) + ", " + (p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]) + ") * " + (p_input_vars[0].is_empty() ? "vec3(0.0)" : p_input_vars[0]) + ";\n";
  663. }
  664. return code;
  665. }
  666. void VisualShaderNodeParticleMultiplyByAxisAngle::set_degrees_mode(bool p_enabled) {
  667. degrees_mode = p_enabled;
  668. emit_changed();
  669. }
  670. bool VisualShaderNodeParticleMultiplyByAxisAngle::is_degrees_mode() const {
  671. return degrees_mode;
  672. }
  673. Vector<StringName> VisualShaderNodeParticleMultiplyByAxisAngle::get_editable_properties() const {
  674. Vector<StringName> props;
  675. props.push_back("degrees_mode");
  676. return props;
  677. }
  678. bool VisualShaderNodeParticleMultiplyByAxisAngle::has_output_port_preview(int p_port) const {
  679. return false;
  680. }
  681. VisualShaderNodeParticleMultiplyByAxisAngle::VisualShaderNodeParticleMultiplyByAxisAngle() {
  682. set_input_port_default_value(1, Vector3(1, 0, 0));
  683. set_input_port_default_value(2, 0.0);
  684. }
  685. // VisualShaderNodeParticleConeVelocity
  686. String VisualShaderNodeParticleConeVelocity::get_caption() const {
  687. return "ConeVelocity";
  688. }
  689. int VisualShaderNodeParticleConeVelocity::get_input_port_count() const {
  690. return 2;
  691. }
  692. VisualShaderNodeParticleConeVelocity::PortType VisualShaderNodeParticleConeVelocity::get_input_port_type(int p_port) const {
  693. if (p_port == 0) {
  694. return PORT_TYPE_VECTOR_3D;
  695. } else if (p_port == 1) {
  696. return PORT_TYPE_SCALAR;
  697. }
  698. return PORT_TYPE_SCALAR;
  699. }
  700. String VisualShaderNodeParticleConeVelocity::get_input_port_name(int p_port) const {
  701. if (p_port == 0) {
  702. return "direction";
  703. } else if (p_port == 1) {
  704. return "spread(degrees)";
  705. }
  706. return String();
  707. }
  708. int VisualShaderNodeParticleConeVelocity::get_output_port_count() const {
  709. return 1;
  710. }
  711. VisualShaderNodeParticleConeVelocity::PortType VisualShaderNodeParticleConeVelocity::get_output_port_type(int p_port) const {
  712. return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
  713. }
  714. String VisualShaderNodeParticleConeVelocity::get_output_port_name(int p_port) const {
  715. if (p_port == 0) {
  716. return "velocity";
  717. }
  718. return String();
  719. }
  720. bool VisualShaderNodeParticleConeVelocity::has_output_port_preview(int p_port) const {
  721. return false;
  722. }
  723. String VisualShaderNodeParticleConeVelocity::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  724. String code;
  725. code += " {\n";
  726. code += " float __radians = radians(" + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ");\n";
  727. code += " float __scalar_buff1 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
  728. code += " float __scalar_buff2 = __rand_from_seed_m1_p1(__seed) * __radians;\n";
  729. code += " vec3 __vec3_buff1 = " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + ";\n";
  730. code += " __scalar_buff1 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.x, __vec3_buff1.z) : sign(__vec3_buff1.x) * (PI / 2.0);\n";
  731. code += " __scalar_buff2 += __vec3_buff1.z != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.z)) : (__vec3_buff1.x != 0.0 ? atan(__vec3_buff1.y, abs(__vec3_buff1.x)) : sign(__vec3_buff1.y) * (PI / 2.0));\n";
  732. code += " __vec3_buff1 = vec3(sin(__scalar_buff1), 0.0, cos(__scalar_buff1));\n";
  733. code += " vec3 __vec3_buff2 = vec3(0.0, sin(__scalar_buff2), cos(__scalar_buff2));\n";
  734. code += " __vec3_buff2.z = __vec3_buff2.z / max(0.0001, sqrt(abs(__vec3_buff2.z)));\n";
  735. code += " " + p_output_vars[0] + " = normalize(vec3(__vec3_buff1.x * __vec3_buff2.z, __vec3_buff2.y, __vec3_buff1.z * __vec3_buff2.z));\n";
  736. code += " }\n";
  737. return code;
  738. }
  739. VisualShaderNodeParticleConeVelocity::VisualShaderNodeParticleConeVelocity() {
  740. set_input_port_default_value(0, Vector3(1, 0, 0));
  741. set_input_port_default_value(1, 45.0);
  742. simple_decl = false;
  743. }
  744. // VisualShaderNodeParticleRandomness
  745. void VisualShaderNodeParticleRandomness::_bind_methods() {
  746. ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeParticleRandomness::set_op_type);
  747. ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeParticleRandomness::get_op_type);
  748. ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3,Vector4"), "set_op_type", "get_op_type");
  749. BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
  750. BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
  751. BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
  752. BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_4D);
  753. BIND_ENUM_CONSTANT(OP_TYPE_MAX);
  754. }
  755. Vector<StringName> VisualShaderNodeParticleRandomness::get_editable_properties() const {
  756. Vector<StringName> props;
  757. props.push_back("op_type");
  758. return props;
  759. }
  760. String VisualShaderNodeParticleRandomness::get_caption() const {
  761. return "ParticleRandomness";
  762. }
  763. int VisualShaderNodeParticleRandomness::get_output_port_count() const {
  764. return 1;
  765. }
  766. VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_output_port_type(int p_port) const {
  767. switch (op_type) {
  768. case OP_TYPE_VECTOR_2D:
  769. return p_port == 0 ? PORT_TYPE_VECTOR_2D : PORT_TYPE_SCALAR;
  770. case OP_TYPE_VECTOR_3D:
  771. return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
  772. case OP_TYPE_VECTOR_4D:
  773. return p_port == 0 ? PORT_TYPE_VECTOR_4D : PORT_TYPE_SCALAR;
  774. default:
  775. break;
  776. }
  777. return PORT_TYPE_SCALAR;
  778. }
  779. String VisualShaderNodeParticleRandomness::get_output_port_name(int p_port) const {
  780. return "random";
  781. }
  782. int VisualShaderNodeParticleRandomness::get_input_port_count() const {
  783. return 3;
  784. }
  785. VisualShaderNodeParticleRandomness::PortType VisualShaderNodeParticleRandomness::get_input_port_type(int p_port) const {
  786. switch (p_port) {
  787. case 0:
  788. return PORT_TYPE_SCALAR_UINT;
  789. case 1:
  790. case 2:
  791. switch (op_type) {
  792. case OP_TYPE_VECTOR_2D:
  793. return PORT_TYPE_VECTOR_2D;
  794. case OP_TYPE_VECTOR_3D:
  795. return PORT_TYPE_VECTOR_3D;
  796. case OP_TYPE_VECTOR_4D:
  797. return PORT_TYPE_VECTOR_4D;
  798. default:
  799. break;
  800. }
  801. break;
  802. }
  803. return PORT_TYPE_SCALAR;
  804. }
  805. String VisualShaderNodeParticleRandomness::get_input_port_name(int p_port) const {
  806. switch (p_port) {
  807. case 0:
  808. return "seed";
  809. case 1:
  810. return "min";
  811. case 2:
  812. return "max";
  813. }
  814. return String();
  815. }
  816. bool VisualShaderNodeParticleRandomness::is_input_port_default(int p_port, Shader::Mode p_mode) const {
  817. return p_port == 0; // seed
  818. }
  819. String VisualShaderNodeParticleRandomness::generate_global_per_node(Shader::Mode p_mode, int p_id) const {
  820. String code;
  821. code += "vec2 __randv2_range(inout uint seed, vec2 from, vec2 to) {\n";
  822. code += " return vec2(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y));\n";
  823. code += "}\n\n";
  824. code += "vec3 __randv3_range(inout uint seed, vec3 from, vec3 to) {\n";
  825. code += " return vec3(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z));\n";
  826. code += "}\n\n";
  827. code += "vec4 __randv4_range(inout uint seed, vec4 from, vec4 to) {\n";
  828. code += " return vec4(__randf_range(seed, from.x, to.x), __randf_range(seed, from.y, to.y), __randf_range(seed, from.z, to.z), __randf_range(seed, from.w, to.w));\n";
  829. code += "}\n\n";
  830. return code;
  831. }
  832. String VisualShaderNodeParticleRandomness::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  833. static const char *func[(int)OP_TYPE_MAX] = { "__randf_range", "__randv2_range", "__randv3_range", "__randv4_range" };
  834. return vformat(" %s = %s(%s, %s, %s);\n", p_output_vars[0], func[op_type], p_input_vars[0].is_empty() ? "__seed" : p_input_vars[0], p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1], p_input_vars[2].is_empty() ? (String)get_input_port_default_value(2) : p_input_vars[2]);
  835. }
  836. void VisualShaderNodeParticleRandomness::set_op_type(OpType p_op_type) {
  837. ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
  838. if (op_type == p_op_type) {
  839. return;
  840. }
  841. switch (p_op_type) {
  842. case OP_TYPE_SCALAR: {
  843. set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
  844. set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
  845. } break;
  846. case OP_TYPE_VECTOR_2D: {
  847. set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
  848. set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
  849. } break;
  850. case OP_TYPE_VECTOR_3D: {
  851. set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
  852. set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
  853. } break;
  854. case OP_TYPE_VECTOR_4D: {
  855. set_input_port_default_value(1, Quaternion(), get_input_port_default_value(1));
  856. set_input_port_default_value(2, Quaternion(), get_input_port_default_value(2));
  857. } break;
  858. default:
  859. break;
  860. }
  861. op_type = p_op_type;
  862. emit_changed();
  863. }
  864. VisualShaderNodeParticleRandomness::OpType VisualShaderNodeParticleRandomness::get_op_type() const {
  865. return op_type;
  866. }
  867. bool VisualShaderNodeParticleRandomness::has_output_port_preview(int p_port) const {
  868. return false;
  869. }
  870. VisualShaderNodeParticleRandomness::VisualShaderNodeParticleRandomness() {
  871. set_input_port_default_value(1, -1.0);
  872. set_input_port_default_value(2, 1.0);
  873. }
  874. // VisualShaderNodeParticleAccelerator
  875. void VisualShaderNodeParticleAccelerator::_bind_methods() {
  876. ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VisualShaderNodeParticleAccelerator::set_mode);
  877. ClassDB::bind_method(D_METHOD("get_mode"), &VisualShaderNodeParticleAccelerator::get_mode);
  878. ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Linear,Radial,Tangential"), "set_mode", "get_mode");
  879. BIND_ENUM_CONSTANT(MODE_LINEAR);
  880. BIND_ENUM_CONSTANT(MODE_RADIAL)
  881. BIND_ENUM_CONSTANT(MODE_TANGENTIAL);
  882. BIND_ENUM_CONSTANT(MODE_MAX);
  883. }
  884. Vector<StringName> VisualShaderNodeParticleAccelerator::get_editable_properties() const {
  885. Vector<StringName> props;
  886. props.push_back("mode");
  887. return props;
  888. }
  889. String VisualShaderNodeParticleAccelerator::get_caption() const {
  890. return "ParticleAccelerator";
  891. }
  892. int VisualShaderNodeParticleAccelerator::get_output_port_count() const {
  893. return 1;
  894. }
  895. VisualShaderNodeParticleAccelerator::PortType VisualShaderNodeParticleAccelerator::get_output_port_type(int p_port) const {
  896. return p_port == 0 ? PORT_TYPE_VECTOR_3D : PORT_TYPE_SCALAR;
  897. }
  898. String VisualShaderNodeParticleAccelerator::get_output_port_name(int p_port) const {
  899. return String();
  900. }
  901. int VisualShaderNodeParticleAccelerator::get_input_port_count() const {
  902. return 3;
  903. }
  904. VisualShaderNodeParticleAccelerator::PortType VisualShaderNodeParticleAccelerator::get_input_port_type(int p_port) const {
  905. if (p_port == 0) {
  906. return PORT_TYPE_VECTOR_3D;
  907. } else if (p_port == 1) {
  908. return PORT_TYPE_SCALAR;
  909. } else if (p_port == 2) {
  910. return PORT_TYPE_VECTOR_3D;
  911. }
  912. return PORT_TYPE_SCALAR;
  913. }
  914. String VisualShaderNodeParticleAccelerator::get_input_port_name(int p_port) const {
  915. if (p_port == 0) {
  916. return "amount";
  917. } else if (p_port == 1) {
  918. return "randomness";
  919. } else if (p_port == 2) {
  920. return "axis";
  921. }
  922. return String();
  923. }
  924. String VisualShaderNodeParticleAccelerator::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  925. String code;
  926. code += " {\n";
  927. switch (mode) {
  928. case MODE_LINEAR:
  929. code += " " + p_output_vars[0] + " = length(VELOCITY) > 0.0 ? " + "normalize(VELOCITY) * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
  930. break;
  931. case MODE_RADIAL:
  932. code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
  933. code += " vec3 __ndiff = normalize(__diff);\n\n";
  934. code += " " + p_output_vars[0] + " = length(__diff) > 0.0 ? __ndiff * " + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ") : vec3(0.0);\n";
  935. break;
  936. case MODE_TANGENTIAL:
  937. code += " vec3 __diff = TRANSFORM[3].xyz - EMISSION_TRANSFORM[3].xyz;\n";
  938. code += " vec3 __ndiff = normalize(__diff);\n\n";
  939. code += " vec3 __vec3_buff1 = cross(__ndiff, normalize(" + (p_input_vars[2].is_empty() ? "vec3" + (String)get_input_port_default_value(2) : p_input_vars[2]) + "));\n";
  940. code += " " + p_output_vars[0] + " = length(__vec3_buff1) > 0.0 ? normalize(__vec3_buff1) * (" + (p_input_vars[0].is_empty() ? "vec3" + (String)get_input_port_default_value(0) : p_input_vars[0]) + " * mix(1.0, __rand_from_seed(__seed), " + (p_input_vars[1].is_empty() ? (String)get_input_port_default_value(1) : p_input_vars[1]) + ")) : vec3(0.0);\n";
  941. break;
  942. default:
  943. break;
  944. }
  945. code += " }\n";
  946. return code;
  947. }
  948. void VisualShaderNodeParticleAccelerator::set_mode(Mode p_mode) {
  949. ERR_FAIL_INDEX(int(p_mode), int(MODE_MAX));
  950. if (mode == p_mode) {
  951. return;
  952. }
  953. mode = p_mode;
  954. emit_changed();
  955. }
  956. VisualShaderNodeParticleAccelerator::Mode VisualShaderNodeParticleAccelerator::get_mode() const {
  957. return mode;
  958. }
  959. bool VisualShaderNodeParticleAccelerator::has_output_port_preview(int p_port) const {
  960. return false;
  961. }
  962. VisualShaderNodeParticleAccelerator::VisualShaderNodeParticleAccelerator() {
  963. set_input_port_default_value(0, Vector3(1, 1, 1));
  964. set_input_port_default_value(1, 0.0);
  965. set_input_port_default_value(2, Vector3(0, -9.8, 0));
  966. simple_decl = false;
  967. }
  968. // VisualShaderNodeParticleOutput
  969. String VisualShaderNodeParticleOutput::get_caption() const {
  970. switch (shader_type) {
  971. case VisualShader::TYPE_START:
  972. return "StartOutput";
  973. case VisualShader::TYPE_PROCESS:
  974. return "ProcessOutput";
  975. case VisualShader::TYPE_COLLIDE:
  976. return "CollideOutput";
  977. case VisualShader::TYPE_START_CUSTOM:
  978. return "CustomStartOutput";
  979. case VisualShader::TYPE_PROCESS_CUSTOM:
  980. return "CustomProcessOutput";
  981. default:
  982. ERR_PRINT(vformat("Unexpected shader_type %d for VisualShaderNodeParticleOutput.", shader_type));
  983. return "";
  984. }
  985. }
  986. int VisualShaderNodeParticleOutput::get_input_port_count() const {
  987. switch (shader_type) {
  988. case VisualShader::TYPE_START:
  989. return 8;
  990. case VisualShader::TYPE_PROCESS:
  991. return 7;
  992. case VisualShader::TYPE_COLLIDE:
  993. return 5;
  994. case VisualShader::TYPE_START_CUSTOM:
  995. case VisualShader::TYPE_PROCESS_CUSTOM:
  996. return 6;
  997. default:
  998. ERR_PRINT(vformat("Unexpected shader_type %d for VisualShaderNodeParticleOutput.", shader_type));
  999. return 0;
  1000. }
  1001. }
  1002. VisualShaderNodeParticleOutput::PortType VisualShaderNodeParticleOutput::get_input_port_type(int p_port) const {
  1003. switch (p_port) {
  1004. case 0:
  1005. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1006. return PORT_TYPE_VECTOR_3D; // custom.rgb
  1007. }
  1008. return PORT_TYPE_BOOLEAN; // active
  1009. case 1:
  1010. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1011. break; // custom.a (scalar)
  1012. }
  1013. return PORT_TYPE_VECTOR_3D; // velocity
  1014. case 2:
  1015. return PORT_TYPE_VECTOR_3D; // color & velocity
  1016. case 3:
  1017. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1018. return PORT_TYPE_VECTOR_3D; // color
  1019. }
  1020. break; // alpha (scalar)
  1021. case 4:
  1022. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1023. break; // alpha
  1024. }
  1025. if (shader_type == VisualShader::TYPE_PROCESS) {
  1026. break; // scale
  1027. }
  1028. if (shader_type == VisualShader::TYPE_COLLIDE) {
  1029. return PORT_TYPE_TRANSFORM; // transform
  1030. }
  1031. return PORT_TYPE_VECTOR_3D; // position
  1032. case 5:
  1033. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1034. return PORT_TYPE_TRANSFORM; // transform
  1035. }
  1036. if (shader_type == VisualShader::TYPE_PROCESS) {
  1037. return PORT_TYPE_VECTOR_3D; // rotation_axis
  1038. }
  1039. break; // scale (scalar)
  1040. case 6:
  1041. if (shader_type == VisualShader::TYPE_START) {
  1042. return PORT_TYPE_VECTOR_3D; // rotation_axis
  1043. }
  1044. break;
  1045. case 7:
  1046. break; // angle (scalar)
  1047. }
  1048. return PORT_TYPE_SCALAR;
  1049. }
  1050. String VisualShaderNodeParticleOutput::get_input_port_name(int p_port) const {
  1051. String port_name;
  1052. switch (p_port) {
  1053. case 0:
  1054. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1055. port_name = "custom";
  1056. break;
  1057. }
  1058. port_name = "active";
  1059. break;
  1060. case 1:
  1061. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1062. port_name = "custom_alpha";
  1063. break;
  1064. }
  1065. port_name = "velocity";
  1066. break;
  1067. case 2:
  1068. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1069. port_name = "velocity";
  1070. break;
  1071. }
  1072. port_name = "color";
  1073. break;
  1074. case 3:
  1075. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1076. port_name = "color";
  1077. break;
  1078. }
  1079. port_name = "alpha";
  1080. break;
  1081. case 4:
  1082. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1083. port_name = "alpha";
  1084. break;
  1085. }
  1086. if (shader_type == VisualShader::TYPE_PROCESS) {
  1087. port_name = "scale";
  1088. break;
  1089. }
  1090. if (shader_type == VisualShader::TYPE_COLLIDE) {
  1091. port_name = "transform";
  1092. break;
  1093. }
  1094. port_name = "position";
  1095. break;
  1096. case 5:
  1097. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1098. port_name = "transform";
  1099. break;
  1100. }
  1101. if (shader_type == VisualShader::TYPE_PROCESS) {
  1102. port_name = "rotation_axis";
  1103. break;
  1104. }
  1105. port_name = "scale";
  1106. break;
  1107. case 6:
  1108. if (shader_type == VisualShader::TYPE_PROCESS) {
  1109. port_name = "angle_in_radians";
  1110. break;
  1111. }
  1112. port_name = "rotation_axis";
  1113. break;
  1114. case 7:
  1115. port_name = "angle_in_radians";
  1116. break;
  1117. default:
  1118. break;
  1119. }
  1120. if (!port_name.is_empty()) {
  1121. return port_name.capitalize();
  1122. }
  1123. return String();
  1124. }
  1125. bool VisualShaderNodeParticleOutput::is_port_separator(int p_index) const {
  1126. if (shader_type == VisualShader::TYPE_START || shader_type == VisualShader::TYPE_PROCESS) {
  1127. String port_name = get_input_port_name(p_index);
  1128. return bool(port_name == "Scale");
  1129. }
  1130. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1131. String port_name = get_input_port_name(p_index);
  1132. return bool(port_name == "Velocity");
  1133. }
  1134. return false;
  1135. }
  1136. String VisualShaderNodeParticleOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  1137. String code;
  1138. String tab = " ";
  1139. if (shader_type == VisualShader::TYPE_START_CUSTOM || shader_type == VisualShader::TYPE_PROCESS_CUSTOM) {
  1140. if (!p_input_vars[0].is_empty()) { // custom.rgb
  1141. code += tab + "CUSTOM.rgb = " + p_input_vars[0] + ";\n";
  1142. }
  1143. if (!p_input_vars[1].is_empty()) { // custom.a
  1144. code += tab + "CUSTOM.a = " + p_input_vars[1] + ";\n";
  1145. }
  1146. if (!p_input_vars[2].is_empty()) { // velocity
  1147. code += tab + "VELOCITY = " + p_input_vars[2] + ";\n";
  1148. }
  1149. if (!p_input_vars[3].is_empty()) { // color.rgb
  1150. code += tab + "COLOR.rgb = " + p_input_vars[3] + ";\n";
  1151. }
  1152. if (!p_input_vars[4].is_empty()) { // color.a
  1153. code += tab + "COLOR.a = " + p_input_vars[4] + ";\n";
  1154. }
  1155. if (!p_input_vars[5].is_empty()) { // transform
  1156. code += tab + "TRANSFORM = " + p_input_vars[5] + ";\n";
  1157. }
  1158. } else {
  1159. if (!p_input_vars[0].is_empty()) { // Active (begin).
  1160. code += tab + "ACTIVE = " + p_input_vars[0] + ";\n";
  1161. code += tab + "if(ACTIVE) {\n";
  1162. tab += " ";
  1163. }
  1164. if (!p_input_vars[1].is_empty()) { // velocity
  1165. code += tab + "VELOCITY = " + p_input_vars[1] + ";\n";
  1166. }
  1167. if (!p_input_vars[2].is_empty()) { // color
  1168. code += tab + "COLOR.rgb = " + p_input_vars[2] + ";\n";
  1169. }
  1170. if (!p_input_vars[3].is_empty()) { // alpha
  1171. code += tab + "COLOR.a = " + p_input_vars[3] + ";\n";
  1172. }
  1173. // position
  1174. if (shader_type == VisualShader::TYPE_START) {
  1175. code += tab + "if (RESTART_POSITION) {\n";
  1176. if (!p_input_vars[4].is_empty()) {
  1177. code += tab + " TRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(" + p_input_vars[4] + ", 1.0));\n";
  1178. } else {
  1179. code += tab + " TRANSFORM = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
  1180. }
  1181. code += tab + " if (RESTART_VELOCITY) {\n";
  1182. code += tab + " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
  1183. code += tab + " }\n";
  1184. code += tab + " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
  1185. code += tab + "}\n";
  1186. } else if (shader_type == VisualShader::TYPE_COLLIDE) { // position
  1187. if (!p_input_vars[4].is_empty()) {
  1188. code += tab + "TRANSFORM = " + p_input_vars[4] + ";\n";
  1189. }
  1190. }
  1191. if (shader_type == VisualShader::TYPE_START || shader_type == VisualShader::TYPE_PROCESS) {
  1192. int scale = 5;
  1193. int rotation_axis = 6;
  1194. int rotation = 7;
  1195. if (shader_type == VisualShader::TYPE_PROCESS) {
  1196. scale = 4;
  1197. rotation_axis = 5;
  1198. rotation = 6;
  1199. }
  1200. String op;
  1201. if (shader_type == VisualShader::TYPE_START) {
  1202. op = "*=";
  1203. } else {
  1204. op = "=";
  1205. }
  1206. if (!p_input_vars[rotation].is_empty()) { // rotation_axis & angle_in_radians
  1207. String axis;
  1208. if (p_input_vars[rotation_axis].is_empty()) {
  1209. axis = "vec3(0, 1, 0)";
  1210. } else {
  1211. axis = p_input_vars[rotation_axis];
  1212. }
  1213. code += tab + "TRANSFORM " + op + " __build_rotation_mat4(" + axis + ", " + p_input_vars[rotation] + ");\n";
  1214. }
  1215. if (!p_input_vars[scale].is_empty()) { // scale
  1216. code += tab + "TRANSFORM " + op + " mat4(vec4(" + p_input_vars[scale] + ", 0, 0, 0), vec4(0, " + p_input_vars[scale] + ", 0, 0), vec4(0, 0, " + p_input_vars[scale] + ", 0), vec4(0, 0, 0, 1));\n";
  1217. }
  1218. }
  1219. if (!p_input_vars[0].is_empty()) { // Active (end).
  1220. code += " }\n";
  1221. }
  1222. }
  1223. return code;
  1224. }
  1225. VisualShaderNodeParticleOutput::VisualShaderNodeParticleOutput() {
  1226. }
  1227. // EmitParticle
  1228. Vector<StringName> VisualShaderNodeParticleEmit::get_editable_properties() const {
  1229. Vector<StringName> props;
  1230. props.push_back("flags");
  1231. return props;
  1232. }
  1233. void VisualShaderNodeParticleEmit::_bind_methods() {
  1234. ClassDB::bind_method(D_METHOD("set_flags", "flags"), &VisualShaderNodeParticleEmit::set_flags);
  1235. ClassDB::bind_method(D_METHOD("get_flags"), &VisualShaderNodeParticleEmit::get_flags);
  1236. ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Position,RotScale,Velocity,Color,Custom"), "set_flags", "get_flags");
  1237. BIND_ENUM_CONSTANT(EMIT_FLAG_POSITION);
  1238. BIND_ENUM_CONSTANT(EMIT_FLAG_ROT_SCALE);
  1239. BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY);
  1240. BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR);
  1241. BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM);
  1242. }
  1243. String VisualShaderNodeParticleEmit::get_caption() const {
  1244. return "EmitParticle";
  1245. }
  1246. int VisualShaderNodeParticleEmit::get_input_port_count() const {
  1247. return 7;
  1248. }
  1249. VisualShaderNodeParticleEmit::PortType VisualShaderNodeParticleEmit::get_input_port_type(int p_port) const {
  1250. switch (p_port) {
  1251. case 0:
  1252. return PORT_TYPE_BOOLEAN;
  1253. case 1:
  1254. return PORT_TYPE_TRANSFORM;
  1255. case 2:
  1256. return PORT_TYPE_VECTOR_3D;
  1257. case 3:
  1258. return PORT_TYPE_VECTOR_3D;
  1259. case 4:
  1260. return PORT_TYPE_SCALAR;
  1261. case 5:
  1262. return PORT_TYPE_VECTOR_3D;
  1263. case 6:
  1264. return PORT_TYPE_SCALAR;
  1265. }
  1266. return PORT_TYPE_SCALAR;
  1267. }
  1268. String VisualShaderNodeParticleEmit::get_input_port_name(int p_port) const {
  1269. switch (p_port) {
  1270. case 0:
  1271. return "condition";
  1272. case 1:
  1273. return "transform";
  1274. case 2:
  1275. return "velocity";
  1276. case 3:
  1277. return "color";
  1278. case 4:
  1279. return "alpha";
  1280. case 5:
  1281. return "custom";
  1282. case 6:
  1283. return "custom_alpha";
  1284. }
  1285. return String();
  1286. }
  1287. int VisualShaderNodeParticleEmit::get_output_port_count() const {
  1288. return 0;
  1289. }
  1290. VisualShaderNodeParticleEmit::PortType VisualShaderNodeParticleEmit::get_output_port_type(int p_port) const {
  1291. return PORT_TYPE_SCALAR;
  1292. }
  1293. String VisualShaderNodeParticleEmit::get_output_port_name(int p_port) const {
  1294. return String();
  1295. }
  1296. void VisualShaderNodeParticleEmit::add_flag(EmitFlags p_flag) {
  1297. flags |= p_flag;
  1298. emit_changed();
  1299. }
  1300. bool VisualShaderNodeParticleEmit::has_flag(EmitFlags p_flag) const {
  1301. return flags & p_flag;
  1302. }
  1303. void VisualShaderNodeParticleEmit::set_flags(EmitFlags p_flags) {
  1304. flags = (int)p_flags;
  1305. emit_changed();
  1306. }
  1307. VisualShaderNodeParticleEmit::EmitFlags VisualShaderNodeParticleEmit::get_flags() const {
  1308. return EmitFlags(flags);
  1309. }
  1310. bool VisualShaderNodeParticleEmit::is_show_prop_names() const {
  1311. return true;
  1312. }
  1313. bool VisualShaderNodeParticleEmit::is_generate_input_var(int p_port) const {
  1314. if (p_port == 0) {
  1315. if (!is_input_port_connected(0)) {
  1316. return false;
  1317. }
  1318. }
  1319. return true;
  1320. }
  1321. bool VisualShaderNodeParticleEmit::is_input_port_default(int p_port, Shader::Mode p_mode) const {
  1322. switch (p_port) {
  1323. case 1:
  1324. return true;
  1325. case 2:
  1326. return true;
  1327. case 3:
  1328. return true;
  1329. case 4:
  1330. return true;
  1331. case 5:
  1332. return true;
  1333. case 6:
  1334. return true;
  1335. }
  1336. return false;
  1337. }
  1338. String VisualShaderNodeParticleEmit::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
  1339. String code;
  1340. String tab;
  1341. bool default_condition = false;
  1342. if (!is_input_port_connected(0)) {
  1343. default_condition = true;
  1344. if (get_input_port_default_value(0)) {
  1345. tab = " ";
  1346. } else {
  1347. return code;
  1348. }
  1349. } else {
  1350. tab = " ";
  1351. }
  1352. String transform;
  1353. if (p_input_vars[1].is_empty()) {
  1354. transform = "TRANSFORM";
  1355. } else {
  1356. transform = p_input_vars[1];
  1357. }
  1358. String velocity;
  1359. if (p_input_vars[2].is_empty()) {
  1360. velocity = "VELOCITY";
  1361. } else {
  1362. velocity = p_input_vars[2];
  1363. }
  1364. String color;
  1365. if (p_input_vars[3].is_empty()) {
  1366. color = "COLOR.rgb";
  1367. } else {
  1368. color = p_input_vars[3];
  1369. }
  1370. String alpha;
  1371. if (p_input_vars[4].is_empty()) {
  1372. alpha = "COLOR.a";
  1373. } else {
  1374. alpha = p_input_vars[4];
  1375. }
  1376. String custom;
  1377. if (p_input_vars[5].is_empty()) {
  1378. custom = "CUSTOM.rgb";
  1379. } else {
  1380. custom = p_input_vars[5];
  1381. }
  1382. String custom_alpha;
  1383. if (p_input_vars[6].is_empty()) {
  1384. custom_alpha = "CUSTOM.a";
  1385. } else {
  1386. custom_alpha = p_input_vars[6];
  1387. }
  1388. List<String> flags_arr;
  1389. if (has_flag(EmitFlags::EMIT_FLAG_POSITION)) {
  1390. flags_arr.push_back("FLAG_EMIT_POSITION");
  1391. }
  1392. if (has_flag(EmitFlags::EMIT_FLAG_ROT_SCALE)) {
  1393. flags_arr.push_back("FLAG_EMIT_ROT_SCALE");
  1394. }
  1395. if (has_flag(EmitFlags::EMIT_FLAG_VELOCITY)) {
  1396. flags_arr.push_back("FLAG_EMIT_VELOCITY");
  1397. }
  1398. if (has_flag(EmitFlags::EMIT_FLAG_COLOR)) {
  1399. flags_arr.push_back("FLAG_EMIT_COLOR");
  1400. }
  1401. if (has_flag(EmitFlags::EMIT_FLAG_CUSTOM)) {
  1402. flags_arr.push_back("FLAG_EMIT_CUSTOM");
  1403. }
  1404. String flags_str;
  1405. for (List<String>::ConstIterator itr = flags_arr.begin(); itr != flags_arr.end(); ++itr) {
  1406. if (itr != flags_arr.begin()) {
  1407. flags_str += "|";
  1408. }
  1409. flags_str += *itr;
  1410. }
  1411. if (flags_str.is_empty()) {
  1412. flags_str = "uint(0)";
  1413. }
  1414. if (!default_condition) {
  1415. code += " if (" + p_input_vars[0] + ") {\n";
  1416. }
  1417. code += tab + "emit_subparticle(" + transform + ", " + velocity + ", vec4(" + color + ", " + alpha + "), vec4(" + custom + ", " + custom_alpha + "), " + flags_str + ");\n";
  1418. if (!default_condition) {
  1419. code += " }\n";
  1420. }
  1421. return code;
  1422. }
  1423. VisualShaderNodeParticleEmit::VisualShaderNodeParticleEmit() {
  1424. set_input_port_default_value(0, true);
  1425. }