Unravel Engine C++ Reference
Loading...
Searching...
No Matches
atmospheric_pass_perez.cpp
Go to the documentation of this file.
6#include <graphics/texture.h>
7#include <cstring>
8
9namespace unravel
10{
11
12namespace
13{
14#ifndef ANONYMOUS
15#define ANONYMOUS anonymous
16#endif
17namespace ANONYMOUS
18{
19// Represents color. Color-space depends on context.
20// In the code below, used to represent color in XYZ, and RGB color-space
21typedef bx::Vec3 Color;
22
23// Performs piecewise linear interpolation of a Color parameter.
24class dynamic_value_controller
25{
26 using value_type = Color;
27 using key_map = std::map<float, value_type>;
28
29public:
30 dynamic_value_controller(const key_map& keymap) : key_map_(keymap)
31 {
32 }
33
34 value_type get_value(float time) const
35 {
36 auto itUpper = key_map_.upper_bound(time + 1e-6f);
37 auto itLower = itUpper;
38 --itLower;
39
40 if(itLower == key_map_.end())
41 {
42 return itUpper->second;
43 }
44
45 if(itUpper == key_map_.end())
46 {
47 return itLower->second;
48 }
49
50 float lowerTime = itLower->first;
51 const auto& lowerVal = itLower->second;
52 float upperTime = itUpper->first;
53 const auto& upperVal = itUpper->second;
54
55 if(lowerTime == upperTime)
56 {
57 return lowerVal;
58 }
59
60 return interpolate(lowerTime, lowerVal, upperTime, upperVal, time);
61 };
62
63private:
64 value_type interpolate(float lowerTime,
65 const value_type& lowerVal,
66 float upperTime,
67 const value_type& upperVal,
68 float time) const
69 {
70 const float tt = (time - lowerTime) / (upperTime - lowerTime);
71 const auto result = bx::lerp(lowerVal, upperVal, tt);
72 return result;
73 };
74
75 const key_map& key_map_;
76};
77
78// HDTV rec. 709 matrix.
79static constexpr float M_XYZ2RGB[] = {
80 3.240479f,
81 -0.969256f,
82 0.055648f,
83 -1.53715f,
84 1.875991f,
85 -0.204043f,
86 -0.49853f,
87 0.041556f,
88 1.057311f,
89};
90
91// Converts color representation from CIE XYZ to RGB color-space.
92Color xyzToRgb(const Color& xyz)
93{
94 Color rgb(bx::InitNone);
95 rgb.x = M_XYZ2RGB[0] * xyz.x + M_XYZ2RGB[3] * xyz.y + M_XYZ2RGB[6] * xyz.z;
96 rgb.y = M_XYZ2RGB[1] * xyz.x + M_XYZ2RGB[4] * xyz.y + M_XYZ2RGB[7] * xyz.z;
97 rgb.z = M_XYZ2RGB[2] * xyz.x + M_XYZ2RGB[5] * xyz.y + M_XYZ2RGB[8] * xyz.z;
98 return rgb;
99};
100
101// Precomputed luminance of sunlight in XYZ colorspace.
102// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
103// This table is used for piecewise linear interpolation. Transitions from and to 0.0 at sunset and sunrise are highly
104// inaccurate
105static std::map<float, Color> sunLuminanceXYZTable = {
106 {5.0f, {0.000000f, 0.000000f, 0.000000f}},
107 {7.0f, {12.703322f, 12.989393f, 9.100411f}},
108 {8.0f, {13.202644f, 13.597814f, 11.524929f}},
109 {9.0f, {13.192974f, 13.597458f, 12.264488f}},
110 {10.0f, {13.132943f, 13.535914f, 12.560032f}},
111 {11.0f, {13.088722f, 13.489535f, 12.692996f}},
112 {12.0f, {13.067827f, 13.467483f, 12.745179f}},
113 {13.0f, {13.069653f, 13.469413f, 12.740822f}},
114 {14.0f, {13.094319f, 13.495428f, 12.678066f}},
115 {15.0f, {13.142133f, 13.545483f, 12.526785f}},
116 {16.0f, {13.201734f, 13.606017f, 12.188001f}},
117 {17.0f, {13.182774f, 13.572725f, 11.311157f}},
118 {18.0f, {12.448635f, 12.672520f, 8.267771f}},
119 {20.0f, {0.000000f, 0.000000f, 0.000000f}},
120};
121
122// Precomputed luminance of sky in the zenith point in XYZ colorspace.
123// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
124// This table is used for piecewise linear interpolation. Day/night transitions are highly inaccurate.
125// The scale of luminance change in Day/night transitions is not preserved.
126// Luminance at night was increased to eliminate need the of HDR render.
127static std::map<float, Color> skyLuminanceXYZTable = {
128 {0.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
129 //{1.0f, {0.308f, 0.308f, 0.410f}},
130 //{2.0f, {0.301f, 0.301f, 0.402f}},
131 //{3.0f, {0.287f, 0.287f, 0.382f}},
132 {4.0f, bx::mul({0.258f, 0.258f, 0.344f}, 0.05f)},
133 {5.0f, {0.258f, 0.258f, 0.344f}},
134 {7.0f, {0.962851f, 1.000000f, 1.747835f}},
135 {8.0f, {0.967787f, 1.000000f, 1.776762f}},
136 {9.0f, {0.970173f, 1.000000f, 1.788413f}},
137 {10.0f, {0.971431f, 1.000000f, 1.794102f}},
138 {11.0f, {0.972099f, 1.000000f, 1.797096f}},
139 {12.0f, {0.972385f, 1.000000f, 1.798389f}},
140 {13.0f, {0.972361f, 1.000000f, 1.798278f}},
141 {14.0f, {0.972020f, 1.000000f, 1.796740f}},
142 {15.0f, {0.971275f, 1.000000f, 1.793407f}},
143 {16.0f, {0.969885f, 1.000000f, 1.787078f}},
144 {17.0f, {0.967216f, 1.000000f, 1.773758f}},
145 {18.0f, {0.961668f, 1.000000f, 1.739891f}},
146 {20.0f, {0.264f, 0.264f, 0.352f}},
147 {21.0f, bx::mul({0.264f, 0.264f, 0.352f}, 0.05f)},
148 //{22.0f, {0.290f, 0.290f, 0.386f}},
149 {23.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
150 {24.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
151};
152
153// Turbidity tables. Taken from:
154// A. J. Preetham, P. Shirley, and B. Smits. A Practical Analytic Model for Daylight. SIGGRAPH '99
155// Coefficients correspond to xyY colorspace.
156static constexpr Color ABCDE[] = {
157 {-0.2592f, -0.2608f, -1.4630f},
158 {0.0008f, 0.0092f, 0.4275f},
159 {0.2125f, 0.2102f, 5.3251f},
160 {-0.8989f, -1.6537f, -2.5771f},
161 {0.0452f, 0.0529f, 0.3703f},
162};
163
164static constexpr Color ABCDE_t[] = {
165 {-0.0193f, -0.0167f, 0.1787f},
166 {-0.0665f, -0.0950f, -0.3554f},
167 {-0.0004f, -0.0079f, -0.0227f},
168 {-0.0641f, -0.0441f, 0.1206f},
169 {-0.0033f, -0.0109f, -0.0670f},
170};
171
172void compute_perez_coeff(float _turbidity, float* _outPerezCoeff)
173{
174 const bx::Vec3 turbidity = {_turbidity, _turbidity, _turbidity};
175 for(uint32_t ii = 0; ii < 5; ++ii)
176 {
177 const bx::Vec3 tmp = bx::mad(ABCDE_t[ii], turbidity, ABCDE[ii]);
178 float* out = _outPerezCoeff + 4 * ii;
179 bx::store(out, tmp);
180 out[3] = 0.0f;
181 }
182}
183
184float hour_of_day(math::vec3 sun_dir)
185{
186 // Define the ground normal vector (assuming flat and horizontal ground)
187 math::vec3 normal(0.0, -1.0, 0.0);
188
189 auto v1 = sun_dir;
190 auto v2 = normal;
191 auto ref = math::vec3(-1.0f, 0.0f, 0.0f);
192
193 float angle = math::orientedAngle(v1, v2, ref); // angle in [-pi, pi]
194 angle = math::mod(angle, 2 * math::pi<float>()); // angle in [0, 2pi]
195 angle = math::degrees(angle);
196 // The hour angle is 0 at 6:00, 90 at 12:00, and 180 at 18:00
197 // Therefore, we can use a simple linear formula to map the hour angle to the hour of day
198 float hour_of_day = angle / 15;
199
200 // Return the hour of day
201 return hour_of_day;
202}
203}
204} // namespace
205
207{
208 vb_.reset();
209 ib_.reset();
210}
211
213{
214 auto& am = ctx.get_cached<asset_manager>();
215 auto vs_sky = am.get_asset<gfx::shader>("engine:/data/shaders/atmospherics/vs_sky.sc");
216 auto fs_sky = am.get_asset<gfx::shader>("engine:/data/shaders/atmospherics/fs_sky.sc");
217 auto fs_cloud = am.get_asset<gfx::shader>("engine:/data/shaders/atmospherics/fs_cloud.sc");
218
219 atmospheric_program_.program = std::make_unique<gpu_program>(vs_sky, fs_sky);
220 atmospheric_program_.cache_uniforms();
221
222 cloud_program_.program = std::make_unique<gpu_program>(vs_sky, fs_cloud);
223 cloud_program_.cache_uniforms();
224
225 int vertical_count = 32;
226 int horizontal_count = 32;
227 std::vector<gfx::screen_pos_vertex> vertices(vertical_count * horizontal_count);
228
229 for(int i = 0; i < vertical_count; i++)
230 {
231 for(int j = 0; j < horizontal_count; j++)
232 {
233 gfx::screen_pos_vertex& v = vertices[i * vertical_count + j];
234 v.x = float(j) / (horizontal_count - 1) * 2.0f - 1.0f;
235 v.y = float(i) / (vertical_count - 1) * 2.0f - 1.0f;
236 }
237 }
238
239 std::vector<uint16_t> indices((vertical_count - 1) * (horizontal_count - 1) * 6);
240
241 int k = 0;
242 for(int i = 0; i < vertical_count - 1; i++)
243 {
244 for(int j = 0; j < horizontal_count - 1; j++)
245 {
246 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 0));
247 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 0));
248 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 1));
249
250 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 0));
251 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 1));
252 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 1));
253 }
254 }
255
256 vb_ = std::make_unique<gfx::vertex_buffer>(
257 gfx::copy(vertices.data(), sizeof(gfx::screen_pos_vertex) * vertical_count * horizontal_count),
259 ib_ = std::make_unique<gfx::index_buffer>(gfx::copy(indices.data(), sizeof(uint16_t) * k));
260
261 sun_.update(0);
262
263 return true;
264}
265
267 const camera& camera,
268 gfx::render_view& rview,
269 delta_t dt,
270 const run_params& params)
271{
272 const auto& view = camera.get_view_relative();
273 const auto& proj = camera.get_projection();
274
275 const auto surface = input.get();
276 const auto output_size = surface->get_size();
277
280 perez.exposition *= params.sky_brightness;
281
282 float hour = ANONYMOUS::hour_of_day(-params.light_direction);
283 float exposition[4] = {0.02f, 3.0f, perez.exposition, hour};
284 float cloud_params[4] = {params.cloud_coverage, params.cloud_base_altitude, params.cloud_time, params.cloud_density};
285 float cloud_params2[4] = {params.cloud_absorption, params.cloud_light_absorption, params.cloud_top_altitude, float(params.cloud_mode)};
286 float cloud_params3[4] = {params.cloud_vol_uv_scale,
290 float cloud_params4[4] = {params.cloud_vol_macro_strength,
292 params.cloud_vol_base_mix,
294
295 auto& cloud_noise = default_textures::get().cloud_noise();
296
297 // === Pass 1: Cloud pre-pass at half resolution with temporal blending (ping-pong) ===
298 // Only run when cloud_mode == volumetric (2)
299 if(params.cloud_mode == 2 && cloud_program_.program && cloud_program_.program->is_valid())
300 {
301 uint32_t half_w = output_size.width / 2;
302 uint32_t half_h = output_size.height / 2;
303 if(half_w < 1) half_w = 1;
304 if(half_h < 1) half_h = 1;
305
306 constexpr uint64_t cloud_tex_flags = BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
307
308 auto& cloud_frame_count = rview.data_get_or_emplace("CLOUD_FRAME_COUNT");
309
310 auto& prev_cloud_time_bits = rview.data_get_or_emplace("CLOUD_PREV_TIME");
311 float prev_cloud_time{};
312 std::memcpy(&prev_cloud_time, &prev_cloud_time_bits, sizeof(float));
313 float cloud_time_delta = params.cloud_time - prev_cloud_time;
314 uint32_t cur_time_bits{};
315 std::memcpy(&cur_time_bits, &params.cloud_time, sizeof(float));
316 prev_cloud_time_bits = cur_time_bits;
317
318 auto& cloud_tex_a = rview.tex_get_or_emplace("CLOUD_PING");
319 if(gfx::needs_recreate(cloud_tex_a, {half_w, half_h}))
320 {
321 cloud_tex_a.reset();
322 cloud_tex_a = std::make_shared<gfx::texture>(half_w, half_h, false, 1,
323 gfx::texture_format::RGBA16F, cloud_tex_flags);
324 cloud_frame_count = 0;
325 }
326
327 auto& cloud_tex_b = rview.tex_get_or_emplace("CLOUD_PONG");
328 if(gfx::needs_recreate(cloud_tex_b, {half_w, half_h}))
329 {
330 cloud_tex_b.reset();
331 cloud_tex_b = std::make_shared<gfx::texture>(half_w, half_h, false, 1,
332 gfx::texture_format::RGBA16F, cloud_tex_flags);
333 cloud_frame_count = 0;
334 }
335
336 uint32_t cur = cloud_frame_count & 1;
337 auto& current_tex = (cur == 0) ? cloud_tex_a : cloud_tex_b;
338 auto& history_tex = (cur == 0) ? cloud_tex_b : cloud_tex_a;
339
340 auto& cloud_fbo_a = rview.fbo_get_or_emplace("CLOUD_FBO_PING");
341 if(gfx::needs_recreate(cloud_fbo_a, {half_w, half_h}))
342 {
343 cloud_fbo_a.reset();
344 cloud_fbo_a = std::make_shared<gfx::frame_buffer>();
345 cloud_fbo_a->populate({cloud_tex_a});
346 }
347
348 auto& cloud_fbo_b = rview.fbo_get_or_emplace("CLOUD_FBO_PONG");
349 if(gfx::needs_recreate(cloud_fbo_b, {half_w, half_h}))
350 {
351 cloud_fbo_b.reset();
352 cloud_fbo_b = std::make_shared<gfx::frame_buffer>();
353 cloud_fbo_b->populate({cloud_tex_b});
354 }
355
356 auto& current_fbo = (cur == 0) ? cloud_fbo_a : cloud_fbo_b;
357
358 gfx::render_pass cloud_pass("Atmospherics/Cloud Pre-Pass");
359 cloud_pass.bind(current_fbo.get());
360 cloud_pass.set_view_proj(view, proj);
361 cloud_pass.clear(BGFX_CLEAR_COLOR, 0x000000FF, 0.0f, 0);
362
363 cloud_program_.program->begin();
364
365 gfx::set_uniform(cloud_program_.u_skyLuminanceXYZ, perez.sky_luminance_xyz);
366 gfx::set_uniform(cloud_program_.u_skyLuminance, perez.sky_luminance_rgb);
367 gfx::set_uniform(cloud_program_.u_sunLuminance, perez.sun_luminance_rgb);
368 gfx::set_uniform(cloud_program_.u_sunDirection, perez.sun_direction);
369 gfx::set_uniform(cloud_program_.u_parameters, exposition);
370 gfx::set_uniform(cloud_program_.u_perezCoeff, &perez.perez_coeff[0][0], 5);
371 gfx::set_uniform(cloud_program_.u_cloudParams, cloud_params);
372 gfx::set_uniform(cloud_program_.u_cloudParams2, cloud_params2);
373 gfx::set_uniform(cloud_program_.u_cloudParams3, cloud_params3);
374 gfx::set_uniform(cloud_program_.u_cloudParams4, cloud_params4);
375
376 float cloud_frame[4] = {float(gfx::get_render_frame()), float(cloud_frame_count), cloud_time_delta, 0.0f};
377 gfx::set_uniform(cloud_program_.u_cloudFrame, cloud_frame);
378
380 gfx::set_uniform(cloud_program_.u_prevViewProj, prev_vp.get_matrix());
381
382 if(cloud_noise.base_noise)
383 {
384 gfx::set_texture(cloud_program_.s_cloudNoise, 0, cloud_noise.base_noise.get());
385 }
386 gfx::set_texture(cloud_program_.s_cloudHistory, 1, history_tex.get());
387
388 irect32_t cloud_rect(0, 0, half_w, half_h);
389 gfx::set_scissor(cloud_rect.left, cloud_rect.top, cloud_rect.width(), cloud_rect.height());
390
391 gfx::set_state(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
392 gfx::set_index_buffer(ib_->native_handle());
393 gfx::set_vertex_buffer(0, vb_->native_handle());
394 gfx::submit(cloud_pass.id, cloud_program_.program->native_handle());
395
396 gfx::set_state(BGFX_STATE_DEFAULT);
397 cloud_program_.program->end();
398
399 cloud_frame_count++;
400 }
401
402 // === Pass 2: Sky pass (full resolution, composites half-res clouds) ===
403 gfx::render_pass pass("Atmospherics/Sky Pass");
404 pass.bind(surface);
405 pass.set_view_proj(view, proj);
406
407 if(atmospheric_program_.program->is_valid())
408 {
409 atmospheric_program_.program->begin();
410
411 gfx::set_uniform(atmospheric_program_.u_sunLuminance, perez.sun_luminance_rgb);
412 gfx::set_uniform(atmospheric_program_.u_skyLuminanceXYZ, perez.sky_luminance_xyz);
413 gfx::set_uniform(atmospheric_program_.u_skyLuminance, perez.sky_luminance_rgb);
414 gfx::set_uniform(atmospheric_program_.u_sunDirection, perez.sun_direction);
415 gfx::set_uniform(atmospheric_program_.u_parameters, exposition);
416 gfx::set_uniform(atmospheric_program_.u_perezCoeff, &perez.perez_coeff[0][0], 5);
417 gfx::set_uniform(atmospheric_program_.u_cloudParams, cloud_params);
418 gfx::set_uniform(atmospheric_program_.u_cloudParams2, cloud_params2);
419
420 auto cloud_frame_count = rview.data_get("CLOUD_FRAME_COUNT");
421 uint32_t prev = (cloud_frame_count - 1) & 1;
422 const auto& cloud_tex = rview.tex_safe_get(prev == 0 ? "CLOUD_PING" : "CLOUD_PONG");
423 if(cloud_tex)
424 {
425 gfx::set_texture(atmospheric_program_.s_cloudTex, 0, cloud_tex);
426 }
427
428 if(cloud_noise.flat_noise)
429 {
430 gfx::set_texture(atmospheric_program_.s_cloudNoise2D, 1, cloud_noise.flat_noise.get());
431 }
432
433 irect32_t rect(0, 0, irect32_t::value_type(output_size.width), irect32_t::value_type(output_size.height));
435
436 gfx::set_state(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_DEPTH_TEST_EQUAL);
437 gfx::set_index_buffer(ib_->native_handle());
438 gfx::set_vertex_buffer(0, vb_->native_handle());
439 gfx::submit(pass.id, atmospheric_program_.program->native_handle());
440
441 gfx::set_state(BGFX_STATE_DEFAULT);
442 atmospheric_program_.program->end();
443 }
444
445 gfx::discard();
446}
447
448void compute_perez_luminance(const math::vec3& light_direction,
449 math::vec3& out_sky_luminance_rgb,
450 math::vec3& out_sun_luminance_rgb)
451{
452 auto hour = ANONYMOUS::hour_of_day(-light_direction);
453 ANONYMOUS::dynamic_value_controller sun_luminance_dc(ANONYMOUS::sunLuminanceXYZTable);
454 ANONYMOUS::dynamic_value_controller sky_luminance_dc(ANONYMOUS::skyLuminanceXYZTable);
455 auto sunLuminanceXYZ = sun_luminance_dc.get_value(hour);
456 auto sunLuminanceRGB = ANONYMOUS::xyzToRgb(sunLuminanceXYZ);
457 out_sun_luminance_rgb = math::vec3(sunLuminanceRGB.x, sunLuminanceRGB.y, sunLuminanceRGB.z);
458 auto skyLuminanceXYZ = sky_luminance_dc.get_value(hour);
459 auto skyLuminanceRGB = ANONYMOUS::xyzToRgb(skyLuminanceXYZ);
460 out_sky_luminance_rgb = math::vec3(skyLuminanceRGB.x, skyLuminanceRGB.y, skyLuminanceRGB.z);
461}
462
463void compute_irradiance_perez_params(const math::vec3& light_direction,
464 float turbidity,
466{
467 math::vec3 sun_dir(-light_direction.x, -light_direction.y, -light_direction.z);
468 sun_dir = math::normalize(sun_dir);
469
470 auto hour = ANONYMOUS::hour_of_day(-light_direction);
471 ANONYMOUS::dynamic_value_controller sun_luminance_dc(ANONYMOUS::sunLuminanceXYZTable);
472 ANONYMOUS::dynamic_value_controller sky_luminance_dc(ANONYMOUS::skyLuminanceXYZTable);
473 auto sunLuminanceXYZ = sun_luminance_dc.get_value(hour);
474 auto sunLuminanceRGB = ANONYMOUS::xyzToRgb(sunLuminanceXYZ);
475 out.sun_luminance_rgb = math::vec3(sunLuminanceRGB.x, sunLuminanceRGB.y, sunLuminanceRGB.z);
476
477 auto skyLuminanceXYZ = sky_luminance_dc.get_value(hour);
478 out.sky_luminance_xyz =
479 math::vec3(skyLuminanceXYZ.x, skyLuminanceXYZ.y, skyLuminanceXYZ.z);
480 auto skyLuminanceRGB = ANONYMOUS::xyzToRgb(skyLuminanceXYZ);
481 out.sky_luminance_rgb = math::vec3(skyLuminanceRGB.x, skyLuminanceRGB.y, skyLuminanceRGB.z);
482
483 out.sun_direction = sun_dir;
484
485 float sun_altitude = sun_dir.y;
486 // At zenith use 1.0, at horizon use 0.6 (was 0.35) for more vibrant sunsets
487 float altitude_factor = bx::lerp(0.6f, 1.0f, bx::clamp(bx::abs(sun_altitude), 0.0f, 1.0f));
488 out.exposition = 0.1f * altitude_factor;
489
490 ANONYMOUS::compute_perez_coeff(turbidity, &out.perez_coeff[0][0]);
491}
492
493} // namespace unravel
auto data_get(const hpp::string_view &id, uint32_t default_val=0) const -> uint32_t
auto fbo_get_or_emplace(const hpp::string_view &id) -> frame_buffer::ptr &
auto tex_safe_get(const hpp::string_view &id) const -> const texture::ptr &
auto tex_get_or_emplace(const hpp::string_view &id) -> texture::ptr &
auto data_get_or_emplace(const hpp::string_view &id, uint32_t default_val=0) -> uint32_t &
Manages assets, including loading, unloading, and storage.
auto get_asset(const std::string &key, load_flags flags=load_flags::standard, load_mode mode=load_mode::immediate) -> asset_handle< T >
Gets an asset by its key.
auto init(rtti::context &ctx) -> bool
void run(gfx::frame_buffer::ptr input, const camera &camera, gfx::render_view &rview, delta_t dt, const run_params &params)
Class representing a camera. Contains functionality for manipulating and updating a camera....
Definition camera.h:62
auto get_projection() const -> const math::transform &
Retrieves the current projection matrix.
Definition camera.cpp:205
auto get_prev_view_projection_relative() const -> math::transform
Definition camera.cpp:328
auto get_view_relative() const -> const math::transform &
Definition camera.cpp:288
static auto get() -> default_textures &
std::chrono::duration< float > delta_t
math::vec3 normal
Definition defaults.cpp:53
uint16_t view
void submit(view_id _id, program_handle _handle, int32_t _depth, bool _preserveState)
uint16_t set_scissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
Definition graphics.cpp:952
void set_state(uint64_t _state, uint32_t _rgba)
Definition graphics.cpp:937
auto needs_recreate(const gfx::frame_buffer::ptr &fbo, const usize32_t &size) -> bool
void set_vertex_buffer(uint8_t _stream, vertex_buffer_handle _handle)
void discard(uint8_t _flags)
const memory_view * copy(const void *_data, uint32_t _size)
Definition graphics.cpp:460
void set_uniform(uniform_handle _handle, const void *_value, uint16_t _num)
Definition graphics.cpp:977
void set_index_buffer(index_buffer_handle _handle)
Definition graphics.cpp:992
uint32_t get_render_frame()
void set_texture(uint8_t _stage, uniform_handle _sampler, texture_handle _handle, uint32_t _flags)
void compute_perez_luminance(const math::vec3 &light_direction, math::vec3 &out_sky_luminance_rgb, math::vec3 &out_sun_luminance_rgb)
Computes Perez sky and sun luminance from light direction (time-of-day). Uses the same tables as the ...
void compute_irradiance_perez_params(const math::vec3 &light_direction, float turbidity, irradiance_perez_params &out)
std::vector< uint32_t > indices
void set_view_proj(const float *v, const float *p)
gfx::view_id id
void clear(uint16_t _flags, uint32_t _rgba=0x000000ff, float _depth=1.0f, uint8_t _stencil=0) const
void bind(const frame_buffer *fb=nullptr) const
static auto get_layout() -> const vertex_layout &
Definition vertex_decl.h:15
T width() const
std::int32_t value_type
T height() const
float cloud_vol_uv_scale
Volumetric cloud u_cloudParams3: uv scale, edge width, shape power, detail erode.
float cloud_density
Cloud density/opacity multiplier.
float cloud_absorption
Beer-Lambert extinction coefficient [0.01-0.5].
float cloud_light_absorption
Light absorption / self-shadow strength [0.01-0.5].
float cloud_vol_macro_strength
Volumetric cloud u_cloudParams4: macro strength, coarse scale, base mix, sun intensity.
float cloud_top_altitude
Cloud top altitude in world units. Vol: slab top. Flat: ignored.
float cloud_coverage
Cloud coverage [0.0 = clear sky, 1.0 = overcast]. Controls the density threshold.
int cloud_mode
Cloud mode: 0=none, 1=flat, 2=volumetric.
float cloud_time
Accumulated elapsed time (seconds) for cloud animation.
float sky_brightness
Sky brightness multiplier (1.0 = neutral). Affects visible sky and irradiance.
float cloud_base_altitude
Cloud base altitude in world units. Vol: slab bottom. Flat: projection height.
Full Perez params for irradiance SH compute shader (mode 1).