particles_storage.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437
  1. /**************************************************************************/
  2. /* particles_storage.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. #ifdef GLES3_ENABLED
  31. #include "particles_storage.h"
  32. #include "config.h"
  33. #include "material_storage.h"
  34. #include "mesh_storage.h"
  35. #include "texture_storage.h"
  36. #include "utilities.h"
  37. #include "servers/rendering/rendering_server_globals.h"
  38. using namespace GLES3;
  39. ParticlesStorage *ParticlesStorage::singleton = nullptr;
  40. ParticlesStorage *ParticlesStorage::get_singleton() {
  41. return singleton;
  42. }
  43. ParticlesStorage::ParticlesStorage() {
  44. singleton = this;
  45. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  46. {
  47. String global_defines;
  48. global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
  49. material_storage->shaders.particles_process_shader.initialize(global_defines, 1);
  50. }
  51. {
  52. // default material and shader for particles shader
  53. particles_shader.default_shader = material_storage->shader_allocate();
  54. material_storage->shader_initialize(particles_shader.default_shader);
  55. material_storage->shader_set_code(particles_shader.default_shader, R"(
  56. // Default particles shader.
  57. shader_type particles;
  58. void process() {
  59. COLOR = vec4(1.0);
  60. }
  61. )");
  62. particles_shader.default_material = material_storage->material_allocate();
  63. material_storage->material_initialize(particles_shader.default_material);
  64. material_storage->material_set_shader(particles_shader.default_material, particles_shader.default_shader);
  65. }
  66. {
  67. particles_shader.copy_shader.initialize();
  68. particles_shader.copy_shader_version = particles_shader.copy_shader.version_create();
  69. }
  70. }
  71. ParticlesStorage::~ParticlesStorage() {
  72. singleton = nullptr;
  73. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  74. material_storage->material_free(particles_shader.default_material);
  75. material_storage->shader_free(particles_shader.default_shader);
  76. particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
  77. }
  78. /* PARTICLES */
  79. RID ParticlesStorage::particles_allocate() {
  80. return particles_owner.allocate_rid();
  81. }
  82. void ParticlesStorage::particles_initialize(RID p_rid) {
  83. particles_owner.initialize_rid(p_rid);
  84. }
  85. void ParticlesStorage::particles_free(RID p_rid) {
  86. Particles *particles = particles_owner.get_or_null(p_rid);
  87. particles->dependency.deleted_notify(p_rid);
  88. particles->update_list.remove_from_list();
  89. _particles_free_data(particles);
  90. particles_owner.free(p_rid);
  91. }
  92. void ParticlesStorage::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) {
  93. Particles *particles = particles_owner.get_or_null(p_particles);
  94. ERR_FAIL_NULL(particles);
  95. if (particles->mode == p_mode) {
  96. return;
  97. }
  98. _particles_free_data(particles);
  99. particles->mode = p_mode;
  100. }
  101. void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) {
  102. ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->disable_particles_workaround, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead.");
  103. Particles *particles = particles_owner.get_or_null(p_particles);
  104. ERR_FAIL_NULL(particles);
  105. particles->emitting = p_emitting;
  106. }
  107. bool ParticlesStorage::particles_get_emitting(RID p_particles) {
  108. if (GLES3::Config::get_singleton()->disable_particles_workaround) {
  109. return false;
  110. }
  111. Particles *particles = particles_owner.get_or_null(p_particles);
  112. ERR_FAIL_NULL_V(particles, false);
  113. return particles->emitting;
  114. }
  115. void ParticlesStorage::_particles_free_data(Particles *particles) {
  116. particles->userdata_count = 0;
  117. particles->instance_buffer_size_cache = 0;
  118. particles->instance_buffer_stride_cache = 0;
  119. particles->num_attrib_arrays_cache = 0;
  120. particles->process_buffer_stride_cache = 0;
  121. if (particles->front_process_buffer != 0) {
  122. glDeleteVertexArrays(1, &particles->front_vertex_array);
  123. GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_process_buffer);
  124. GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_instance_buffer);
  125. particles->front_vertex_array = 0;
  126. particles->front_process_buffer = 0;
  127. particles->front_instance_buffer = 0;
  128. glDeleteVertexArrays(1, &particles->back_vertex_array);
  129. GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_process_buffer);
  130. GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_instance_buffer);
  131. particles->back_vertex_array = 0;
  132. particles->back_process_buffer = 0;
  133. particles->back_instance_buffer = 0;
  134. }
  135. if (particles->sort_buffer != 0) {
  136. GLES3::Utilities::get_singleton()->buffer_free_data(particles->last_frame_buffer);
  137. GLES3::Utilities::get_singleton()->buffer_free_data(particles->sort_buffer);
  138. particles->last_frame_buffer = 0;
  139. particles->sort_buffer = 0;
  140. particles->sort_buffer_filled = false;
  141. particles->last_frame_buffer_filled = false;
  142. }
  143. if (particles->frame_params_ubo != 0) {
  144. GLES3::Utilities::get_singleton()->buffer_free_data(particles->frame_params_ubo);
  145. particles->frame_params_ubo = 0;
  146. }
  147. }
  148. void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) {
  149. Particles *particles = particles_owner.get_or_null(p_particles);
  150. ERR_FAIL_NULL(particles);
  151. if (particles->amount == p_amount) {
  152. return;
  153. }
  154. _particles_free_data(particles);
  155. particles->amount = p_amount;
  156. particles->prev_ticks = 0;
  157. particles->phase = 0;
  158. particles->prev_phase = 0;
  159. particles->clear = true;
  160. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  161. }
  162. void ParticlesStorage::particles_set_amount_ratio(RID p_particles, float p_amount_ratio) {
  163. Particles *particles = particles_owner.get_or_null(p_particles);
  164. ERR_FAIL_NULL(particles);
  165. particles->amount_ratio = p_amount_ratio;
  166. }
  167. void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) {
  168. Particles *particles = particles_owner.get_or_null(p_particles);
  169. ERR_FAIL_NULL(particles);
  170. particles->lifetime = p_lifetime;
  171. }
  172. void ParticlesStorage::particles_set_one_shot(RID p_particles, bool p_one_shot) {
  173. Particles *particles = particles_owner.get_or_null(p_particles);
  174. ERR_FAIL_NULL(particles);
  175. particles->one_shot = p_one_shot;
  176. }
  177. void ParticlesStorage::particles_set_pre_process_time(RID p_particles, double p_time) {
  178. Particles *particles = particles_owner.get_or_null(p_particles);
  179. ERR_FAIL_NULL(particles);
  180. particles->pre_process_time = p_time;
  181. }
  182. void ParticlesStorage::particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) {
  183. Particles *particles = particles_owner.get_or_null(p_particles);
  184. ERR_FAIL_NULL(particles);
  185. particles->explosiveness = p_ratio;
  186. }
  187. void ParticlesStorage::particles_set_randomness_ratio(RID p_particles, real_t p_ratio) {
  188. Particles *particles = particles_owner.get_or_null(p_particles);
  189. ERR_FAIL_NULL(particles);
  190. particles->randomness = p_ratio;
  191. }
  192. void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
  193. Particles *particles = particles_owner.get_or_null(p_particles);
  194. ERR_FAIL_NULL(particles);
  195. particles->custom_aabb = p_aabb;
  196. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  197. }
  198. void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) {
  199. Particles *particles = particles_owner.get_or_null(p_particles);
  200. ERR_FAIL_NULL(particles);
  201. particles->speed_scale = p_scale;
  202. }
  203. void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
  204. Particles *particles = particles_owner.get_or_null(p_particles);
  205. ERR_FAIL_NULL(particles);
  206. particles->use_local_coords = p_enable;
  207. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  208. }
  209. void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
  210. Particles *particles = particles_owner.get_or_null(p_particles);
  211. ERR_FAIL_NULL(particles);
  212. particles->fixed_fps = p_fps;
  213. _particles_free_data(particles);
  214. particles->prev_ticks = 0;
  215. particles->phase = 0;
  216. particles->prev_phase = 0;
  217. particles->clear = true;
  218. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  219. }
  220. void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) {
  221. Particles *particles = particles_owner.get_or_null(p_particles);
  222. ERR_FAIL_NULL(particles);
  223. particles->interpolate = p_enable;
  224. }
  225. void ParticlesStorage::particles_set_fractional_delta(RID p_particles, bool p_enable) {
  226. Particles *particles = particles_owner.get_or_null(p_particles);
  227. ERR_FAIL_NULL(particles);
  228. particles->fractional_delta = p_enable;
  229. }
  230. void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, double p_length) {
  231. if (p_enable) {
  232. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle trails.");
  233. }
  234. }
  235. void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) {
  236. if (p_bind_poses.size() != 0) {
  237. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle trails.");
  238. }
  239. }
  240. void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) {
  241. Particles *particles = particles_owner.get_or_null(p_particles);
  242. ERR_FAIL_NULL(particles);
  243. particles->collision_base_size = p_size;
  244. }
  245. void ParticlesStorage::particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) {
  246. Particles *particles = particles_owner.get_or_null(p_particles);
  247. ERR_FAIL_NULL(particles);
  248. particles->transform_align = p_transform_align;
  249. }
  250. void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_material) {
  251. Particles *particles = particles_owner.get_or_null(p_particles);
  252. ERR_FAIL_NULL(particles);
  253. particles->process_material = p_material;
  254. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
  255. }
  256. RID ParticlesStorage::particles_get_process_material(RID p_particles) const {
  257. Particles *particles = particles_owner.get_or_null(p_particles);
  258. ERR_FAIL_NULL_V(particles, RID());
  259. return particles->process_material;
  260. }
  261. void ParticlesStorage::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {
  262. Particles *particles = particles_owner.get_or_null(p_particles);
  263. ERR_FAIL_NULL(particles);
  264. particles->draw_order = p_order;
  265. }
  266. void ParticlesStorage::particles_set_draw_passes(RID p_particles, int p_passes) {
  267. Particles *particles = particles_owner.get_or_null(p_particles);
  268. ERR_FAIL_NULL(particles);
  269. particles->draw_passes.resize(p_passes);
  270. }
  271. void ParticlesStorage::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
  272. Particles *particles = particles_owner.get_or_null(p_particles);
  273. ERR_FAIL_NULL(particles);
  274. ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
  275. particles->draw_passes.write[p_pass] = p_mesh;
  276. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  277. }
  278. void ParticlesStorage::particles_restart(RID p_particles) {
  279. Particles *particles = particles_owner.get_or_null(p_particles);
  280. ERR_FAIL_NULL(particles);
  281. particles->restart_request = true;
  282. }
  283. void ParticlesStorage::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
  284. if (p_subemitter_particles.is_valid()) {
  285. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle sub-emitters.");
  286. }
  287. }
  288. void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
  289. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support manually emitting particles.");
  290. }
  291. void ParticlesStorage::particles_request_process(RID p_particles) {
  292. Particles *particles = particles_owner.get_or_null(p_particles);
  293. ERR_FAIL_NULL(particles);
  294. if (!particles->dirty) {
  295. particles->dirty = true;
  296. if (!particles->update_list.in_list()) {
  297. particle_update_list.add(&particles->update_list);
  298. }
  299. }
  300. }
  301. AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) {
  302. const Particles *particles = particles_owner.get_or_null(p_particles);
  303. ERR_FAIL_NULL_V(particles, AABB());
  304. int total_amount = particles->amount;
  305. // If available, read from the sort buffer which should be 2 frames out of date.
  306. // This will help alleviate GPU stalls.
  307. GLuint read_buffer = particles->sort_buffer_filled ? particles->sort_buffer : particles->back_instance_buffer;
  308. Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, read_buffer, total_amount * sizeof(ParticleInstanceData3D));
  309. ERR_FAIL_COND_V(buffer.size() != (int)(total_amount * sizeof(ParticleInstanceData3D)), AABB());
  310. Transform3D inv = particles->emission_transform.affine_inverse();
  311. AABB aabb;
  312. if (buffer.size()) {
  313. bool first = true;
  314. const uint8_t *data_ptr = (const uint8_t *)buffer.ptr();
  315. uint32_t particle_data_size = sizeof(ParticleInstanceData3D);
  316. for (int i = 0; i < total_amount; i++) {
  317. const ParticleInstanceData3D &particle_data = *(const ParticleInstanceData3D *)&data_ptr[particle_data_size * i];
  318. // If scale is 0.0, we assume the particle is inactive.
  319. if (particle_data.xform[0] > 0.0) {
  320. Vector3 pos = Vector3(particle_data.xform[3], particle_data.xform[7], particle_data.xform[11]);
  321. if (!particles->use_local_coords) {
  322. pos = inv.xform(pos);
  323. }
  324. if (first) {
  325. aabb.position = pos;
  326. first = false;
  327. } else {
  328. aabb.expand_to(pos);
  329. }
  330. }
  331. }
  332. }
  333. float longest_axis_size = 0;
  334. for (int i = 0; i < particles->draw_passes.size(); i++) {
  335. if (particles->draw_passes[i].is_valid()) {
  336. AABB maabb = MeshStorage::get_singleton()->mesh_get_aabb(particles->draw_passes[i], RID());
  337. longest_axis_size = MAX(maabb.get_longest_axis_size(), longest_axis_size);
  338. }
  339. }
  340. aabb.grow_by(longest_axis_size);
  341. return aabb;
  342. }
  343. AABB ParticlesStorage::particles_get_aabb(RID p_particles) const {
  344. const Particles *particles = particles_owner.get_or_null(p_particles);
  345. ERR_FAIL_NULL_V(particles, AABB());
  346. return particles->custom_aabb;
  347. }
  348. void ParticlesStorage::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) {
  349. Particles *particles = particles_owner.get_or_null(p_particles);
  350. ERR_FAIL_NULL(particles);
  351. particles->emission_transform = p_transform;
  352. }
  353. void ParticlesStorage::particles_set_emitter_velocity(RID p_particles, const Vector3 &p_velocity) {
  354. Particles *particles = particles_owner.get_or_null(p_particles);
  355. ERR_FAIL_NULL(particles);
  356. particles->emitter_velocity = p_velocity;
  357. }
  358. void ParticlesStorage::particles_set_interp_to_end(RID p_particles, float p_interp) {
  359. Particles *particles = particles_owner.get_or_null(p_particles);
  360. ERR_FAIL_NULL(particles);
  361. particles->interp_to_end = p_interp;
  362. }
  363. int ParticlesStorage::particles_get_draw_passes(RID p_particles) const {
  364. const Particles *particles = particles_owner.get_or_null(p_particles);
  365. ERR_FAIL_NULL_V(particles, 0);
  366. return particles->draw_passes.size();
  367. }
  368. RID ParticlesStorage::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
  369. const Particles *particles = particles_owner.get_or_null(p_particles);
  370. ERR_FAIL_NULL_V(particles, RID());
  371. ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
  372. return particles->draw_passes[p_pass];
  373. }
  374. void ParticlesStorage::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
  375. Particles *particles = particles_owner.get_or_null(p_particles);
  376. ERR_FAIL_NULL(particles);
  377. particles->collisions.insert(p_particles_collision_instance);
  378. }
  379. void ParticlesStorage::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
  380. Particles *particles = particles_owner.get_or_null(p_particles);
  381. ERR_FAIL_NULL(particles);
  382. particles->collisions.erase(p_particles_collision_instance);
  383. }
  384. void ParticlesStorage::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, GLuint p_texture) {
  385. Particles *particles = particles_owner.get_or_null(p_particles);
  386. ERR_FAIL_NULL(particles);
  387. particles->has_sdf_collision = p_enable;
  388. particles->sdf_collision_transform = p_xform;
  389. particles->sdf_collision_to_screen = p_to_screen;
  390. particles->sdf_collision_texture = p_texture;
  391. }
  392. // Does one step of processing particles by reading from back_process_buffer and writing to front_process_buffer.
  393. void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta) {
  394. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  395. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  396. double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime) * p_particles->speed_scale, 1.0);
  397. //update current frame
  398. ParticlesFrameParams frame_params;
  399. if (p_particles->clear) {
  400. p_particles->cycle_number = 0;
  401. p_particles->random_seed = Math::rand();
  402. } else if (new_phase < p_particles->phase) {
  403. if (p_particles->one_shot) {
  404. p_particles->emitting = false;
  405. }
  406. p_particles->cycle_number++;
  407. }
  408. frame_params.emitting = p_particles->emitting;
  409. frame_params.system_phase = new_phase;
  410. frame_params.prev_system_phase = p_particles->phase;
  411. p_particles->phase = new_phase;
  412. frame_params.time = RSG::rasterizer->get_total_time();
  413. frame_params.delta = p_delta * p_particles->speed_scale;
  414. frame_params.random_seed = p_particles->random_seed;
  415. frame_params.explosiveness = p_particles->explosiveness;
  416. frame_params.randomness = p_particles->randomness;
  417. if (p_particles->use_local_coords) {
  418. GLES3::MaterialStorage::store_transform(Transform3D(), frame_params.emission_transform);
  419. } else {
  420. GLES3::MaterialStorage::store_transform(p_particles->emission_transform, frame_params.emission_transform);
  421. }
  422. frame_params.cycle = p_particles->cycle_number;
  423. frame_params.frame = p_particles->frame_counter++;
  424. frame_params.amount_ratio = p_particles->amount_ratio;
  425. frame_params.pad1 = 0;
  426. frame_params.pad2 = 0;
  427. frame_params.interp_to_end = p_particles->interp_to_end;
  428. frame_params.emitter_velocity[0] = p_particles->emitter_velocity.x;
  429. frame_params.emitter_velocity[1] = p_particles->emitter_velocity.y;
  430. frame_params.emitter_velocity[2] = p_particles->emitter_velocity.z;
  431. { //collision and attractors
  432. frame_params.collider_count = 0;
  433. frame_params.attractor_count = 0;
  434. frame_params.particle_size = p_particles->collision_base_size;
  435. GLuint collision_heightmap_texture = 0;
  436. Transform3D to_particles;
  437. if (p_particles->use_local_coords) {
  438. to_particles = p_particles->emission_transform.affine_inverse();
  439. }
  440. if (p_particles->has_sdf_collision && p_particles->sdf_collision_texture != 0) {
  441. //2D collision
  442. Transform2D xform = p_particles->sdf_collision_transform; //will use dotproduct manually so invert beforehand
  443. if (!p_particles->use_local_coords) {
  444. Transform2D emission;
  445. emission.columns[0] = Vector2(p_particles->emission_transform.basis.get_column(0).x, p_particles->emission_transform.basis.get_column(0).y);
  446. emission.columns[1] = Vector2(p_particles->emission_transform.basis.get_column(1).x, p_particles->emission_transform.basis.get_column(1).y);
  447. emission.set_origin(Vector2(p_particles->emission_transform.origin.x, p_particles->emission_transform.origin.y));
  448. xform = xform * emission.affine_inverse();
  449. }
  450. Transform2D revert = xform.affine_inverse();
  451. frame_params.collider_count = 1;
  452. frame_params.colliders[0].transform[0] = xform.columns[0][0];
  453. frame_params.colliders[0].transform[1] = xform.columns[0][1];
  454. frame_params.colliders[0].transform[2] = 0;
  455. frame_params.colliders[0].transform[3] = xform.columns[2][0];
  456. frame_params.colliders[0].transform[4] = xform.columns[1][0];
  457. frame_params.colliders[0].transform[5] = xform.columns[1][1];
  458. frame_params.colliders[0].transform[6] = 0;
  459. frame_params.colliders[0].transform[7] = xform.columns[2][1];
  460. frame_params.colliders[0].transform[8] = revert.columns[0][0];
  461. frame_params.colliders[0].transform[9] = revert.columns[0][1];
  462. frame_params.colliders[0].transform[10] = 0;
  463. frame_params.colliders[0].transform[11] = revert.columns[2][0];
  464. frame_params.colliders[0].transform[12] = revert.columns[1][0];
  465. frame_params.colliders[0].transform[13] = revert.columns[1][1];
  466. frame_params.colliders[0].transform[14] = 0;
  467. frame_params.colliders[0].transform[15] = revert.columns[2][1];
  468. frame_params.colliders[0].extents[0] = p_particles->sdf_collision_to_screen.size.x;
  469. frame_params.colliders[0].extents[1] = p_particles->sdf_collision_to_screen.size.y;
  470. frame_params.colliders[0].extents[2] = p_particles->sdf_collision_to_screen.position.x;
  471. frame_params.colliders[0].scale = p_particles->sdf_collision_to_screen.position.y;
  472. frame_params.colliders[0].type = ParticlesFrameParams::COLLISION_TYPE_2D_SDF;
  473. collision_heightmap_texture = p_particles->sdf_collision_texture;
  474. }
  475. for (const RID &E : p_particles->collisions) {
  476. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E);
  477. if (!pci || !pci->active) {
  478. continue;
  479. }
  480. ParticlesCollision *pc = particles_collision_owner.get_or_null(pci->collision);
  481. ERR_CONTINUE(!pc);
  482. Transform3D to_collider = pci->transform;
  483. if (p_particles->use_local_coords) {
  484. to_collider = to_particles * to_collider;
  485. }
  486. Vector3 scale = to_collider.basis.get_scale();
  487. to_collider.basis.orthonormalize();
  488. if (pc->type <= RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT) {
  489. //attractor
  490. if (frame_params.attractor_count >= ParticlesFrameParams::MAX_ATTRACTORS) {
  491. continue;
  492. }
  493. ParticlesFrameParams::Attractor &attr = frame_params.attractors[frame_params.attractor_count];
  494. GLES3::MaterialStorage::store_transform(to_collider, attr.transform);
  495. attr.strength = pc->attractor_strength;
  496. attr.attenuation = pc->attractor_attenuation;
  497. attr.directionality = pc->attractor_directionality;
  498. switch (pc->type) {
  499. case RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT: {
  500. attr.type = ParticlesFrameParams::ATTRACTOR_TYPE_SPHERE;
  501. float radius = pc->radius;
  502. radius *= (scale.x + scale.y + scale.z) / 3.0;
  503. attr.extents[0] = radius;
  504. attr.extents[1] = radius;
  505. attr.extents[2] = radius;
  506. } break;
  507. case RS::PARTICLES_COLLISION_TYPE_BOX_ATTRACT: {
  508. attr.type = ParticlesFrameParams::ATTRACTOR_TYPE_BOX;
  509. Vector3 extents = pc->extents * scale;
  510. attr.extents[0] = extents.x;
  511. attr.extents[1] = extents.y;
  512. attr.extents[2] = extents.z;
  513. } break;
  514. case RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT: {
  515. WARN_PRINT_ONCE_ED("Vector field particle attractors are not available in the Compatibility renderer.");
  516. } break;
  517. default: {
  518. }
  519. }
  520. frame_params.attractor_count++;
  521. } else {
  522. //collider
  523. if (frame_params.collider_count >= ParticlesFrameParams::MAX_COLLIDERS) {
  524. continue;
  525. }
  526. ParticlesFrameParams::Collider &col = frame_params.colliders[frame_params.collider_count];
  527. GLES3::MaterialStorage::store_transform(to_collider, col.transform);
  528. switch (pc->type) {
  529. case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
  530. col.type = ParticlesFrameParams::COLLISION_TYPE_SPHERE;
  531. float radius = pc->radius;
  532. radius *= (scale.x + scale.y + scale.z) / 3.0;
  533. col.extents[0] = radius;
  534. col.extents[1] = radius;
  535. col.extents[2] = radius;
  536. } break;
  537. case RS::PARTICLES_COLLISION_TYPE_BOX_COLLIDE: {
  538. col.type = ParticlesFrameParams::COLLISION_TYPE_BOX;
  539. Vector3 extents = pc->extents * scale;
  540. col.extents[0] = extents.x;
  541. col.extents[1] = extents.y;
  542. col.extents[2] = extents.z;
  543. } break;
  544. case RS::PARTICLES_COLLISION_TYPE_SDF_COLLIDE: {
  545. WARN_PRINT_ONCE_ED("SDF Particle Colliders are not available in the Compatibility renderer.");
  546. } break;
  547. case RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE: {
  548. if (collision_heightmap_texture != 0) { //already taken
  549. continue;
  550. }
  551. col.type = ParticlesFrameParams::COLLISION_TYPE_HEIGHT_FIELD;
  552. Vector3 extents = pc->extents * scale;
  553. col.extents[0] = extents.x;
  554. col.extents[1] = extents.y;
  555. col.extents[2] = extents.z;
  556. collision_heightmap_texture = pc->heightfield_texture;
  557. } break;
  558. default: {
  559. }
  560. }
  561. frame_params.collider_count++;
  562. }
  563. }
  564. // Bind heightmap or SDF texture.
  565. GLuint heightmap = collision_heightmap_texture;
  566. if (heightmap == 0) {
  567. GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_BLACK));
  568. heightmap = tex->tex_id;
  569. }
  570. glActiveTexture(GL_TEXTURE0);
  571. glBindTexture(GL_TEXTURE_2D, heightmap);
  572. }
  573. if (p_particles->frame_params_ubo == 0) {
  574. glGenBuffers(1, &p_particles->frame_params_ubo);
  575. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
  576. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_particles->frame_params_ubo, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW, "Particle Frame UBO");
  577. } else {
  578. // Update per-frame UBO.
  579. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
  580. glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
  581. }
  582. // Get shader and set shader uniforms;
  583. ParticleProcessMaterialData *m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(p_particles->process_material, RS::SHADER_PARTICLES));
  584. if (!m) {
  585. m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(particles_shader.default_material, RS::SHADER_PARTICLES));
  586. }
  587. ERR_FAIL_NULL(m);
  588. ParticlesShaderGLES3::ShaderVariant variant = ParticlesShaderGLES3::MODE_DEFAULT;
  589. uint32_t specialization = 0;
  590. for (uint32_t i = 0; i < PARTICLES_MAX_USERDATAS; i++) {
  591. if (m->shader_data->userdatas_used[i]) {
  592. specialization |= ParticlesShaderGLES3::USERDATA1_USED << i;
  593. }
  594. }
  595. if (p_particles->mode == RS::ParticlesMode::PARTICLES_MODE_3D) {
  596. specialization |= ParticlesShaderGLES3::MODE_3D;
  597. }
  598. RID version = particles_shader.default_shader_version;
  599. if (m->shader_data->version.is_valid() && m->shader_data->valid) {
  600. // Bind material uniform buffer and textures.
  601. m->bind_uniforms();
  602. version = m->shader_data->version;
  603. }
  604. bool success = material_storage->shaders.particles_process_shader.version_bind_shader(version, variant, specialization);
  605. if (!success) {
  606. return;
  607. }
  608. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::LIFETIME, p_particles->lifetime, version, variant, specialization);
  609. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::CLEAR, p_particles->clear, version, variant, specialization);
  610. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, uint32_t(p_particles->amount), version, variant, specialization);
  611. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::USE_FRACTIONAL_DELTA, p_particles->fractional_delta, version, variant, specialization);
  612. p_particles->clear = false;
  613. p_particles->has_collision_cache = m->shader_data->uses_collision;
  614. glBindVertexArray(p_particles->back_vertex_array);
  615. glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, p_particles->front_process_buffer);
  616. glBeginTransformFeedback(GL_POINTS);
  617. glDrawArrays(GL_POINTS, 0, p_particles->amount);
  618. glEndTransformFeedback();
  619. glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
  620. glBindVertexArray(0);
  621. SWAP(p_particles->front_process_buffer, p_particles->back_process_buffer);
  622. SWAP(p_particles->front_vertex_array, p_particles->back_vertex_array);
  623. }
  624. void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) {
  625. Particles *particles = particles_owner.get_or_null(p_particles);
  626. ERR_FAIL_NULL(particles);
  627. if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
  628. return;
  629. }
  630. if (particles->front_process_buffer == 0) {
  631. return; //particles have not processed yet
  632. }
  633. Vector3 axis = -p_axis; // cameras look to z negative
  634. if (particles->use_local_coords) {
  635. axis = particles->emission_transform.basis.xform_inv(axis).normalized();
  636. }
  637. // Sort will be done on CPU since we don't have compute shaders.
  638. // If the sort_buffer has valid data
  639. // Use a buffer that is 2 frames out of date to avoid stalls.
  640. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->sort_buffer_filled) {
  641. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  642. ParticleInstanceData3D *particle_array;
  643. #ifndef __EMSCRIPTEN__
  644. particle_array = static_cast<ParticleInstanceData3D *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
  645. ERR_FAIL_NULL(particle_array);
  646. #else
  647. LocalVector<ParticleInstanceData3D> particle_vector;
  648. particle_vector.resize(particles->amount);
  649. particle_array = particle_vector.ptr();
  650. godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_array);
  651. #endif
  652. SortArray<ParticleInstanceData3D, ParticlesViewSort> sorter;
  653. sorter.compare.z_dir = axis;
  654. sorter.sort(particle_array, particles->amount);
  655. #ifndef __EMSCRIPTEN__
  656. glUnmapBuffer(GL_ARRAY_BUFFER);
  657. #else
  658. glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_vector.ptr());
  659. #endif
  660. }
  661. glEnable(GL_RASTERIZER_DISCARD);
  662. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  663. _particles_update_instance_buffer(particles, axis, p_up_axis);
  664. glDisable(GL_RASTERIZER_DISCARD);
  665. }
  666. void ParticlesStorage::_particles_update_buffers(Particles *particles) {
  667. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  668. uint32_t userdata_count = 0;
  669. if (particles->process_material.is_valid()) {
  670. GLES3::ParticleProcessMaterialData *material_data = static_cast<GLES3::ParticleProcessMaterialData *>(material_storage->material_get_data(particles->process_material, RS::SHADER_PARTICLES));
  671. if (material_data && material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
  672. userdata_count = material_data->shader_data->userdata_count;
  673. }
  674. }
  675. if (userdata_count != particles->userdata_count) {
  676. // Mismatch userdata, re-create buffers.
  677. _particles_free_data(particles);
  678. }
  679. if (particles->amount > 0 && particles->front_process_buffer == 0) {
  680. int total_amount = particles->amount;
  681. particles->userdata_count = userdata_count;
  682. uint32_t xform_size = particles->mode == RS::PARTICLES_MODE_2D ? 2 : 3;
  683. particles->instance_buffer_stride_cache = sizeof(float) * 4 * (xform_size + 1);
  684. particles->instance_buffer_size_cache = particles->instance_buffer_stride_cache * total_amount;
  685. particles->num_attrib_arrays_cache = 5 + userdata_count + (xform_size - 2);
  686. particles->process_buffer_stride_cache = sizeof(float) * 4 * particles->num_attrib_arrays_cache;
  687. PackedByteArray data;
  688. data.resize_zeroed(particles->process_buffer_stride_cache * total_amount);
  689. PackedByteArray instance_data;
  690. instance_data.resize_zeroed(particles->instance_buffer_size_cache);
  691. {
  692. glGenVertexArrays(1, &particles->front_vertex_array);
  693. glBindVertexArray(particles->front_vertex_array);
  694. glGenBuffers(1, &particles->front_process_buffer);
  695. glGenBuffers(1, &particles->front_instance_buffer);
  696. glBindBuffer(GL_ARRAY_BUFFER, particles->front_process_buffer);
  697. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_process_buffer, particles->process_buffer_stride_cache * total_amount, data.ptr(), GL_DYNAMIC_COPY, "Particles front process buffer");
  698. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  699. glEnableVertexAttribArray(j);
  700. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, particles->process_buffer_stride_cache, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  701. }
  702. glBindVertexArray(0);
  703. glBindBuffer(GL_ARRAY_BUFFER, particles->front_instance_buffer);
  704. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_instance_buffer, particles->instance_buffer_size_cache, instance_data.ptr(), GL_DYNAMIC_COPY, "Particles front instance buffer");
  705. }
  706. {
  707. glGenVertexArrays(1, &particles->back_vertex_array);
  708. glBindVertexArray(particles->back_vertex_array);
  709. glGenBuffers(1, &particles->back_process_buffer);
  710. glGenBuffers(1, &particles->back_instance_buffer);
  711. glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
  712. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_process_buffer, particles->process_buffer_stride_cache * total_amount, data.ptr(), GL_DYNAMIC_COPY, "Particles back process buffer");
  713. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  714. glEnableVertexAttribArray(j);
  715. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, particles->process_buffer_stride_cache, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  716. }
  717. glBindVertexArray(0);
  718. glBindBuffer(GL_ARRAY_BUFFER, particles->back_instance_buffer);
  719. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_instance_buffer, particles->instance_buffer_size_cache, instance_data.ptr(), GL_DYNAMIC_COPY, "Particles back instance buffer");
  720. }
  721. glBindBuffer(GL_ARRAY_BUFFER, 0);
  722. }
  723. }
  724. void ParticlesStorage::_particles_allocate_history_buffers(Particles *particles) {
  725. if (particles->sort_buffer == 0) {
  726. glGenBuffers(1, &particles->last_frame_buffer);
  727. glBindBuffer(GL_ARRAY_BUFFER, particles->last_frame_buffer);
  728. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->last_frame_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles last frame buffer");
  729. glGenBuffers(1, &particles->sort_buffer);
  730. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  731. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->sort_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles sort buffer");
  732. particles->sort_buffer_filled = false;
  733. particles->last_frame_buffer_filled = false;
  734. glBindBuffer(GL_ARRAY_BUFFER, 0);
  735. }
  736. }
  737. void ParticlesStorage::_particles_update_instance_buffer(Particles *particles, const Vector3 &p_axis, const Vector3 &p_up_axis) {
  738. ParticlesCopyShaderGLES3::ShaderVariant variant = ParticlesCopyShaderGLES3::MODE_DEFAULT;
  739. uint64_t specialization = 0;
  740. if (particles->mode == RS::ParticlesMode::PARTICLES_MODE_3D) {
  741. specialization |= ParticlesCopyShaderGLES3::MODE_3D;
  742. }
  743. bool success = particles_shader.copy_shader.version_bind_shader(particles_shader.copy_shader_version, variant, specialization);
  744. if (!success) {
  745. return;
  746. }
  747. // Affect 2D only.
  748. if (particles->use_local_coords) {
  749. // In local mode, particle positions are calculated locally (relative to the node position)
  750. // and they're also drawn locally.
  751. // It works as expected, so we just pass an identity transform.
  752. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::INV_EMISSION_TRANSFORM, Transform3D(), particles_shader.copy_shader_version, variant, specialization);
  753. } else {
  754. // In global mode, particle positions are calculated globally (relative to the canvas origin)
  755. // but they're drawn locally.
  756. // So, we need to pass the inverse of the emission transform to bring the
  757. // particles to local coordinates before drawing.
  758. Transform3D inv = particles->emission_transform.affine_inverse();
  759. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::INV_EMISSION_TRANSFORM, inv, particles_shader.copy_shader_version, variant, specialization);
  760. }
  761. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::FRAME_REMAINDER, particles->interpolate ? particles->frame_remainder : 0.0, particles_shader.copy_shader_version, variant, specialization);
  762. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::ALIGN_MODE, uint32_t(particles->transform_align), particles_shader.copy_shader_version, variant, specialization);
  763. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::ALIGN_UP, p_up_axis, particles_shader.copy_shader_version, variant, specialization);
  764. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::SORT_DIRECTION, p_axis, particles_shader.copy_shader_version, variant, specialization);
  765. glBindVertexArray(particles->back_vertex_array);
  766. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->front_instance_buffer, 0, particles->instance_buffer_size_cache);
  767. glBeginTransformFeedback(GL_POINTS);
  768. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_LIFETIME) {
  769. uint32_t lifetime_split = (MIN(int(particles->amount * particles->phase), particles->amount - 1) + 1) % particles->amount;
  770. uint32_t stride = particles->process_buffer_stride_cache;
  771. glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
  772. // Offset VBO so you render starting at the newest particle.
  773. if (particles->amount - lifetime_split > 0) {
  774. glEnableVertexAttribArray(0); // Color.
  775. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 0));
  776. glEnableVertexAttribArray(1); // .xyz: velocity. .z: flags.
  777. glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 1));
  778. glEnableVertexAttribArray(2); // Custom.
  779. glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 2));
  780. glEnableVertexAttribArray(3); // Xform1.
  781. glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 3));
  782. glEnableVertexAttribArray(4); // Xform2.
  783. glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 4));
  784. if (particles->mode == RS::PARTICLES_MODE_3D) {
  785. glEnableVertexAttribArray(5); // Xform3.
  786. glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 5));
  787. }
  788. uint32_t to_draw = particles->amount - lifetime_split;
  789. glDrawArrays(GL_POINTS, 0, to_draw);
  790. }
  791. // Then render from index 0 up intil the newest particle.
  792. if (lifetime_split > 0) {
  793. glEndTransformFeedback();
  794. // Now output to the second portion of the instance buffer.
  795. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->front_instance_buffer, particles->instance_buffer_stride_cache * (particles->amount - lifetime_split), particles->instance_buffer_stride_cache * (lifetime_split));
  796. glBeginTransformFeedback(GL_POINTS);
  797. // Reset back to normal.
  798. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  799. glEnableVertexAttribArray(j);
  800. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  801. }
  802. glDrawArrays(GL_POINTS, 0, lifetime_split);
  803. }
  804. } else {
  805. glDrawArrays(GL_POINTS, 0, particles->amount);
  806. }
  807. glEndTransformFeedback();
  808. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, 0, 0);
  809. glBindVertexArray(0);
  810. glBindBuffer(GL_ARRAY_BUFFER, 0);
  811. }
  812. void ParticlesStorage::update_particles() {
  813. if (!particle_update_list.first()) {
  814. // Return early to avoid unnecessary state changes.
  815. return;
  816. }
  817. RENDER_TIMESTAMP("Update GPUParticles");
  818. glEnable(GL_RASTERIZER_DISCARD);
  819. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  820. GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();
  821. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer);
  822. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  823. while (particle_update_list.first()) {
  824. // Use transform feedback to process particles.
  825. Particles *particles = particle_update_list.first()->self();
  826. particles->update_list.remove_from_list();
  827. particles->dirty = false;
  828. _particles_update_buffers(particles);
  829. if (particles->restart_request) {
  830. particles->prev_ticks = 0;
  831. particles->phase = 0;
  832. particles->prev_phase = 0;
  833. particles->clear = true;
  834. particles->restart_request = false;
  835. }
  836. if (particles->inactive && !particles->emitting) {
  837. //go next
  838. continue;
  839. }
  840. if (particles->emitting) {
  841. if (particles->inactive) {
  842. //restart system from scratch
  843. particles->prev_ticks = 0;
  844. particles->phase = 0;
  845. particles->prev_phase = 0;
  846. particles->clear = true;
  847. }
  848. particles->inactive = false;
  849. particles->inactive_time = 0;
  850. } else {
  851. particles->inactive_time += particles->speed_scale * RSG::rasterizer->get_frame_delta_time();
  852. if (particles->inactive_time > particles->lifetime * 1.2) {
  853. particles->inactive = true;
  854. continue;
  855. }
  856. }
  857. // Copy the instance buffer that was last used into the last_frame buffer.
  858. // sort_buffer should now be 2 frames out of date.
  859. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH || particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME) {
  860. _particles_allocate_history_buffers(particles);
  861. SWAP(particles->last_frame_buffer, particles->sort_buffer);
  862. glBindBuffer(GL_COPY_READ_BUFFER, particles->back_instance_buffer);
  863. glBindBuffer(GL_COPY_WRITE_BUFFER, particles->last_frame_buffer);
  864. glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, particles->instance_buffer_size_cache);
  865. // Last frame's last_frame turned into this frame's sort buffer.
  866. particles->sort_buffer_filled = particles->last_frame_buffer_filled;
  867. particles->sort_buffer_phase = particles->last_frame_phase;
  868. particles->last_frame_buffer_filled = true;
  869. particles->last_frame_phase = particles->phase;
  870. glBindBuffer(GL_COPY_READ_BUFFER, 0);
  871. glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
  872. }
  873. int fixed_fps = 0;
  874. if (particles->fixed_fps > 0) {
  875. fixed_fps = particles->fixed_fps;
  876. }
  877. bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0;
  878. if (particles->clear && particles->pre_process_time > 0.0) {
  879. double frame_time;
  880. if (fixed_fps > 0) {
  881. frame_time = 1.0 / fixed_fps;
  882. } else {
  883. frame_time = 1.0 / 30.0;
  884. }
  885. double todo = particles->pre_process_time;
  886. while (todo >= 0) {
  887. _particles_process(particles, frame_time);
  888. todo -= frame_time;
  889. }
  890. }
  891. if (fixed_fps > 0) {
  892. double frame_time;
  893. double decr;
  894. if (zero_time_scale) {
  895. frame_time = 0.0;
  896. decr = 1.0 / fixed_fps;
  897. } else {
  898. frame_time = 1.0 / fixed_fps;
  899. decr = frame_time;
  900. }
  901. double delta = RSG::rasterizer->get_frame_delta_time();
  902. if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
  903. delta = 0.1;
  904. } else if (delta <= 0.0) { //unlikely but..
  905. delta = 0.001;
  906. }
  907. double todo = particles->frame_remainder + delta;
  908. while (todo >= frame_time) {
  909. _particles_process(particles, frame_time);
  910. todo -= decr;
  911. }
  912. particles->frame_remainder = todo;
  913. } else {
  914. if (zero_time_scale) {
  915. _particles_process(particles, 0.0);
  916. } else {
  917. _particles_process(particles, RSG::rasterizer->get_frame_delta_time());
  918. }
  919. }
  920. // Copy particles to instance buffer and pack Color/Custom.
  921. // We don't have camera information here, so don't copy here if we need camera information for view depth or align mode.
  922. if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
  923. _particles_update_instance_buffer(particles, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0));
  924. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME && particles->sort_buffer_filled) {
  925. if (particles->mode == RS::ParticlesMode::PARTICLES_MODE_2D) {
  926. _particles_reverse_lifetime_sort<ParticleInstanceData2D>(particles);
  927. } else {
  928. _particles_reverse_lifetime_sort<ParticleInstanceData3D>(particles);
  929. }
  930. }
  931. }
  932. SWAP(particles->front_instance_buffer, particles->back_instance_buffer);
  933. // At the end of update, the back_buffer contains the most up-to-date-information to read from.
  934. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  935. }
  936. glDisable(GL_RASTERIZER_DISCARD);
  937. }
  938. template <typename ParticleInstanceData>
  939. void ParticlesStorage::_particles_reverse_lifetime_sort(Particles *particles) {
  940. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  941. ParticleInstanceData *particle_array;
  942. uint32_t buffer_size = particles->amount * sizeof(ParticleInstanceData);
  943. #ifndef __EMSCRIPTEN__
  944. particle_array = static_cast<ParticleInstanceData *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, buffer_size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
  945. ERR_FAIL_NULL(particle_array);
  946. #else
  947. LocalVector<ParticleInstanceData> particle_vector;
  948. particle_vector.resize(particles->amount);
  949. particle_array = particle_vector.ptr();
  950. godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_array);
  951. #endif
  952. uint32_t lifetime_split = (MIN(int(particles->amount * particles->sort_buffer_phase), particles->amount - 1) + 1) % particles->amount;
  953. for (uint32_t i = 0; i < lifetime_split / 2; i++) {
  954. SWAP(particle_array[i], particle_array[lifetime_split - i - 1]);
  955. }
  956. for (uint32_t i = 0; i < (particles->amount - lifetime_split) / 2; i++) {
  957. SWAP(particle_array[lifetime_split + i], particle_array[particles->amount - 1 - i]);
  958. }
  959. #ifndef __EMSCRIPTEN__
  960. glUnmapBuffer(GL_ARRAY_BUFFER);
  961. #else
  962. glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_vector.ptr());
  963. #endif
  964. glBindBuffer(GL_ARRAY_BUFFER, 0);
  965. }
  966. Dependency *ParticlesStorage::particles_get_dependency(RID p_particles) const {
  967. Particles *particles = particles_owner.get_or_null(p_particles);
  968. ERR_FAIL_NULL_V(particles, nullptr);
  969. return &particles->dependency;
  970. }
  971. bool ParticlesStorage::particles_is_inactive(RID p_particles) const {
  972. const Particles *particles = particles_owner.get_or_null(p_particles);
  973. ERR_FAIL_NULL_V(particles, false);
  974. return !particles->emitting && particles->inactive;
  975. }
  976. /* PARTICLES COLLISION API */
  977. RID ParticlesStorage::particles_collision_allocate() {
  978. return particles_collision_owner.allocate_rid();
  979. }
  980. void ParticlesStorage::particles_collision_initialize(RID p_rid) {
  981. particles_collision_owner.initialize_rid(p_rid, ParticlesCollision());
  982. }
  983. void ParticlesStorage::particles_collision_free(RID p_rid) {
  984. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_rid);
  985. if (particles_collision->heightfield_texture != 0) {
  986. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  987. particles_collision->heightfield_texture = 0;
  988. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  989. particles_collision->heightfield_fb = 0;
  990. }
  991. particles_collision->dependency.deleted_notify(p_rid);
  992. particles_collision_owner.free(p_rid);
  993. }
  994. GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const {
  995. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  996. ERR_FAIL_NULL_V(particles_collision, 0);
  997. ERR_FAIL_COND_V(particles_collision->type != RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE, 0);
  998. if (particles_collision->heightfield_texture == 0) {
  999. //create
  1000. const int resolutions[RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX] = { 256, 512, 1024, 2048, 4096, 8192 };
  1001. Size2i size;
  1002. if (particles_collision->extents.x > particles_collision->extents.z) {
  1003. size.x = resolutions[particles_collision->heightfield_resolution];
  1004. size.y = int32_t(particles_collision->extents.z / particles_collision->extents.x * size.x);
  1005. } else {
  1006. size.y = resolutions[particles_collision->heightfield_resolution];
  1007. size.x = int32_t(particles_collision->extents.x / particles_collision->extents.z * size.y);
  1008. }
  1009. glGenTextures(1, &particles_collision->heightfield_texture);
  1010. glActiveTexture(GL_TEXTURE0);
  1011. glBindTexture(GL_TEXTURE_2D, particles_collision->heightfield_texture);
  1012. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
  1013. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1014. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1015. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
  1016. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
  1017. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1018. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1019. glGenFramebuffers(1, &particles_collision->heightfield_fb);
  1020. glBindFramebuffer(GL_FRAMEBUFFER, particles_collision->heightfield_fb);
  1021. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, particles_collision->heightfield_texture, 0);
  1022. #ifdef DEBUG_ENABLED
  1023. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  1024. if (status != GL_FRAMEBUFFER_COMPLETE) {
  1025. WARN_PRINT("Could create heightmap texture status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
  1026. }
  1027. #endif
  1028. GLES3::Utilities::get_singleton()->texture_allocated_data(particles_collision->heightfield_texture, size.x * size.y * 4, "Particles collision heightfield texture");
  1029. particles_collision->heightfield_fb_size = size;
  1030. glBindTexture(GL_TEXTURE_2D, 0);
  1031. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  1032. }
  1033. return particles_collision->heightfield_fb;
  1034. }
  1035. void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) {
  1036. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1037. ERR_FAIL_NULL(particles_collision);
  1038. if (p_type == particles_collision->type) {
  1039. return;
  1040. }
  1041. if (particles_collision->heightfield_texture != 0) {
  1042. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  1043. particles_collision->heightfield_texture = 0;
  1044. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  1045. particles_collision->heightfield_fb = 0;
  1046. }
  1047. particles_collision->type = p_type;
  1048. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1049. }
  1050. void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
  1051. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1052. ERR_FAIL_NULL(particles_collision);
  1053. particles_collision->cull_mask = p_cull_mask;
  1054. }
  1055. void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) {
  1056. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1057. ERR_FAIL_NULL(particles_collision);
  1058. particles_collision->radius = p_radius;
  1059. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1060. }
  1061. void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
  1062. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1063. ERR_FAIL_NULL(particles_collision);
  1064. particles_collision->extents = p_extents;
  1065. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1066. }
  1067. void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) {
  1068. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1069. ERR_FAIL_NULL(particles_collision);
  1070. particles_collision->attractor_strength = p_strength;
  1071. }
  1072. void ParticlesStorage::particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) {
  1073. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1074. ERR_FAIL_NULL(particles_collision);
  1075. particles_collision->attractor_directionality = p_directionality;
  1076. }
  1077. void ParticlesStorage::particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) {
  1078. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1079. ERR_FAIL_NULL(particles_collision);
  1080. particles_collision->attractor_attenuation = p_curve;
  1081. }
  1082. void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) {
  1083. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support SDF collisions in 3D particle shaders");
  1084. }
  1085. void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) {
  1086. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1087. ERR_FAIL_NULL(particles_collision);
  1088. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1089. }
  1090. void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
  1091. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1092. ERR_FAIL_NULL(particles_collision);
  1093. ERR_FAIL_INDEX(p_resolution, RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX);
  1094. if (particles_collision->heightfield_resolution == p_resolution) {
  1095. return;
  1096. }
  1097. particles_collision->heightfield_resolution = p_resolution;
  1098. if (particles_collision->heightfield_texture != 0) {
  1099. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  1100. particles_collision->heightfield_texture = 0;
  1101. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  1102. particles_collision->heightfield_fb = 0;
  1103. }
  1104. }
  1105. AABB ParticlesStorage::particles_collision_get_aabb(RID p_particles_collision) const {
  1106. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1107. ERR_FAIL_NULL_V(particles_collision, AABB());
  1108. switch (particles_collision->type) {
  1109. case RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT:
  1110. case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
  1111. AABB aabb;
  1112. aabb.position = -Vector3(1, 1, 1) * particles_collision->radius;
  1113. aabb.size = Vector3(2, 2, 2) * particles_collision->radius;
  1114. return aabb;
  1115. }
  1116. default: {
  1117. AABB aabb;
  1118. aabb.position = -particles_collision->extents;
  1119. aabb.size = particles_collision->extents * 2;
  1120. return aabb;
  1121. }
  1122. }
  1123. }
  1124. Vector3 ParticlesStorage::particles_collision_get_extents(RID p_particles_collision) const {
  1125. const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1126. ERR_FAIL_NULL_V(particles_collision, Vector3());
  1127. return particles_collision->extents;
  1128. }
  1129. bool ParticlesStorage::particles_collision_is_heightfield(RID p_particles_collision) const {
  1130. const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1131. ERR_FAIL_NULL_V(particles_collision, false);
  1132. return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
  1133. }
  1134. Dependency *ParticlesStorage::particles_collision_get_dependency(RID p_particles_collision) const {
  1135. ParticlesCollision *pc = particles_collision_owner.get_or_null(p_particles_collision);
  1136. ERR_FAIL_NULL_V(pc, nullptr);
  1137. return &pc->dependency;
  1138. }
  1139. /* Particles collision instance */
  1140. RID ParticlesStorage::particles_collision_instance_create(RID p_collision) {
  1141. ParticlesCollisionInstance pci;
  1142. pci.collision = p_collision;
  1143. return particles_collision_instance_owner.make_rid(pci);
  1144. }
  1145. void ParticlesStorage::particles_collision_instance_free(RID p_rid) {
  1146. particles_collision_instance_owner.free(p_rid);
  1147. }
  1148. void ParticlesStorage::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) {
  1149. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance);
  1150. ERR_FAIL_NULL(pci);
  1151. pci->transform = p_transform;
  1152. }
  1153. void ParticlesStorage::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
  1154. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance);
  1155. ERR_FAIL_NULL(pci);
  1156. pci->active = p_active;
  1157. }
  1158. #endif // GLES3_ENABLED