environment_storage.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. /**************************************************************************/
  2. /* environment_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. #include "environment_storage.h"
  31. // Storage
  32. RendererEnvironmentStorage *RendererEnvironmentStorage::singleton = nullptr;
  33. RendererEnvironmentStorage::RendererEnvironmentStorage() {
  34. singleton = this;
  35. }
  36. RendererEnvironmentStorage::~RendererEnvironmentStorage() {
  37. singleton = nullptr;
  38. }
  39. // Environment
  40. RID RendererEnvironmentStorage::environment_allocate() {
  41. return environment_owner.allocate_rid();
  42. }
  43. void RendererEnvironmentStorage::environment_initialize(RID p_rid) {
  44. environment_owner.initialize_rid(p_rid, Environment());
  45. }
  46. void RendererEnvironmentStorage::environment_free(RID p_rid) {
  47. environment_owner.free(p_rid);
  48. }
  49. // Background
  50. void RendererEnvironmentStorage::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
  51. Environment *env = environment_owner.get_or_null(p_env);
  52. ERR_FAIL_NULL(env);
  53. env->background = p_bg;
  54. }
  55. void RendererEnvironmentStorage::environment_set_sky(RID p_env, RID p_sky) {
  56. Environment *env = environment_owner.get_or_null(p_env);
  57. ERR_FAIL_NULL(env);
  58. env->sky = p_sky;
  59. }
  60. void RendererEnvironmentStorage::environment_set_sky_custom_fov(RID p_env, float p_scale) {
  61. Environment *env = environment_owner.get_or_null(p_env);
  62. ERR_FAIL_NULL(env);
  63. env->sky_custom_fov = p_scale;
  64. }
  65. void RendererEnvironmentStorage::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
  66. Environment *env = environment_owner.get_or_null(p_env);
  67. ERR_FAIL_NULL(env);
  68. env->sky_orientation = p_orientation;
  69. }
  70. void RendererEnvironmentStorage::environment_set_bg_color(RID p_env, const Color &p_color) {
  71. Environment *env = environment_owner.get_or_null(p_env);
  72. ERR_FAIL_NULL(env);
  73. env->bg_color = p_color;
  74. }
  75. void RendererEnvironmentStorage::environment_set_bg_energy(RID p_env, float p_multiplier, float p_intensity) {
  76. Environment *env = environment_owner.get_or_null(p_env);
  77. ERR_FAIL_NULL(env);
  78. env->bg_energy_multiplier = p_multiplier;
  79. env->bg_intensity = p_intensity;
  80. }
  81. void RendererEnvironmentStorage::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
  82. Environment *env = environment_owner.get_or_null(p_env);
  83. ERR_FAIL_NULL(env);
  84. env->canvas_max_layer = p_max_layer;
  85. }
  86. void RendererEnvironmentStorage::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) {
  87. Environment *env = environment_owner.get_or_null(p_env);
  88. ERR_FAIL_NULL(env);
  89. env->ambient_light = p_color;
  90. env->ambient_source = p_ambient;
  91. env->ambient_light_energy = p_energy;
  92. env->ambient_sky_contribution = p_sky_contribution;
  93. env->reflection_source = p_reflection_source;
  94. }
  95. RS::EnvironmentBG RendererEnvironmentStorage::environment_get_background(RID p_env) const {
  96. Environment *env = environment_owner.get_or_null(p_env);
  97. ERR_FAIL_NULL_V(env, RS::ENV_BG_CLEAR_COLOR);
  98. return env->background;
  99. }
  100. RID RendererEnvironmentStorage::environment_get_sky(RID p_env) const {
  101. Environment *env = environment_owner.get_or_null(p_env);
  102. ERR_FAIL_NULL_V(env, RID());
  103. return env->sky;
  104. }
  105. float RendererEnvironmentStorage::environment_get_sky_custom_fov(RID p_env) const {
  106. Environment *env = environment_owner.get_or_null(p_env);
  107. ERR_FAIL_NULL_V(env, 0.0);
  108. return env->sky_custom_fov;
  109. }
  110. Basis RendererEnvironmentStorage::environment_get_sky_orientation(RID p_env) const {
  111. Environment *env = environment_owner.get_or_null(p_env);
  112. ERR_FAIL_NULL_V(env, Basis());
  113. return env->sky_orientation;
  114. }
  115. Color RendererEnvironmentStorage::environment_get_bg_color(RID p_env) const {
  116. Environment *env = environment_owner.get_or_null(p_env);
  117. ERR_FAIL_NULL_V(env, Color());
  118. return env->bg_color;
  119. }
  120. float RendererEnvironmentStorage::environment_get_bg_energy_multiplier(RID p_env) const {
  121. Environment *env = environment_owner.get_or_null(p_env);
  122. ERR_FAIL_NULL_V(env, 1.0);
  123. return env->bg_energy_multiplier;
  124. }
  125. float RendererEnvironmentStorage::environment_get_bg_intensity(RID p_env) const {
  126. Environment *env = environment_owner.get_or_null(p_env);
  127. ERR_FAIL_NULL_V(env, 1.0);
  128. return env->bg_intensity;
  129. }
  130. int RendererEnvironmentStorage::environment_get_canvas_max_layer(RID p_env) const {
  131. Environment *env = environment_owner.get_or_null(p_env);
  132. ERR_FAIL_NULL_V(env, 0);
  133. return env->canvas_max_layer;
  134. }
  135. RS::EnvironmentAmbientSource RendererEnvironmentStorage::environment_get_ambient_source(RID p_env) const {
  136. Environment *env = environment_owner.get_or_null(p_env);
  137. ERR_FAIL_NULL_V(env, RS::ENV_AMBIENT_SOURCE_BG);
  138. return env->ambient_source;
  139. }
  140. Color RendererEnvironmentStorage::environment_get_ambient_light(RID p_env) const {
  141. Environment *env = environment_owner.get_or_null(p_env);
  142. ERR_FAIL_NULL_V(env, Color());
  143. return env->ambient_light;
  144. }
  145. float RendererEnvironmentStorage::environment_get_ambient_light_energy(RID p_env) const {
  146. Environment *env = environment_owner.get_or_null(p_env);
  147. ERR_FAIL_NULL_V(env, 1.0);
  148. return env->ambient_light_energy;
  149. }
  150. float RendererEnvironmentStorage::environment_get_ambient_sky_contribution(RID p_env) const {
  151. Environment *env = environment_owner.get_or_null(p_env);
  152. ERR_FAIL_NULL_V(env, 1.0);
  153. return env->ambient_sky_contribution;
  154. }
  155. RS::EnvironmentReflectionSource RendererEnvironmentStorage::environment_get_reflection_source(RID p_env) const {
  156. Environment *env = environment_owner.get_or_null(p_env);
  157. ERR_FAIL_NULL_V(env, RS::ENV_REFLECTION_SOURCE_BG);
  158. return env->reflection_source;
  159. }
  160. void RendererEnvironmentStorage::environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) {
  161. Environment *env = environment_owner.get_or_null(p_env);
  162. ERR_FAIL_NULL(env);
  163. env->camera_feed_id = p_camera_feed_id;
  164. }
  165. int RendererEnvironmentStorage::environment_get_camera_feed_id(RID p_env) const {
  166. Environment *env = environment_owner.get_or_null(p_env);
  167. ERR_FAIL_NULL_V(env, -1);
  168. return env->camera_feed_id;
  169. }
  170. // Tonemap
  171. void RendererEnvironmentStorage::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) {
  172. Environment *env = environment_owner.get_or_null(p_env);
  173. ERR_FAIL_NULL(env);
  174. env->exposure = p_exposure;
  175. env->tone_mapper = p_tone_mapper;
  176. env->white = p_white;
  177. }
  178. RS::EnvironmentToneMapper RendererEnvironmentStorage::environment_get_tone_mapper(RID p_env) const {
  179. Environment *env = environment_owner.get_or_null(p_env);
  180. ERR_FAIL_NULL_V(env, RS::ENV_TONE_MAPPER_LINEAR);
  181. return env->tone_mapper;
  182. }
  183. float RendererEnvironmentStorage::environment_get_exposure(RID p_env) const {
  184. Environment *env = environment_owner.get_or_null(p_env);
  185. ERR_FAIL_NULL_V(env, 1.0);
  186. return env->exposure;
  187. }
  188. float RendererEnvironmentStorage::environment_get_white(RID p_env, bool p_limit_agx_white) const {
  189. Environment *env = environment_owner.get_or_null(p_env);
  190. ERR_FAIL_NULL_V(env, 1.0);
  191. const float output_max_value = 1.0; // SDR always has an output_max_value of 1.0.
  192. // Glow with screen blend mode does not work when white < 1.0, so make sure
  193. // it is at least 1.0 for all tonemappers:
  194. if (env->tone_mapper == RS::ENV_TONE_MAPPER_LINEAR) {
  195. return output_max_value;
  196. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_FILMIC || env->tone_mapper == RS::ENV_TONE_MAPPER_ACES) {
  197. // Filmic and ACES only support SDR; their white is stable regardless
  198. // of output_max_value.
  199. return MAX(1.0, env->white);
  200. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_AGX) {
  201. // AgX works best with a high white. 2.0 is the minimum required for
  202. // good behavior with Mobile rendering method.
  203. if (p_limit_agx_white) {
  204. return 2.0;
  205. } else {
  206. float agx_white = MAX(2.0, env->white);
  207. // Instead of constraining by matching the output_max_value, constrain
  208. // by multiplying to ensure the desired non-uniform scaling behavior
  209. // is maintained in the shoulder.
  210. return agx_white * output_max_value;
  211. }
  212. } else { // Reinhard
  213. // The Reinhard tonemapper is not designed to have a white parameter
  214. // that is less than the output max value. This is especially important
  215. // in the variable Extended Dynamic Range (EDR) paradigm where the
  216. // output max value may change to be greater or less than the white
  217. // parameter, depending on the available dynamic range.
  218. return MAX(output_max_value, env->white);
  219. }
  220. }
  221. void RendererEnvironmentStorage::environment_set_tonemap_agx_contrast(RID p_env, float p_agx_contrast) {
  222. Environment *env = environment_owner.get_or_null(p_env);
  223. ERR_FAIL_NULL(env);
  224. env->tonemap_agx_contrast = p_agx_contrast;
  225. }
  226. float RendererEnvironmentStorage::environment_get_tonemap_agx_contrast(RID p_env) const {
  227. Environment *env = environment_owner.get_or_null(p_env);
  228. ERR_FAIL_NULL_V(env, 1.0);
  229. return env->tonemap_agx_contrast;
  230. }
  231. RendererEnvironmentStorage::TonemapParameters RendererEnvironmentStorage::environment_get_tonemap_parameters(RID p_env, bool p_limit_agx_white) const {
  232. Environment *env = environment_owner.get_or_null(p_env);
  233. ERR_FAIL_NULL_V(env, TonemapParameters());
  234. const float output_max_value = 1.0; // SDR always has an output_max_value of 1.0.
  235. float white = environment_get_white(p_env, p_limit_agx_white);
  236. TonemapParameters tonemap_parameters = TonemapParameters();
  237. if (env->tone_mapper == RS::ENV_TONE_MAPPER_LINEAR) {
  238. // Linear has no tonemapping parameters
  239. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_REINHARD) {
  240. tonemap_parameters.white_squared = white * white;
  241. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_FILMIC) {
  242. // These constants must match those in the shader code.
  243. // exposure_bias: Input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers
  244. // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values).
  245. // Has no effect on the curve's general shape or visual properties.
  246. const float exposure_bias = 2.0f;
  247. const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance
  248. const float B = 0.30f * exposure_bias;
  249. const float C = 0.10f;
  250. const float D = 0.20f;
  251. const float E = 0.01f;
  252. const float F = 0.30f;
  253. tonemap_parameters.white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F;
  254. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_ACES) {
  255. // These constants must match those in the shader code.
  256. const float exposure_bias = 1.8f;
  257. const float A = 0.0245786f;
  258. const float B = 0.000090537f;
  259. const float C = 0.983729f;
  260. const float D = 0.432951f;
  261. const float E = 0.238081f;
  262. white *= exposure_bias;
  263. float white_tonemapped = (white * (white + A) - B) / (white * (C * white + D) + E);
  264. tonemap_parameters.white_tonemapped = white_tonemapped;
  265. } else if (env->tone_mapper == RS::ENV_TONE_MAPPER_AGX) {
  266. // Calculate allenwp tonemapping curve parameters on the CPU to improve shader performance.
  267. // Source and details: https://allenwp.com/blog/2025/05/29/allenwp-tonemapping-curve/
  268. // These constants must match the those in the shader code.
  269. // 18% "middle gray" is perceptually 50% of the brightness of reference white.
  270. const float awp_crossover_point = 0.18;
  271. // When output_max_value and/or awp_crossover_point are no longer constant, awp_shoulder_max can
  272. // be calculated on the CPU and passed in as tonemap_parameters.tonemap_e.
  273. const float awp_shoulder_max = output_max_value - awp_crossover_point;
  274. float awp_high_clip = white;
  275. // awp_toe_a is a solution generated by Mathematica that ensures intersection at awp_crossover_point.
  276. float awp_toe_a = ((1.0 / awp_crossover_point) - 1.0) * pow(awp_crossover_point, env->tonemap_agx_contrast);
  277. // Slope formula is simply the derivative of the toe function with an input of awp_crossover_point.
  278. float awp_slope_denom = pow(awp_crossover_point, env->tonemap_agx_contrast) + awp_toe_a;
  279. float awp_slope = (env->tonemap_agx_contrast * pow(awp_crossover_point, env->tonemap_agx_contrast - 1.0) * awp_toe_a) / (awp_slope_denom * awp_slope_denom);
  280. float awp_w = awp_high_clip - awp_crossover_point;
  281. awp_w = awp_w * awp_w;
  282. awp_w = awp_w / awp_shoulder_max;
  283. awp_w = awp_w * awp_slope;
  284. tonemap_parameters.awp_contrast = env->tonemap_agx_contrast;
  285. tonemap_parameters.awp_toe_a = awp_toe_a;
  286. tonemap_parameters.awp_slope = awp_slope;
  287. tonemap_parameters.awp_w = awp_w;
  288. }
  289. return tonemap_parameters;
  290. }
  291. // Fog
  292. void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode) {
  293. Environment *env = environment_owner.get_or_null(p_env);
  294. ERR_FAIL_NULL(env);
  295. env->fog_enabled = p_enable;
  296. env->fog_mode = p_mode;
  297. env->fog_light_color = p_light_color;
  298. env->fog_light_energy = p_light_energy;
  299. env->fog_sun_scatter = p_sun_scatter;
  300. env->fog_density = p_density;
  301. env->fog_height = p_height;
  302. env->fog_height_density = p_height_density;
  303. env->fog_aerial_perspective = p_fog_aerial_perspective;
  304. env->fog_sky_affect = p_sky_affect;
  305. }
  306. bool RendererEnvironmentStorage::environment_get_fog_enabled(RID p_env) const {
  307. Environment *env = environment_owner.get_or_null(p_env);
  308. ERR_FAIL_NULL_V(env, false);
  309. return env->fog_enabled;
  310. }
  311. RS::EnvironmentFogMode RendererEnvironmentStorage::environment_get_fog_mode(RID p_env) const {
  312. Environment *env = environment_owner.get_or_null(p_env);
  313. ERR_FAIL_NULL_V(env, RS::ENV_FOG_MODE_EXPONENTIAL);
  314. return env->fog_mode;
  315. }
  316. Color RendererEnvironmentStorage::environment_get_fog_light_color(RID p_env) const {
  317. Environment *env = environment_owner.get_or_null(p_env);
  318. ERR_FAIL_NULL_V(env, Color(0.5, 0.6, 0.7));
  319. return env->fog_light_color;
  320. }
  321. float RendererEnvironmentStorage::environment_get_fog_light_energy(RID p_env) const {
  322. Environment *env = environment_owner.get_or_null(p_env);
  323. ERR_FAIL_NULL_V(env, 1.0);
  324. return env->fog_light_energy;
  325. }
  326. float RendererEnvironmentStorage::environment_get_fog_sun_scatter(RID p_env) const {
  327. Environment *env = environment_owner.get_or_null(p_env);
  328. ERR_FAIL_NULL_V(env, 0.0);
  329. return env->fog_sun_scatter;
  330. }
  331. float RendererEnvironmentStorage::environment_get_fog_density(RID p_env) const {
  332. Environment *env = environment_owner.get_or_null(p_env);
  333. ERR_FAIL_NULL_V(env, 0.001);
  334. return env->fog_density;
  335. }
  336. float RendererEnvironmentStorage::environment_get_fog_height(RID p_env) const {
  337. Environment *env = environment_owner.get_or_null(p_env);
  338. ERR_FAIL_NULL_V(env, 0.0);
  339. return env->fog_height;
  340. }
  341. float RendererEnvironmentStorage::environment_get_fog_height_density(RID p_env) const {
  342. Environment *env = environment_owner.get_or_null(p_env);
  343. ERR_FAIL_NULL_V(env, 0.0);
  344. return env->fog_height_density;
  345. }
  346. float RendererEnvironmentStorage::environment_get_fog_aerial_perspective(RID p_env) const {
  347. Environment *env = environment_owner.get_or_null(p_env);
  348. ERR_FAIL_NULL_V(env, 0.0);
  349. return env->fog_aerial_perspective;
  350. }
  351. float RendererEnvironmentStorage::environment_get_fog_sky_affect(RID p_env) const {
  352. Environment *env = environment_owner.get_or_null(p_env);
  353. ERR_FAIL_NULL_V(env, 0.0);
  354. return env->fog_sky_affect;
  355. }
  356. // Depth Fog
  357. void RendererEnvironmentStorage::environment_set_fog_depth(RID p_env, float p_curve, float p_begin, float p_end) {
  358. Environment *env = environment_owner.get_or_null(p_env);
  359. ERR_FAIL_NULL(env);
  360. env->fog_depth_curve = p_curve;
  361. env->fog_depth_begin = p_begin;
  362. env->fog_depth_end = p_end;
  363. }
  364. float RendererEnvironmentStorage::environment_get_fog_depth_curve(RID p_env) const {
  365. Environment *env = environment_owner.get_or_null(p_env);
  366. ERR_FAIL_NULL_V(env, 0.0);
  367. return env->fog_depth_curve;
  368. }
  369. float RendererEnvironmentStorage::environment_get_fog_depth_begin(RID p_env) const {
  370. Environment *env = environment_owner.get_or_null(p_env);
  371. ERR_FAIL_NULL_V(env, 0.0);
  372. return env->fog_depth_begin;
  373. }
  374. float RendererEnvironmentStorage::environment_get_fog_depth_end(RID p_env) const {
  375. Environment *env = environment_owner.get_or_null(p_env);
  376. ERR_FAIL_NULL_V(env, 0.0);
  377. return env->fog_depth_end;
  378. }
  379. // Volumetric Fog
  380. void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject, float p_sky_affect) {
  381. Environment *env = environment_owner.get_or_null(p_env);
  382. ERR_FAIL_NULL(env);
  383. #ifdef DEBUG_ENABLED
  384. if (OS::get_singleton()->get_current_rendering_method() != "forward_plus" && p_enable) {
  385. WARN_PRINT_ONCE_ED("Volumetric fog is only available when using the Forward+ renderer.");
  386. }
  387. #endif
  388. env->volumetric_fog_enabled = p_enable;
  389. env->volumetric_fog_density = p_density;
  390. env->volumetric_fog_scattering = p_albedo;
  391. env->volumetric_fog_emission = p_emission;
  392. env->volumetric_fog_emission_energy = p_emission_energy;
  393. env->volumetric_fog_anisotropy = p_anisotropy;
  394. env->volumetric_fog_length = p_length;
  395. env->volumetric_fog_detail_spread = p_detail_spread;
  396. env->volumetric_fog_gi_inject = p_gi_inject;
  397. env->volumetric_fog_temporal_reprojection = p_temporal_reprojection;
  398. env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount;
  399. env->volumetric_fog_ambient_inject = p_ambient_inject;
  400. env->volumetric_fog_sky_affect = p_sky_affect;
  401. }
  402. bool RendererEnvironmentStorage::environment_get_volumetric_fog_enabled(RID p_env) const {
  403. Environment *env = environment_owner.get_or_null(p_env);
  404. ERR_FAIL_NULL_V(env, false);
  405. return env->volumetric_fog_enabled;
  406. }
  407. float RendererEnvironmentStorage::environment_get_volumetric_fog_density(RID p_env) const {
  408. Environment *env = environment_owner.get_or_null(p_env);
  409. ERR_FAIL_NULL_V(env, 0.01);
  410. return env->volumetric_fog_density;
  411. }
  412. Color RendererEnvironmentStorage::environment_get_volumetric_fog_scattering(RID p_env) const {
  413. Environment *env = environment_owner.get_or_null(p_env);
  414. ERR_FAIL_NULL_V(env, Color(1, 1, 1));
  415. return env->volumetric_fog_scattering;
  416. }
  417. Color RendererEnvironmentStorage::environment_get_volumetric_fog_emission(RID p_env) const {
  418. Environment *env = environment_owner.get_or_null(p_env);
  419. ERR_FAIL_NULL_V(env, Color(0, 0, 0));
  420. return env->volumetric_fog_emission;
  421. }
  422. float RendererEnvironmentStorage::environment_get_volumetric_fog_emission_energy(RID p_env) const {
  423. Environment *env = environment_owner.get_or_null(p_env);
  424. ERR_FAIL_NULL_V(env, 0.0);
  425. return env->volumetric_fog_emission_energy;
  426. }
  427. float RendererEnvironmentStorage::environment_get_volumetric_fog_anisotropy(RID p_env) const {
  428. Environment *env = environment_owner.get_or_null(p_env);
  429. ERR_FAIL_NULL_V(env, 0.2);
  430. return env->volumetric_fog_anisotropy;
  431. }
  432. float RendererEnvironmentStorage::environment_get_volumetric_fog_length(RID p_env) const {
  433. Environment *env = environment_owner.get_or_null(p_env);
  434. ERR_FAIL_NULL_V(env, 64.0);
  435. return env->volumetric_fog_length;
  436. }
  437. float RendererEnvironmentStorage::environment_get_volumetric_fog_detail_spread(RID p_env) const {
  438. Environment *env = environment_owner.get_or_null(p_env);
  439. ERR_FAIL_NULL_V(env, 2.0);
  440. return env->volumetric_fog_detail_spread;
  441. }
  442. float RendererEnvironmentStorage::environment_get_volumetric_fog_gi_inject(RID p_env) const {
  443. Environment *env = environment_owner.get_or_null(p_env);
  444. ERR_FAIL_NULL_V(env, 0.0);
  445. return env->volumetric_fog_gi_inject;
  446. }
  447. float RendererEnvironmentStorage::environment_get_volumetric_fog_sky_affect(RID p_env) const {
  448. Environment *env = environment_owner.get_or_null(p_env);
  449. ERR_FAIL_NULL_V(env, 0.0);
  450. return env->volumetric_fog_sky_affect;
  451. }
  452. bool RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const {
  453. Environment *env = environment_owner.get_or_null(p_env);
  454. ERR_FAIL_NULL_V(env, true);
  455. return env->volumetric_fog_temporal_reprojection;
  456. }
  457. float RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const {
  458. Environment *env = environment_owner.get_or_null(p_env);
  459. ERR_FAIL_NULL_V(env, 0.9);
  460. return env->volumetric_fog_temporal_reprojection_amount;
  461. }
  462. float RendererEnvironmentStorage::environment_get_volumetric_fog_ambient_inject(RID p_env) const {
  463. Environment *env = environment_owner.get_or_null(p_env);
  464. ERR_FAIL_NULL_V(env, 0.0);
  465. return env->volumetric_fog_ambient_inject;
  466. }
  467. // GLOW
  468. void RendererEnvironmentStorage::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) {
  469. Environment *env = environment_owner.get_or_null(p_env);
  470. ERR_FAIL_NULL(env);
  471. ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
  472. env->glow_enabled = p_enable;
  473. env->glow_levels = p_levels;
  474. env->glow_intensity = p_intensity;
  475. env->glow_strength = p_strength;
  476. env->glow_mix = p_mix;
  477. env->glow_bloom = p_bloom_threshold;
  478. env->glow_blend_mode = p_blend_mode;
  479. env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
  480. env->glow_hdr_bleed_scale = p_hdr_bleed_scale;
  481. env->glow_hdr_luminance_cap = p_hdr_luminance_cap;
  482. env->glow_map_strength = p_glow_map_strength;
  483. env->glow_map = p_glow_map;
  484. }
  485. bool RendererEnvironmentStorage::environment_get_glow_enabled(RID p_env) const {
  486. Environment *env = environment_owner.get_or_null(p_env);
  487. ERR_FAIL_NULL_V(env, false);
  488. return env->glow_enabled;
  489. }
  490. Vector<float> RendererEnvironmentStorage::environment_get_glow_levels(RID p_env) const {
  491. Environment *env = environment_owner.get_or_null(p_env);
  492. ERR_FAIL_NULL_V(env, Vector<float>());
  493. return env->glow_levels;
  494. }
  495. float RendererEnvironmentStorage::environment_get_glow_intensity(RID p_env) const {
  496. Environment *env = environment_owner.get_or_null(p_env);
  497. ERR_FAIL_NULL_V(env, 0.3);
  498. return env->glow_intensity;
  499. }
  500. float RendererEnvironmentStorage::environment_get_glow_strength(RID p_env) const {
  501. Environment *env = environment_owner.get_or_null(p_env);
  502. ERR_FAIL_NULL_V(env, 1.0);
  503. return env->glow_strength;
  504. }
  505. float RendererEnvironmentStorage::environment_get_glow_bloom(RID p_env) const {
  506. Environment *env = environment_owner.get_or_null(p_env);
  507. ERR_FAIL_NULL_V(env, 0.0);
  508. return env->glow_bloom;
  509. }
  510. float RendererEnvironmentStorage::environment_get_glow_mix(RID p_env) const {
  511. Environment *env = environment_owner.get_or_null(p_env);
  512. ERR_FAIL_NULL_V(env, 0.01);
  513. return env->glow_mix;
  514. }
  515. RS::EnvironmentGlowBlendMode RendererEnvironmentStorage::environment_get_glow_blend_mode(RID p_env) const {
  516. Environment *env = environment_owner.get_or_null(p_env);
  517. ERR_FAIL_NULL_V(env, RS::ENV_GLOW_BLEND_MODE_SCREEN);
  518. return env->glow_blend_mode;
  519. }
  520. float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_threshold(RID p_env) const {
  521. Environment *env = environment_owner.get_or_null(p_env);
  522. ERR_FAIL_NULL_V(env, 1.0);
  523. return env->glow_hdr_bleed_threshold;
  524. }
  525. float RendererEnvironmentStorage::environment_get_glow_hdr_luminance_cap(RID p_env) const {
  526. Environment *env = environment_owner.get_or_null(p_env);
  527. ERR_FAIL_NULL_V(env, 12.0);
  528. return env->glow_hdr_luminance_cap;
  529. }
  530. float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_scale(RID p_env) const {
  531. Environment *env = environment_owner.get_or_null(p_env);
  532. ERR_FAIL_NULL_V(env, 2.0);
  533. return env->glow_hdr_bleed_scale;
  534. }
  535. float RendererEnvironmentStorage::environment_get_glow_map_strength(RID p_env) const {
  536. Environment *env = environment_owner.get_or_null(p_env);
  537. ERR_FAIL_NULL_V(env, 0.0);
  538. return env->glow_map_strength;
  539. }
  540. RID RendererEnvironmentStorage::environment_get_glow_map(RID p_env) const {
  541. Environment *env = environment_owner.get_or_null(p_env);
  542. ERR_FAIL_NULL_V(env, RID());
  543. return env->glow_map;
  544. }
  545. // SSR
  546. void RendererEnvironmentStorage::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
  547. Environment *env = environment_owner.get_or_null(p_env);
  548. ERR_FAIL_NULL(env);
  549. #ifdef DEBUG_ENABLED
  550. if (OS::get_singleton()->get_current_rendering_method() != "forward_plus" && p_enable) {
  551. WARN_PRINT_ONCE_ED("Screen-space reflections (SSR) are only available when using the Forward+ renderer.");
  552. }
  553. #endif
  554. env->ssr_enabled = p_enable;
  555. env->ssr_max_steps = p_max_steps;
  556. env->ssr_fade_in = p_fade_int;
  557. env->ssr_fade_out = p_fade_out;
  558. env->ssr_depth_tolerance = p_depth_tolerance;
  559. }
  560. bool RendererEnvironmentStorage::environment_get_ssr_enabled(RID p_env) const {
  561. Environment *env = environment_owner.get_or_null(p_env);
  562. ERR_FAIL_NULL_V(env, false);
  563. return env->ssr_enabled;
  564. }
  565. int RendererEnvironmentStorage::environment_get_ssr_max_steps(RID p_env) const {
  566. Environment *env = environment_owner.get_or_null(p_env);
  567. ERR_FAIL_NULL_V(env, 64);
  568. return env->ssr_max_steps;
  569. }
  570. float RendererEnvironmentStorage::environment_get_ssr_fade_in(RID p_env) const {
  571. Environment *env = environment_owner.get_or_null(p_env);
  572. ERR_FAIL_NULL_V(env, 0.15);
  573. return env->ssr_fade_in;
  574. }
  575. float RendererEnvironmentStorage::environment_get_ssr_fade_out(RID p_env) const {
  576. Environment *env = environment_owner.get_or_null(p_env);
  577. ERR_FAIL_NULL_V(env, 2.0);
  578. return env->ssr_fade_out;
  579. }
  580. float RendererEnvironmentStorage::environment_get_ssr_depth_tolerance(RID p_env) const {
  581. Environment *env = environment_owner.get_or_null(p_env);
  582. ERR_FAIL_NULL_V(env, 0.5);
  583. return env->ssr_depth_tolerance;
  584. }
  585. // SSAO
  586. void RendererEnvironmentStorage::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) {
  587. Environment *env = environment_owner.get_or_null(p_env);
  588. ERR_FAIL_NULL(env);
  589. #ifdef DEBUG_ENABLED
  590. if (OS::get_singleton()->get_current_rendering_method() == "mobile" && p_enable) {
  591. WARN_PRINT_ONCE_ED("Screen-space ambient occlusion (SSAO) is only available when using the Forward+ or Compatibility renderers.");
  592. }
  593. #endif
  594. env->ssao_enabled = p_enable;
  595. env->ssao_radius = p_radius;
  596. env->ssao_intensity = p_intensity;
  597. env->ssao_power = p_power;
  598. env->ssao_detail = p_detail;
  599. env->ssao_horizon = p_horizon;
  600. env->ssao_sharpness = p_sharpness;
  601. env->ssao_direct_light_affect = p_light_affect;
  602. env->ssao_ao_channel_affect = p_ao_channel_affect;
  603. }
  604. bool RendererEnvironmentStorage::environment_get_ssao_enabled(RID p_env) const {
  605. Environment *env = environment_owner.get_or_null(p_env);
  606. ERR_FAIL_NULL_V(env, false);
  607. return env->ssao_enabled;
  608. }
  609. float RendererEnvironmentStorage::environment_get_ssao_radius(RID p_env) const {
  610. Environment *env = environment_owner.get_or_null(p_env);
  611. ERR_FAIL_NULL_V(env, 1.0);
  612. return env->ssao_radius;
  613. }
  614. float RendererEnvironmentStorage::environment_get_ssao_intensity(RID p_env) const {
  615. Environment *env = environment_owner.get_or_null(p_env);
  616. ERR_FAIL_NULL_V(env, 2.0);
  617. return env->ssao_intensity;
  618. }
  619. float RendererEnvironmentStorage::environment_get_ssao_power(RID p_env) const {
  620. Environment *env = environment_owner.get_or_null(p_env);
  621. ERR_FAIL_NULL_V(env, 1.5);
  622. return env->ssao_power;
  623. }
  624. float RendererEnvironmentStorage::environment_get_ssao_detail(RID p_env) const {
  625. Environment *env = environment_owner.get_or_null(p_env);
  626. ERR_FAIL_NULL_V(env, 0.5);
  627. return env->ssao_detail;
  628. }
  629. float RendererEnvironmentStorage::environment_get_ssao_horizon(RID p_env) const {
  630. Environment *env = environment_owner.get_or_null(p_env);
  631. ERR_FAIL_NULL_V(env, 0.06);
  632. return env->ssao_horizon;
  633. }
  634. float RendererEnvironmentStorage::environment_get_ssao_sharpness(RID p_env) const {
  635. Environment *env = environment_owner.get_or_null(p_env);
  636. ERR_FAIL_NULL_V(env, 0.98);
  637. return env->ssao_sharpness;
  638. }
  639. float RendererEnvironmentStorage::environment_get_ssao_direct_light_affect(RID p_env) const {
  640. Environment *env = environment_owner.get_or_null(p_env);
  641. ERR_FAIL_NULL_V(env, 0.0);
  642. return env->ssao_direct_light_affect;
  643. }
  644. float RendererEnvironmentStorage::environment_get_ssao_ao_channel_affect(RID p_env) const {
  645. Environment *env = environment_owner.get_or_null(p_env);
  646. ERR_FAIL_NULL_V(env, 0.0);
  647. return env->ssao_ao_channel_affect;
  648. }
  649. // SSIL
  650. void RendererEnvironmentStorage::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) {
  651. Environment *env = environment_owner.get_or_null(p_env);
  652. ERR_FAIL_NULL(env);
  653. #ifdef DEBUG_ENABLED
  654. if (OS::get_singleton()->get_current_rendering_method() != "forward_plus" && p_enable) {
  655. WARN_PRINT_ONCE_ED("Screen-space indirect lighting (SSIL) is only available when using the Forward+ renderer.");
  656. }
  657. #endif
  658. env->ssil_enabled = p_enable;
  659. env->ssil_radius = p_radius;
  660. env->ssil_intensity = p_intensity;
  661. env->ssil_sharpness = p_sharpness;
  662. env->ssil_normal_rejection = p_normal_rejection;
  663. }
  664. bool RendererEnvironmentStorage::environment_get_ssil_enabled(RID p_env) const {
  665. Environment *env = environment_owner.get_or_null(p_env);
  666. ERR_FAIL_NULL_V(env, false);
  667. return env->ssil_enabled;
  668. }
  669. float RendererEnvironmentStorage::environment_get_ssil_radius(RID p_env) const {
  670. Environment *env = environment_owner.get_or_null(p_env);
  671. ERR_FAIL_NULL_V(env, 5.0);
  672. return env->ssil_radius;
  673. }
  674. float RendererEnvironmentStorage::environment_get_ssil_intensity(RID p_env) const {
  675. Environment *env = environment_owner.get_or_null(p_env);
  676. ERR_FAIL_NULL_V(env, 1.0);
  677. return env->ssil_intensity;
  678. }
  679. float RendererEnvironmentStorage::environment_get_ssil_sharpness(RID p_env) const {
  680. Environment *env = environment_owner.get_or_null(p_env);
  681. ERR_FAIL_NULL_V(env, 0.98);
  682. return env->ssil_sharpness;
  683. }
  684. float RendererEnvironmentStorage::environment_get_ssil_normal_rejection(RID p_env) const {
  685. Environment *env = environment_owner.get_or_null(p_env);
  686. ERR_FAIL_NULL_V(env, 1.0);
  687. return env->ssil_normal_rejection;
  688. }
  689. // SDFGI
  690. void RendererEnvironmentStorage::environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
  691. Environment *env = environment_owner.get_or_null(p_env);
  692. ERR_FAIL_NULL(env);
  693. #ifdef DEBUG_ENABLED
  694. if (OS::get_singleton()->get_current_rendering_method() != "forward_plus" && p_enable) {
  695. WARN_PRINT_ONCE_ED("SDFGI is only available when using the Forward+ renderer.");
  696. }
  697. #endif
  698. env->sdfgi_enabled = p_enable;
  699. env->sdfgi_cascades = p_cascades;
  700. env->sdfgi_min_cell_size = p_min_cell_size;
  701. env->sdfgi_use_occlusion = p_use_occlusion;
  702. env->sdfgi_bounce_feedback = p_bounce_feedback;
  703. env->sdfgi_read_sky_light = p_read_sky;
  704. env->sdfgi_energy = p_energy;
  705. env->sdfgi_normal_bias = p_normal_bias;
  706. env->sdfgi_probe_bias = p_probe_bias;
  707. env->sdfgi_y_scale = p_y_scale;
  708. }
  709. bool RendererEnvironmentStorage::environment_get_sdfgi_enabled(RID p_env) const {
  710. Environment *env = environment_owner.get_or_null(p_env);
  711. ERR_FAIL_NULL_V(env, false);
  712. return env->sdfgi_enabled;
  713. }
  714. int RendererEnvironmentStorage::environment_get_sdfgi_cascades(RID p_env) const {
  715. Environment *env = environment_owner.get_or_null(p_env);
  716. ERR_FAIL_NULL_V(env, 4);
  717. return env->sdfgi_cascades;
  718. }
  719. float RendererEnvironmentStorage::environment_get_sdfgi_min_cell_size(RID p_env) const {
  720. Environment *env = environment_owner.get_or_null(p_env);
  721. ERR_FAIL_NULL_V(env, 0.2);
  722. return env->sdfgi_min_cell_size;
  723. }
  724. bool RendererEnvironmentStorage::environment_get_sdfgi_use_occlusion(RID p_env) const {
  725. Environment *env = environment_owner.get_or_null(p_env);
  726. ERR_FAIL_NULL_V(env, false);
  727. return env->sdfgi_use_occlusion;
  728. }
  729. float RendererEnvironmentStorage::environment_get_sdfgi_bounce_feedback(RID p_env) const {
  730. Environment *env = environment_owner.get_or_null(p_env);
  731. ERR_FAIL_NULL_V(env, 0.5);
  732. return env->sdfgi_bounce_feedback;
  733. }
  734. bool RendererEnvironmentStorage::environment_get_sdfgi_read_sky_light(RID p_env) const {
  735. Environment *env = environment_owner.get_or_null(p_env);
  736. ERR_FAIL_NULL_V(env, true);
  737. return env->sdfgi_read_sky_light;
  738. }
  739. float RendererEnvironmentStorage::environment_get_sdfgi_energy(RID p_env) const {
  740. Environment *env = environment_owner.get_or_null(p_env);
  741. ERR_FAIL_NULL_V(env, 1.0);
  742. return env->sdfgi_energy;
  743. }
  744. float RendererEnvironmentStorage::environment_get_sdfgi_normal_bias(RID p_env) const {
  745. Environment *env = environment_owner.get_or_null(p_env);
  746. ERR_FAIL_NULL_V(env, 1.1);
  747. return env->sdfgi_normal_bias;
  748. }
  749. float RendererEnvironmentStorage::environment_get_sdfgi_probe_bias(RID p_env) const {
  750. Environment *env = environment_owner.get_or_null(p_env);
  751. ERR_FAIL_NULL_V(env, 1.1);
  752. return env->sdfgi_probe_bias;
  753. }
  754. RS::EnvironmentSDFGIYScale RendererEnvironmentStorage::environment_get_sdfgi_y_scale(RID p_env) const {
  755. Environment *env = environment_owner.get_or_null(p_env);
  756. ERR_FAIL_NULL_V(env, RS::ENV_SDFGI_Y_SCALE_75_PERCENT);
  757. return env->sdfgi_y_scale;
  758. }
  759. // Adjustments
  760. void RendererEnvironmentStorage::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) {
  761. Environment *env = environment_owner.get_or_null(p_env);
  762. ERR_FAIL_NULL(env);
  763. env->adjustments_enabled = p_enable;
  764. // Scale brightness via the nonlinear sRGB transfer function to provide a
  765. // somewhat perceptually uniform brightness adjustment.
  766. env->adjustments_brightness = p_brightness < 0.04045f ? p_brightness * (1.0f / 12.92f) : Math::pow(float((p_brightness + 0.055f) * (1.0f / (1.055f))), 2.4f);
  767. env->adjustments_contrast = p_contrast;
  768. env->adjustments_saturation = p_saturation;
  769. env->use_1d_color_correction = p_use_1d_color_correction;
  770. env->color_correction = p_color_correction;
  771. }
  772. bool RendererEnvironmentStorage::environment_get_adjustments_enabled(RID p_env) const {
  773. Environment *env = environment_owner.get_or_null(p_env);
  774. ERR_FAIL_NULL_V(env, false);
  775. return env->adjustments_enabled;
  776. }
  777. float RendererEnvironmentStorage::environment_get_adjustments_brightness(RID p_env) const {
  778. Environment *env = environment_owner.get_or_null(p_env);
  779. ERR_FAIL_NULL_V(env, 1.0);
  780. return env->adjustments_brightness;
  781. }
  782. float RendererEnvironmentStorage::environment_get_adjustments_contrast(RID p_env) const {
  783. Environment *env = environment_owner.get_or_null(p_env);
  784. ERR_FAIL_NULL_V(env, 1.0);
  785. return env->adjustments_contrast;
  786. }
  787. float RendererEnvironmentStorage::environment_get_adjustments_saturation(RID p_env) const {
  788. Environment *env = environment_owner.get_or_null(p_env);
  789. ERR_FAIL_NULL_V(env, 1.0);
  790. return env->adjustments_saturation;
  791. }
  792. bool RendererEnvironmentStorage::environment_get_use_1d_color_correction(RID p_env) const {
  793. Environment *env = environment_owner.get_or_null(p_env);
  794. ERR_FAIL_NULL_V(env, false);
  795. return env->use_1d_color_correction;
  796. }
  797. RID RendererEnvironmentStorage::environment_get_color_correction(RID p_env) const {
  798. Environment *env = environment_owner.get_or_null(p_env);
  799. ERR_FAIL_NULL_V(env, RID());
  800. return env->color_correction;
  801. }