💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1163 lines
41 KiB

4 years ago
4 years ago
  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <engine/render/passes/sky-pass.hpp>
  20. #include <engine/resources/resource-manager.hpp>
  21. #include <engine/gl/rasterizer.hpp>
  22. #include <engine/gl/framebuffer.hpp>
  23. #include <engine/gl/shader-program.hpp>
  24. #include <engine/gl/shader-variable.hpp>
  25. #include <engine/gl/vertex-buffer.hpp>
  26. #include <engine/gl/vertex-array.hpp>
  27. #include <engine/gl/vertex-attribute.hpp>
  28. #include <engine/gl/drawing-mode.hpp>
  29. #include <engine/gl/texture-2d.hpp>
  30. #include <engine/gl/texture-wrapping.hpp>
  31. #include <engine/gl/texture-filter.hpp>
  32. #include <engine/render/vertex-attribute.hpp>
  33. #include <engine/render/context.hpp>
  34. #include <engine/render/model.hpp>
  35. #include <engine/render/material.hpp>
  36. #include <engine/scene/camera.hpp>
  37. #include <engine/utility/fundamental-types.hpp>
  38. #include <engine/color/color.hpp>
  39. #include <engine/math/interpolation.hpp>
  40. #include <engine/geom/cartesian.hpp>
  41. #include <engine/geom/spherical.hpp>
  42. #include <engine/physics/orbit/orbit.hpp>
  43. #include <engine/physics/light/photometry.hpp>
  44. #include <bit>
  45. #include <cmath>
  46. #include <stdexcept>
  47. #include <glad/glad.h>
  48. namespace render {
  49. sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager):
  50. pass(rasterizer, framebuffer),
  51. mouse_position({0.0f, 0.0f}),
  52. sky_model(nullptr),
  53. sky_material(nullptr),
  54. sky_model_vao(nullptr),
  55. moon_model(nullptr),
  56. moon_model_vao(nullptr),
  57. moon_material(nullptr),
  58. moon_shader_program(nullptr),
  59. stars_model(nullptr),
  60. stars_model_vao(nullptr),
  61. star_material(nullptr),
  62. star_shader_program(nullptr),
  63. observer_position_tween({0, 0, 0}, math::lerp<float3, float>),
  64. sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
  65. sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
  66. sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
  67. icrf_to_eus_translation({0, 0, 0}, math::lerp<float3, float>),
  68. icrf_to_eus_rotation(math::quaternion<float>::identity(), math::nlerp<float>),
  69. moon_position_tween(float3{0, 0, 0}, math::lerp<float3, float>),
  70. moon_rotation_tween(math::quaternion<float>::identity(), math::nlerp<float>),
  71. moon_angular_radius_tween(0.0f, math::lerp<float, float>),
  72. moon_sunlight_direction_tween(float3{0, 0, 0}, math::lerp<float3, float>),
  73. moon_sunlight_illuminance_tween(float3{0, 0, 0}, math::lerp<float3, float>),
  74. moon_planetlight_direction_tween(float3{0, 0, 0}, math::lerp<float3, float>),
  75. moon_planetlight_illuminance_tween(float3{0, 0, 0}, math::lerp<float3, float>),
  76. moon_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp<float3, float>),
  77. magnification(1.0f)
  78. {
  79. // Build quad VBO and VAO
  80. const float2 vertex_positions[] =
  81. {
  82. {-1.0f, 1.0f},
  83. {-1.0f, -1.0f},
  84. { 1.0f, 1.0f},
  85. { 1.0f, -1.0f}
  86. };
  87. const auto vertex_data = std::as_bytes(std::span{vertex_positions});
  88. std::size_t vertex_size = 2;
  89. std::size_t vertex_stride = sizeof(float) * vertex_size;
  90. quad_vbo = std::make_unique<gl::vertex_buffer>(gl::buffer_usage::static_draw, vertex_data.size(), vertex_data);
  91. quad_vao = std::make_unique<gl::vertex_array>();
  92. // Define position vertex attribute
  93. gl::vertex_attribute position_attribute;
  94. position_attribute.buffer = quad_vbo.get();
  95. position_attribute.offset = 0;
  96. position_attribute.stride = vertex_stride;
  97. position_attribute.type = gl::vertex_attribute_type::float_32;
  98. position_attribute.components = 2;
  99. // Bind vertex attributes to VAO
  100. quad_vao->bind(render::vertex_attribute::position, position_attribute);
  101. // Transmittance LUT
  102. {
  103. // Construct transmittance LUT texture
  104. m_transmittance_lut_texture = std::make_unique<gl::texture_2d>(m_transmittance_lut_resolution.x(), m_transmittance_lut_resolution.y(), gl::pixel_type::float_32, gl::pixel_format::rgb);
  105. m_transmittance_lut_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
  106. m_transmittance_lut_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
  107. m_transmittance_lut_texture->set_max_anisotropy(0.0f);
  108. // Construct transmittance LUT framebuffer and attach texture
  109. m_transmittance_lut_framebuffer = std::make_unique<gl::framebuffer>(m_transmittance_lut_resolution.x(), m_transmittance_lut_resolution.y());
  110. m_transmittance_lut_framebuffer->attach(gl::framebuffer_attachment_type::color, m_transmittance_lut_texture.get());
  111. // Load transmittance LUT shader template
  112. m_transmittance_lut_shader_template = resource_manager->load<gl::shader_template>("sky-transmittance-lut.glsl");
  113. // Build transmittance LUT shader program
  114. rebuild_transmittance_lut_shader_program();
  115. // Build transmittance LUT command buffer
  116. rebuild_transmittance_lut_command_buffer();
  117. }
  118. // Multiscattering LUT
  119. {
  120. // Construct multiscattering LUT texture
  121. m_multiscattering_lut_texture = std::make_unique<gl::texture_2d>(m_multiscattering_lut_resolution.x(), m_multiscattering_lut_resolution.y(), gl::pixel_type::float_32, gl::pixel_format::rgb);
  122. m_multiscattering_lut_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
  123. m_multiscattering_lut_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
  124. m_multiscattering_lut_texture->set_max_anisotropy(0.0f);
  125. // Construct multiscattering LUT framebuffer and attach texture
  126. m_multiscattering_lut_framebuffer = std::make_unique<gl::framebuffer>(m_multiscattering_lut_resolution.x(), m_multiscattering_lut_resolution.y());
  127. m_multiscattering_lut_framebuffer->attach(gl::framebuffer_attachment_type::color, m_multiscattering_lut_texture.get());
  128. // Load multiscattering LUT shader template
  129. m_multiscattering_lut_shader_template = resource_manager->load<gl::shader_template>("sky-multiscattering-lut.glsl");
  130. // Build multiscattering LUT shader program
  131. rebuild_multiscattering_lut_shader_program();
  132. // Build multiscattering LUT command buffer
  133. rebuild_multiscattering_lut_command_buffer();
  134. }
  135. // Luminance LUT
  136. {
  137. // Construct luminance LUT texture
  138. m_luminance_lut_texture = std::make_unique<gl::texture_2d>(m_luminance_lut_resolution.x(), m_luminance_lut_resolution.y(), gl::pixel_type::float_32, gl::pixel_format::rgb);
  139. m_luminance_lut_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
  140. m_luminance_lut_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
  141. m_luminance_lut_texture->set_max_anisotropy(0.0f);
  142. // Construct luminance LUT framebuffer and attach texture
  143. m_luminance_lut_framebuffer = std::make_unique<gl::framebuffer>(m_luminance_lut_resolution.x(), m_luminance_lut_resolution.y());
  144. m_luminance_lut_framebuffer->attach(gl::framebuffer_attachment_type::color, m_luminance_lut_texture.get());
  145. // Load luminance LUT shader template
  146. m_luminance_lut_shader_template = resource_manager->load<gl::shader_template>("sky-luminance-lut.glsl");
  147. // Build luminance LUT shader program
  148. rebuild_luminance_lut_shader_program();
  149. // Build luminance LUT command buffer
  150. rebuild_luminance_lut_command_buffer();
  151. }
  152. // Load sky probe shader template
  153. m_sky_probe_shader_template = resource_manager->load<gl::shader_template>("sky-probe.glsl");
  154. // Build sky probe shader program
  155. m_sky_probe_shader_program = m_sky_probe_shader_template->build({});
  156. if (!m_sky_probe_shader_program->linked())
  157. {
  158. debug::log::error("Failed to build sky probe shader program: {}", m_sky_probe_shader_program->info());
  159. debug::log::warning("{}", m_sky_probe_shader_template->configure(gl::shader_stage::vertex));
  160. }
  161. // Load moon textures
  162. m_moon_albedo_map = resource_manager->load<gl::texture_2d>("moon-albedo.tex");
  163. m_moon_normal_map = resource_manager->load<gl::texture_2d>("moon-normal.tex");
  164. }
  165. void sky_pass::render(render::context& ctx)
  166. {
  167. glDisable(GL_BLEND);
  168. glDisable(GL_DEPTH_TEST);
  169. glDepthMask(GL_FALSE);
  170. glEnable(GL_CULL_FACE);
  171. glCullFace(GL_BACK);
  172. // Render transmittance LUT (if parameters have changed)
  173. if (m_render_transmittance_lut)
  174. {
  175. for (const auto& command: m_transmittance_lut_command_buffer)
  176. {
  177. command();
  178. }
  179. m_render_transmittance_lut = false;
  180. }
  181. // Render multiscattering LUT (if parameters have changed)
  182. if (m_render_multiscattering_lut)
  183. {
  184. for (const auto& command: m_multiscattering_lut_command_buffer)
  185. {
  186. command();
  187. }
  188. m_render_multiscattering_lut = false;
  189. }
  190. // Construct matrices
  191. const scene::camera& camera = *ctx.camera;
  192. float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (camera.get_clip_near() + camera.get_clip_far()) * 0.5f;
  193. float4x4 model = math::scale(math::matrix4<float>::identity(), model_scale);
  194. float4x4 view = float4x4(float3x3(camera.get_view()));
  195. float4x4 model_view = view * model;
  196. const float4x4& projection = camera.get_projection();
  197. float4x4 view_projection = projection * view;
  198. float4x4 model_view_projection = projection * model_view;
  199. camera_exposure = camera.get_exposure_normalization();
  200. // Interpolate observer position
  201. observer_position = observer_position_tween.interpolate(ctx.alpha);
  202. // Construct tweened ICRF to EUS transformation
  203. math::transformation::se3<float> icrf_to_eus =
  204. {
  205. icrf_to_eus_translation.interpolate(ctx.alpha),
  206. icrf_to_eus_rotation.interpolate(ctx.alpha)
  207. };
  208. // Get EUS direction to sun
  209. float3 sun_position = sun_position_tween.interpolate(ctx.alpha);
  210. float3 sun_direction = math::normalize(sun_position);
  211. // Interpolate and expose sun luminance and illuminance
  212. float3 sun_illuminance = sun_illuminance_tween.interpolate(ctx.alpha) * camera_exposure;
  213. float3 sun_luminance = sun_luminance_tween.interpolate(ctx.alpha) * camera_exposure;
  214. float3 moon_position = moon_position_tween.interpolate(ctx.alpha);
  215. float3 moon_direction = math::normalize(moon_position);
  216. float3 moon_illuminance = moon_illuminance_tween.interpolate(ctx.alpha) * camera_exposure;
  217. float moon_angular_radius = moon_angular_radius_tween.interpolate(ctx.alpha) * magnification;
  218. float sun_y = color::aces::ap1<float>.luminance(sun_transmitted_illuminance);
  219. float moon_y = color::aces::ap1<float>.luminance(moon_transmitted_illuminance);
  220. // if (math::max(sun_illuminance) > math::max(moon_illuminance))
  221. // {
  222. dominant_light_direction = sun_direction;
  223. dominant_light_illuminance = sun_illuminance;
  224. // }
  225. // else
  226. // {
  227. // dominant_light_direction = moon_direction;
  228. // dominant_light_illuminance = moon_illuminance;
  229. // }
  230. // Render luminance LUT
  231. // if (m_render_luminance_lut)
  232. {
  233. for (const auto& command: m_luminance_lut_command_buffer)
  234. {
  235. command();
  236. }
  237. }
  238. // Render sky probe
  239. for (const auto& command: m_sky_probe_command_buffer)
  240. {
  241. command();
  242. }
  243. rasterizer->use_framebuffer(*framebuffer);
  244. auto viewport = framebuffer->get_dimensions();
  245. rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
  246. float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))};
  247. // Draw atmosphere
  248. if (sky_model && sky_shader_program)
  249. {
  250. rasterizer->use_program(*sky_shader_program);
  251. // Upload shader parameters
  252. if (model_view_projection_var)
  253. model_view_projection_var->update(model_view_projection);
  254. if (mouse_var)
  255. mouse_var->update(mouse_position);
  256. if (resolution_var)
  257. resolution_var->update(resolution);
  258. if (light_direction_var)
  259. light_direction_var->update(dominant_light_direction);
  260. if (sun_luminance_var)
  261. sun_luminance_var->update(sun_luminance);
  262. if (sun_angular_radius_var)
  263. sun_angular_radius_var->update(sun_angular_radius * magnification);
  264. if (atmosphere_radii_var)
  265. atmosphere_radii_var->update(atmosphere_radii);
  266. if (observer_position_var)
  267. observer_position_var->update(observer_position);
  268. if (sky_transmittance_lut_var)
  269. sky_transmittance_lut_var->update(*m_transmittance_lut_texture);
  270. if (sky_transmittance_lut_resolution_var)
  271. sky_transmittance_lut_resolution_var->update(math::vector2<float>(m_transmittance_lut_resolution));
  272. if (sky_luminance_lut_var)
  273. sky_luminance_lut_var->update(*m_luminance_lut_texture);
  274. if (sky_luminance_lut_resolution_var)
  275. sky_luminance_lut_resolution_var->update(math::vector2<float>(m_luminance_lut_resolution));
  276. //sky_material->update(ctx.alpha);
  277. rasterizer->draw_arrays(*sky_model_vao, sky_model_drawing_mode, sky_model_start_index, sky_model_index_count);
  278. }
  279. glEnable(GL_BLEND);
  280. // glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  281. glBlendFunc(GL_ONE, GL_ONE);
  282. // Flag moon pixels in stencil buffer
  283. glEnable(GL_STENCIL_TEST);
  284. glStencilMask(0xff);
  285. glStencilFunc(GL_ALWAYS, 1, 0xff);
  286. glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  287. // Draw moon model
  288. //if (moon_position.y() >= -moon_angular_radius)
  289. if (moon_shader_program)
  290. {
  291. float moon_distance = (camera.get_clip_near() + camera.get_clip_far()) * 0.5f;
  292. float moon_radius = moon_angular_radius * moon_distance;
  293. math::transform<float> moon_transform;
  294. moon_transform.translation = math::normalize(moon_position) * moon_distance;
  295. moon_transform.rotation = moon_rotation_tween.interpolate(ctx.alpha);
  296. moon_transform.scale = {moon_radius, moon_radius, moon_radius};
  297. model = moon_transform.matrix();
  298. float3x3 normal_model = math::transpose(math::inverse(float3x3(model)));
  299. rasterizer->use_program(*moon_shader_program);
  300. if (moon_model_var)
  301. moon_model_var->update(model);
  302. if (moon_view_projection_var)
  303. moon_view_projection_var->update(view_projection);
  304. if (moon_normal_model_var)
  305. moon_normal_model_var->update(normal_model);
  306. if (moon_camera_position_var)
  307. moon_camera_position_var->update(camera.get_translation());
  308. if (moon_sunlight_direction_var)
  309. moon_sunlight_direction_var->update(math::normalize(moon_sunlight_direction_tween.interpolate(ctx.alpha)));
  310. if (moon_sunlight_illuminance_var)
  311. moon_sunlight_illuminance_var->update(moon_sunlight_illuminance_tween.interpolate(ctx.alpha) * camera_exposure);
  312. if (moon_planetlight_direction_var)
  313. moon_planetlight_direction_var->update(math::normalize(moon_planetlight_direction_tween.interpolate(ctx.alpha)));
  314. if (moon_planetlight_illuminance_var)
  315. moon_planetlight_illuminance_var->update(moon_planetlight_illuminance_tween.interpolate(ctx.alpha) * camera_exposure);
  316. if (moon_albedo_map_var && m_moon_albedo_map)
  317. moon_albedo_map_var->update(*m_moon_albedo_map);
  318. if (moon_normal_map_var && m_moon_normal_map)
  319. moon_normal_map_var->update(*m_moon_normal_map);
  320. if (moon_observer_position_var)
  321. moon_observer_position_var->update(observer_position);
  322. if (moon_sky_transmittance_lut_var)
  323. moon_sky_transmittance_lut_var->update(*m_transmittance_lut_texture);
  324. if (moon_atmosphere_radii_var)
  325. moon_atmosphere_radii_var->update(atmosphere_radii);
  326. //moon_material->update(ctx.alpha);
  327. rasterizer->draw_arrays(*moon_model_vao, moon_model_drawing_mode, moon_model_start_index, moon_model_index_count);
  328. }
  329. // Prevent stars from being drawn in front of the moon
  330. glStencilMask(0x00);
  331. glStencilFunc(GL_NOTEQUAL, 1, 0xff);
  332. // Draw stars
  333. if (star_shader_program)
  334. {
  335. float star_distance = (camera.get_clip_near() + camera.get_clip_far()) * 0.5f;
  336. model = float4x4(float3x3(icrf_to_eus.r));
  337. model = math::scale(model, {star_distance, star_distance, star_distance});
  338. model_view_projection = view_projection * model;
  339. rasterizer->use_program(*star_shader_program);
  340. if (star_model_view_projection_var)
  341. star_model_view_projection_var->update(model_view_projection);
  342. if (star_exposure_var)
  343. star_exposure_var->update(camera_exposure);
  344. if (star_inv_resolution_var)
  345. star_inv_resolution_var->update(1.0f / resolution);
  346. //star_material->update(ctx.alpha);
  347. rasterizer->draw_arrays(*stars_model_vao, stars_model_drawing_mode, stars_model_start_index, stars_model_index_count);
  348. }
  349. glDisable(GL_STENCIL_TEST);
  350. }
  351. void sky_pass::set_transmittance_lut_sample_count(std::uint16_t count)
  352. {
  353. if (m_transmittance_lut_sample_count != count)
  354. {
  355. m_transmittance_lut_sample_count = count;
  356. // Rebuild transmittance LUT shader program and command buffer
  357. rebuild_transmittance_lut_shader_program();
  358. rebuild_transmittance_lut_command_buffer();
  359. // Trigger rendering of transmittance LUT
  360. m_render_transmittance_lut = true;
  361. }
  362. }
  363. void sky_pass::set_transmittance_lut_resolution(const math::vector2<std::uint16_t>& resolution)
  364. {
  365. if (m_transmittance_lut_resolution.x() != resolution.x() || m_transmittance_lut_resolution.y() != resolution.y())
  366. {
  367. m_transmittance_lut_resolution = resolution;
  368. m_transmittance_lut_texture->resize(resolution.x(), resolution.y(), nullptr);
  369. m_transmittance_lut_framebuffer->resize({resolution.x(), resolution.y()});
  370. // Trigger rendering of transmittance LUT
  371. m_render_transmittance_lut = true;
  372. }
  373. }
  374. void sky_pass::set_multiscattering_lut_direction_sample_count(std::uint16_t count)
  375. {
  376. if (m_multiscattering_lut_direction_sample_count != count)
  377. {
  378. m_multiscattering_lut_direction_sample_count = count;
  379. // Rebuild multiscattering LUT shader program and command buffer
  380. rebuild_multiscattering_lut_shader_program();
  381. rebuild_multiscattering_lut_command_buffer();
  382. // Trigger rendering of multiscattering LUT
  383. m_render_multiscattering_lut = true;
  384. }
  385. }
  386. void sky_pass::set_multiscattering_lut_scatter_sample_count(std::uint16_t count)
  387. {
  388. if (m_multiscattering_lut_scatter_sample_count != count)
  389. {
  390. m_multiscattering_lut_scatter_sample_count = count;
  391. // Rebuild multiscattering LUT shader program and command buffer
  392. rebuild_multiscattering_lut_shader_program();
  393. rebuild_multiscattering_lut_command_buffer();
  394. // Trigger rendering of multiscattering LUT
  395. m_render_multiscattering_lut = true;
  396. }
  397. }
  398. void sky_pass::set_multiscattering_lut_resolution(const math::vector2<std::uint16_t>& resolution)
  399. {
  400. if (m_multiscattering_lut_resolution.x() != resolution.x() || m_multiscattering_lut_resolution.y() != resolution.y())
  401. {
  402. m_multiscattering_lut_resolution = resolution;
  403. m_multiscattering_lut_texture->resize(resolution.x(), resolution.y(), nullptr);
  404. m_multiscattering_lut_framebuffer->resize({resolution.x(), resolution.y()});
  405. // Trigger rendering of multiscattering LUT
  406. m_render_multiscattering_lut = true;
  407. }
  408. }
  409. void sky_pass::set_luminance_lut_sample_count(std::uint16_t count)
  410. {
  411. if (m_luminance_lut_sample_count != count)
  412. {
  413. m_luminance_lut_sample_count = count;
  414. // Rebuild luminance LUT shader program and command buffer
  415. rebuild_luminance_lut_shader_program();
  416. rebuild_luminance_lut_command_buffer();
  417. // Trigger rendering of luminance LUT
  418. m_render_luminance_lut = true;
  419. }
  420. }
  421. void sky_pass::set_luminance_lut_resolution(const math::vector2<std::uint16_t>& resolution)
  422. {
  423. if (m_luminance_lut_resolution.x() != resolution.x() || m_luminance_lut_resolution.y() != resolution.y())
  424. {
  425. m_luminance_lut_resolution = resolution;
  426. m_luminance_lut_texture->resize(resolution.x(), resolution.y(), nullptr);
  427. m_luminance_lut_framebuffer->resize({resolution.x(), resolution.y()});
  428. // Trigger rendering of luminance LUT
  429. m_render_luminance_lut = true;
  430. }
  431. }
  432. void sky_pass::set_sky_model(std::shared_ptr<render::model> model)
  433. {
  434. sky_model = model;
  435. sky_shader_program = nullptr;
  436. if (sky_model)
  437. {
  438. sky_model_vao = model->get_vertex_array().get();
  439. for (const auto& group: model->get_groups())
  440. {
  441. sky_material = group.material.get();
  442. sky_model_drawing_mode = group.drawing_mode;
  443. sky_model_start_index = group.start_index;
  444. sky_model_index_count = group.index_count;
  445. }
  446. if (sky_material)
  447. {
  448. sky_shader_program = sky_material->get_shader_template()->build();
  449. if (sky_shader_program->linked())
  450. {
  451. model_view_projection_var = sky_shader_program->variable("model_view_projection");
  452. mouse_var = sky_shader_program->variable("mouse");
  453. resolution_var = sky_shader_program->variable("resolution");
  454. light_direction_var = sky_shader_program->variable("light_direction");
  455. sun_luminance_var = sky_shader_program->variable("sun_luminance");
  456. sun_angular_radius_var = sky_shader_program->variable("sun_angular_radius");
  457. atmosphere_radii_var = sky_shader_program->variable("atmosphere_radii");
  458. observer_position_var = sky_shader_program->variable("observer_position");
  459. sky_transmittance_lut_var = sky_shader_program->variable("sky_transmittance_lut");
  460. sky_transmittance_lut_resolution_var = sky_shader_program->variable("sky_transmittance_lut_resolution");
  461. sky_luminance_lut_var = sky_shader_program->variable("sky_luminance_lut");
  462. sky_luminance_lut_resolution_var = sky_shader_program->variable("sky_luminance_lut_resolution");
  463. }
  464. else
  465. {
  466. debug::log::error("Failed to build sky shader program: {}", sky_shader_program->info());
  467. debug::log::warning("{}", sky_material->get_shader_template()->configure(gl::shader_stage::vertex));
  468. }
  469. }
  470. }
  471. else
  472. {
  473. sky_model_vao = nullptr;
  474. }
  475. }
  476. void sky_pass::set_moon_model(std::shared_ptr<render::model> model)
  477. {
  478. moon_model = model;
  479. moon_shader_program = nullptr;
  480. if (moon_model)
  481. {
  482. moon_model_vao = model->get_vertex_array().get();
  483. for (const auto& group: model->get_groups())
  484. {
  485. moon_material = group.material.get();
  486. moon_model_drawing_mode = group.drawing_mode;
  487. moon_model_start_index = group.start_index;
  488. moon_model_index_count = group.index_count;
  489. }
  490. if (moon_material)
  491. {
  492. moon_shader_program = moon_material->get_shader_template()->build();
  493. if (moon_shader_program->linked())
  494. {
  495. moon_model_var = moon_shader_program->variable("model");
  496. moon_view_projection_var = moon_shader_program->variable("view_projection");
  497. moon_normal_model_var = moon_shader_program->variable("normal_model");
  498. moon_camera_position_var = moon_shader_program->variable("camera_position");
  499. moon_sunlight_direction_var = moon_shader_program->variable("sunlight_direction");
  500. moon_sunlight_illuminance_var = moon_shader_program->variable("sunlight_illuminance");
  501. moon_planetlight_direction_var = moon_shader_program->variable("planetlight_direction");
  502. moon_planetlight_illuminance_var = moon_shader_program->variable("planetlight_illuminance");
  503. moon_albedo_map_var = moon_shader_program->variable("albedo_map");
  504. moon_normal_map_var = moon_shader_program->variable("normal_map");
  505. moon_observer_position_var = moon_shader_program->variable("observer_position");
  506. moon_sky_transmittance_lut_var = moon_shader_program->variable("sky_transmittance_lut");
  507. moon_atmosphere_radii_var = moon_shader_program->variable("atmosphere_radii");
  508. }
  509. else
  510. {
  511. debug::log::error("Failed to build moon shader program: {}", moon_shader_program->info());
  512. debug::log::warning("{}", moon_material->get_shader_template()->configure(gl::shader_stage::vertex));
  513. }
  514. }
  515. }
  516. else
  517. {
  518. moon_model = nullptr;
  519. }
  520. }
  521. void sky_pass::set_stars_model(std::shared_ptr<render::model> model)
  522. {
  523. stars_model = model;
  524. star_shader_program = nullptr;
  525. if (stars_model)
  526. {
  527. stars_model_vao = model->get_vertex_array().get();
  528. for (const auto& group: model->get_groups())
  529. {
  530. stars_model_drawing_mode = group.drawing_mode;
  531. stars_model_start_index = group.start_index;
  532. stars_model_index_count = group.index_count;
  533. star_material = group.material.get();
  534. }
  535. if (star_material)
  536. {
  537. star_shader_program = star_material->get_shader_template()->build();
  538. if (star_shader_program->linked())
  539. {
  540. star_model_view_projection_var = star_shader_program->variable("model_view_projection");
  541. star_exposure_var = star_shader_program->variable("camera_exposure");
  542. star_inv_resolution_var = star_shader_program->variable("inv_resolution");
  543. }
  544. else
  545. {
  546. debug::log::error("Failed to build star shader program: {}", star_shader_program->info());
  547. debug::log::warning("{}", star_material->get_shader_template()->configure(gl::shader_stage::vertex));
  548. }
  549. }
  550. }
  551. else
  552. {
  553. stars_model = nullptr;
  554. }
  555. }
  556. void sky_pass::update_tweens()
  557. {
  558. observer_position_tween.update();
  559. sun_position_tween.update();
  560. sun_luminance_tween.update();
  561. sun_illuminance_tween.update();
  562. icrf_to_eus_translation.update();
  563. icrf_to_eus_rotation.update();
  564. moon_position_tween.update();
  565. moon_rotation_tween.update();
  566. moon_angular_radius_tween.update();
  567. moon_sunlight_direction_tween.update();
  568. moon_sunlight_illuminance_tween.update();
  569. moon_planetlight_direction_tween.update();
  570. moon_planetlight_illuminance_tween.update();
  571. moon_illuminance_tween.update();
  572. }
  573. void sky_pass::set_magnification(float magnification)
  574. {
  575. this->magnification = magnification;
  576. }
  577. void sky_pass::set_icrf_to_eus(const math::transformation::se3<float>& transformation)
  578. {
  579. icrf_to_eus_translation[1] = transformation.t;
  580. icrf_to_eus_rotation[1] = transformation.r;
  581. }
  582. void sky_pass::set_sun_position(const float3& position)
  583. {
  584. sun_position_tween[1] = position;
  585. }
  586. void sky_pass::set_sun_illuminance(const float3& illuminance, const float3& transmitted_illuminance)
  587. {
  588. sun_illuminance_tween[1] = illuminance;
  589. sun_transmitted_illuminance = transmitted_illuminance;
  590. }
  591. void sky_pass::set_sun_luminance(const float3& luminance)
  592. {
  593. sun_luminance_tween[1] = luminance;
  594. }
  595. void sky_pass::set_sun_angular_radius(float radius)
  596. {
  597. sun_angular_radius = radius;
  598. }
  599. void sky_pass::set_planet_radius(float radius)
  600. {
  601. atmosphere_radii[0] = radius;
  602. atmosphere_radii[1] = atmosphere_radii[0] + atmosphere_upper_limit;
  603. atmosphere_radii[2] = atmosphere_radii[0] * atmosphere_radii[0];
  604. atmosphere_radii[3] = atmosphere_radii[1] * atmosphere_radii[1];
  605. observer_position_tween[1] = {0.0f, atmosphere_radii.x() + observer_elevation, 0.0f};
  606. // Trigger transmittance and multiscattering LUT render
  607. m_render_transmittance_lut = true;
  608. m_render_multiscattering_lut = true;
  609. }
  610. void sky_pass::set_atmosphere_upper_limit(float limit)
  611. {
  612. atmosphere_upper_limit = limit;
  613. atmosphere_radii[1] = atmosphere_radii[0] + atmosphere_upper_limit;
  614. atmosphere_radii[3] = atmosphere_radii[1] * atmosphere_radii[1];
  615. // Trigger transmittance and multiscattering LUT render
  616. m_render_transmittance_lut = true;
  617. m_render_multiscattering_lut = true;
  618. }
  619. void sky_pass::set_observer_elevation(float elevation)
  620. {
  621. observer_elevation = elevation;
  622. observer_position_tween[1] = {0.0f, atmosphere_radii.x() + observer_elevation, 0.0f};
  623. }
  624. void sky_pass::set_rayleigh_parameters(float scale_height, const float3& scattering)
  625. {
  626. rayleigh_parameters =
  627. {
  628. -1.0f / scale_height,
  629. scattering.x(),
  630. scattering.y(),
  631. scattering.z()
  632. };
  633. // Trigger transmittance and multiscattering LUT render
  634. m_render_transmittance_lut = true;
  635. m_render_multiscattering_lut = true;
  636. }
  637. void sky_pass::set_mie_parameters(float scale_height, float scattering, float extinction, float anisotropy)
  638. {
  639. mie_parameters =
  640. {
  641. -1.0f / scale_height,
  642. scattering,
  643. extinction,
  644. anisotropy
  645. };
  646. // Trigger transmittance and multiscattering LUT render
  647. m_render_transmittance_lut = true;
  648. m_render_multiscattering_lut = true;
  649. }
  650. void sky_pass::set_ozone_parameters(float lower_limit, float upper_limit, float mode, const float3& absorption)
  651. {
  652. ozone_distribution =
  653. {
  654. 1.0f / (lower_limit - mode),
  655. 1.0f / (upper_limit - mode),
  656. mode
  657. };
  658. ozone_absorption = absorption;
  659. // Trigger transmittance and multiscattering LUT render
  660. m_render_transmittance_lut = true;
  661. m_render_multiscattering_lut = true;
  662. }
  663. void sky_pass::set_airglow_luminance(const float3& luminance)
  664. {
  665. airglow_luminance = luminance;
  666. }
  667. void sky_pass::set_ground_albedo(const float3& albedo)
  668. {
  669. m_ground_albedo = albedo;
  670. // Trigger multiscattering LUT render
  671. m_render_multiscattering_lut = true;
  672. }
  673. void sky_pass::set_moon_position(const float3& position)
  674. {
  675. moon_position_tween[1] = position;
  676. }
  677. void sky_pass::set_moon_rotation(const math::quaternion<float>& rotation)
  678. {
  679. moon_rotation_tween[1] = rotation;
  680. }
  681. void sky_pass::set_moon_angular_radius(float angular_radius)
  682. {
  683. moon_angular_radius_tween[1] = angular_radius;
  684. }
  685. void sky_pass::set_moon_sunlight_direction(const float3& direction)
  686. {
  687. moon_sunlight_direction_tween[1] = direction;
  688. }
  689. void sky_pass::set_moon_sunlight_illuminance(const float3& illuminance)
  690. {
  691. moon_sunlight_illuminance_tween[1] = illuminance;
  692. }
  693. void sky_pass::set_moon_planetlight_direction(const float3& direction)
  694. {
  695. moon_planetlight_direction_tween[1] = direction;
  696. }
  697. void sky_pass::set_moon_planetlight_illuminance(const float3& illuminance)
  698. {
  699. moon_planetlight_illuminance_tween[1] = illuminance;
  700. }
  701. void sky_pass::set_moon_illuminance(const float3& illuminance, const float3& transmitted_illuminance)
  702. {
  703. moon_illuminance_tween[1] = illuminance;
  704. moon_transmitted_illuminance = transmitted_illuminance;
  705. }
  706. void sky_pass::set_sky_probe(std::shared_ptr<scene::light_probe> probe)
  707. {
  708. m_sky_probe = probe;
  709. if (m_sky_probe && m_sky_probe->get_luminance_texture())
  710. {
  711. auto& luminance_texture = *m_sky_probe->get_luminance_texture();
  712. std::uint16_t face_size = luminance_texture.get_face_size();
  713. const std::uint8_t mip_count = static_cast<std::uint8_t>(std::bit_width(face_size));
  714. m_sky_probe_framebuffers.resize(mip_count);
  715. for (std::uint8_t i = 0; i < mip_count; ++i)
  716. {
  717. m_sky_probe_framebuffers[i] = std::make_unique<gl::framebuffer>(face_size, face_size);
  718. m_sky_probe_framebuffers[i]->attach(gl::framebuffer_attachment_type::color, &luminance_texture, i);
  719. face_size >>= 1;
  720. }
  721. }
  722. else
  723. {
  724. m_sky_probe_framebuffers.clear();
  725. }
  726. rebuild_sky_probe_command_buffer();
  727. }
  728. void sky_pass::rebuild_transmittance_lut_shader_program()
  729. {
  730. m_transmittance_lut_shader_program = m_transmittance_lut_shader_template->build
  731. (
  732. {
  733. {"SAMPLE_COUNT", std::to_string(m_transmittance_lut_sample_count)}
  734. }
  735. );
  736. if (!m_transmittance_lut_shader_program->linked())
  737. {
  738. debug::log::error("Failed to build sky transmittance LUT shader program: {}", m_transmittance_lut_shader_program->info());
  739. debug::log::warning("{}", m_transmittance_lut_shader_template->configure(gl::shader_stage::vertex));
  740. }
  741. }
  742. void sky_pass::rebuild_transmittance_lut_command_buffer()
  743. {
  744. m_transmittance_lut_command_buffer.clear();
  745. if (!m_transmittance_lut_shader_program->linked() || !m_transmittance_lut_texture)
  746. {
  747. return;
  748. }
  749. // Bind framebuffer and shader program
  750. m_transmittance_lut_command_buffer.emplace_back
  751. (
  752. [&]()
  753. {
  754. rasterizer->set_viewport(0, 0, m_transmittance_lut_resolution.x(), m_transmittance_lut_resolution.y());
  755. rasterizer->use_framebuffer(*m_transmittance_lut_framebuffer);
  756. rasterizer->use_program(*m_transmittance_lut_shader_program);
  757. }
  758. );
  759. // Update shader variables
  760. if (auto atmosphere_radii_var = m_transmittance_lut_shader_program->variable("atmosphere_radii"))
  761. {
  762. m_transmittance_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->update(atmosphere_radii);});
  763. }
  764. if (auto rayleigh_parameters_var = m_transmittance_lut_shader_program->variable("rayleigh_parameters"))
  765. {
  766. m_transmittance_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
  767. }
  768. if (auto mie_parameters_var = m_transmittance_lut_shader_program->variable("mie_parameters"))
  769. {
  770. m_transmittance_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
  771. }
  772. if (auto ozone_distribution_var = m_transmittance_lut_shader_program->variable("ozone_distribution"))
  773. {
  774. m_transmittance_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
  775. }
  776. if (auto ozone_absorption_var = m_transmittance_lut_shader_program->variable("ozone_absorption"))
  777. {
  778. m_transmittance_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
  779. }
  780. if (auto resolution_var = m_transmittance_lut_shader_program->variable("resolution"))
  781. {
  782. m_transmittance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2<float>(m_transmittance_lut_resolution));});
  783. }
  784. // Draw quad
  785. m_transmittance_lut_command_buffer.emplace_back
  786. (
  787. [&]()
  788. {
  789. rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangle_strip, 0, 4);
  790. }
  791. );
  792. }
  793. void sky_pass::rebuild_multiscattering_lut_shader_program()
  794. {
  795. m_multiscattering_lut_shader_program = m_multiscattering_lut_shader_template->build
  796. (
  797. {
  798. {"DIRECTION_SAMPLE_COUNT", std::to_string(m_multiscattering_lut_direction_sample_count)},
  799. {"SCATTER_SAMPLE_COUNT", std::to_string(m_multiscattering_lut_scatter_sample_count)}
  800. }
  801. );
  802. if (!m_multiscattering_lut_shader_program->linked())
  803. {
  804. debug::log::error("Failed to build sky multiscattering LUT shader program: {}", m_multiscattering_lut_shader_program->info());
  805. debug::log::warning("{}", m_multiscattering_lut_shader_template->configure(gl::shader_stage::vertex));
  806. }
  807. }
  808. void sky_pass::rebuild_multiscattering_lut_command_buffer()
  809. {
  810. m_multiscattering_lut_command_buffer.clear();
  811. if (!m_multiscattering_lut_shader_program->linked() || !m_multiscattering_lut_texture)
  812. {
  813. return;
  814. }
  815. // Bind framebuffer and shader program
  816. m_multiscattering_lut_command_buffer.emplace_back
  817. (
  818. [&]()
  819. {
  820. rasterizer->set_viewport(0, 0, m_multiscattering_lut_resolution.x(), m_multiscattering_lut_resolution.y());
  821. rasterizer->use_framebuffer(*m_multiscattering_lut_framebuffer);
  822. rasterizer->use_program(*m_multiscattering_lut_shader_program);
  823. }
  824. );
  825. // Update shader variables
  826. if (auto atmosphere_radii_var = m_multiscattering_lut_shader_program->variable("atmosphere_radii"))
  827. {
  828. m_multiscattering_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->update(atmosphere_radii);});
  829. }
  830. if (auto rayleigh_parameters_var = m_multiscattering_lut_shader_program->variable("rayleigh_parameters"))
  831. {
  832. m_multiscattering_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
  833. }
  834. if (auto mie_parameters_var = m_multiscattering_lut_shader_program->variable("mie_parameters"))
  835. {
  836. m_multiscattering_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
  837. }
  838. if (auto ozone_distribution_var = m_multiscattering_lut_shader_program->variable("ozone_distribution"))
  839. {
  840. m_multiscattering_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
  841. }
  842. if (auto ozone_absorption_var = m_multiscattering_lut_shader_program->variable("ozone_absorption"))
  843. {
  844. m_multiscattering_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
  845. }
  846. if (auto ground_albedo_var = m_multiscattering_lut_shader_program->variable("ground_albedo"))
  847. {
  848. m_multiscattering_lut_command_buffer.emplace_back([&, ground_albedo_var](){ground_albedo_var->update(m_ground_albedo);});
  849. }
  850. if (auto resolution_var = m_multiscattering_lut_shader_program->variable("resolution"))
  851. {
  852. m_multiscattering_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2<float>(m_multiscattering_lut_resolution));});
  853. }
  854. if (auto transmittance_lut_var = m_multiscattering_lut_shader_program->variable("transmittance_lut"))
  855. {
  856. m_multiscattering_lut_command_buffer.emplace_back([&, transmittance_lut_var](){transmittance_lut_var->update(*m_transmittance_lut_texture);});
  857. }
  858. // Draw quad
  859. m_multiscattering_lut_command_buffer.emplace_back
  860. (
  861. [&]()
  862. {
  863. rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangle_strip, 0, 4);
  864. }
  865. );
  866. }
  867. void sky_pass::rebuild_luminance_lut_shader_program()
  868. {
  869. m_luminance_lut_shader_program = m_luminance_lut_shader_template->build
  870. (
  871. {
  872. {"SAMPLE_COUNT", std::to_string(m_luminance_lut_sample_count)}
  873. }
  874. );
  875. if (!m_luminance_lut_shader_program->linked())
  876. {
  877. debug::log::error("Failed to build sky luminance LUT shader program: {}", m_luminance_lut_shader_program->info());
  878. debug::log::warning("{}", m_luminance_lut_shader_template->configure(gl::shader_stage::vertex));
  879. }
  880. }
  881. void sky_pass::rebuild_luminance_lut_command_buffer()
  882. {
  883. m_luminance_lut_command_buffer.clear();
  884. if (!m_luminance_lut_shader_program->linked() || !m_luminance_lut_texture)
  885. {
  886. return;
  887. }
  888. // Bind framebuffer and shader program
  889. m_luminance_lut_command_buffer.emplace_back
  890. (
  891. [&]()
  892. {
  893. rasterizer->set_viewport(0, 0, m_luminance_lut_resolution.x(), m_luminance_lut_resolution.y());
  894. rasterizer->use_framebuffer(*m_luminance_lut_framebuffer);
  895. rasterizer->use_program(*m_luminance_lut_shader_program);
  896. }
  897. );
  898. // Update shader variables
  899. if (auto light_direction_var = m_luminance_lut_shader_program->variable("light_direction"))
  900. {
  901. m_luminance_lut_command_buffer.emplace_back([&, light_direction_var](){light_direction_var->update(dominant_light_direction);});
  902. }
  903. if (auto light_illuminance_var = m_luminance_lut_shader_program->variable("light_illuminance"))
  904. {
  905. m_luminance_lut_command_buffer.emplace_back([&, light_illuminance_var](){light_illuminance_var->update(dominant_light_illuminance);});
  906. }
  907. if (auto atmosphere_radii_var = m_luminance_lut_shader_program->variable("atmosphere_radii"))
  908. {
  909. m_luminance_lut_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->update(atmosphere_radii);});
  910. }
  911. if (auto observer_position_var = m_luminance_lut_shader_program->variable("observer_position"))
  912. {
  913. m_luminance_lut_command_buffer.emplace_back([&, observer_position_var](){observer_position_var->update(observer_position);});
  914. }
  915. if (auto rayleigh_parameters_var = m_luminance_lut_shader_program->variable("rayleigh_parameters"))
  916. {
  917. m_luminance_lut_command_buffer.emplace_back([&, rayleigh_parameters_var](){rayleigh_parameters_var->update(rayleigh_parameters);});
  918. }
  919. if (auto mie_parameters_var = m_luminance_lut_shader_program->variable("mie_parameters"))
  920. {
  921. m_luminance_lut_command_buffer.emplace_back([&, mie_parameters_var](){mie_parameters_var->update(mie_parameters);});
  922. }
  923. if (auto ozone_distribution_var = m_luminance_lut_shader_program->variable("ozone_distribution"))
  924. {
  925. m_luminance_lut_command_buffer.emplace_back([&, ozone_distribution_var](){ozone_distribution_var->update(ozone_distribution);});
  926. }
  927. if (auto ozone_absorption_var = m_luminance_lut_shader_program->variable("ozone_absorption"))
  928. {
  929. m_luminance_lut_command_buffer.emplace_back([&, ozone_absorption_var](){ozone_absorption_var->update(ozone_absorption);});
  930. }
  931. if (auto airglow_luminance_var = m_luminance_lut_shader_program->variable("airglow_luminance"))
  932. {
  933. m_luminance_lut_command_buffer.emplace_back([&, airglow_luminance_var](){airglow_luminance_var->update(airglow_luminance * camera_exposure);});
  934. }
  935. if (auto resolution_var = m_luminance_lut_shader_program->variable("resolution"))
  936. {
  937. m_luminance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2<float>(m_luminance_lut_resolution));});
  938. }
  939. if (auto transmittance_lut_var = m_luminance_lut_shader_program->variable("transmittance_lut"))
  940. {
  941. m_luminance_lut_command_buffer.emplace_back([&, transmittance_lut_var](){transmittance_lut_var->update(*m_transmittance_lut_texture);});
  942. }
  943. if (auto multiscattering_lut_var = m_luminance_lut_shader_program->variable("multiscattering_lut"))
  944. {
  945. m_luminance_lut_command_buffer.emplace_back([&, multiscattering_lut_var](){multiscattering_lut_var->update(*m_multiscattering_lut_texture);});
  946. }
  947. // Draw quad
  948. m_luminance_lut_command_buffer.emplace_back
  949. (
  950. [&]()
  951. {
  952. rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangle_strip, 0, 4);
  953. }
  954. );
  955. }
  956. void sky_pass::rebuild_sky_probe_command_buffer()
  957. {
  958. m_sky_probe_command_buffer.clear();
  959. if (!m_sky_probe_shader_program->linked() || m_sky_probe_framebuffers.empty())
  960. {
  961. return;
  962. }
  963. // Bind sky probe framebuffer and shader program
  964. m_sky_probe_command_buffer.emplace_back
  965. (
  966. [&]()
  967. {
  968. const auto resolution = m_sky_probe->get_luminance_texture()->get_face_size();
  969. rasterizer->set_viewport(0, 0, resolution, resolution);
  970. rasterizer->use_framebuffer(*m_sky_probe_framebuffers[0]);
  971. rasterizer->use_program(*m_sky_probe_shader_program);
  972. }
  973. );
  974. if (auto luminance_lut_var = m_sky_probe_shader_program->variable("luminance_lut"))
  975. {
  976. m_sky_probe_command_buffer.emplace_back([&, luminance_lut_var](){luminance_lut_var->update(*m_luminance_lut_texture);});
  977. }
  978. if (auto light_direction_var = m_sky_probe_shader_program->variable("light_direction"))
  979. {
  980. m_sky_probe_command_buffer.emplace_back([&, light_direction_var](){light_direction_var->update(dominant_light_direction);});
  981. }
  982. if (auto light_illuminance_var = m_sky_probe_shader_program->variable("light_illuminance"))
  983. {
  984. m_sky_probe_command_buffer.emplace_back([&, light_illuminance_var](){light_illuminance_var->update(dominant_light_illuminance);});
  985. }
  986. if (auto observer_position_var = m_sky_probe_shader_program->variable("observer_position"))
  987. {
  988. m_sky_probe_command_buffer.emplace_back([&, observer_position_var](){observer_position_var->update(observer_position);});
  989. }
  990. if (auto atmosphere_radii_var = m_sky_probe_shader_program->variable("atmosphere_radii"))
  991. {
  992. m_sky_probe_command_buffer.emplace_back([&, atmosphere_radii_var](){atmosphere_radii_var->update(atmosphere_radii);});
  993. }
  994. if (auto ground_albedo_var = m_sky_probe_shader_program->variable("ground_albedo"))
  995. {
  996. m_sky_probe_command_buffer.emplace_back([&, ground_albedo_var](){ground_albedo_var->update(m_ground_albedo);});
  997. }
  998. // Draw point
  999. m_sky_probe_command_buffer.emplace_back
  1000. (
  1001. [&]()
  1002. {
  1003. rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::points, 0, 1);
  1004. m_sky_probe->set_luminance_outdated(true);
  1005. m_sky_probe->set_illuminance_outdated(true);
  1006. }
  1007. );
  1008. }
  1009. } // namespace render