12#define ANONYMOUS anonymous
18typedef bx::Vec3
Color;
21class dynamic_value_controller
23 using value_type =
Color;
24 using key_map = std::map<float, value_type>;
27 dynamic_value_controller(
const key_map& keymap) : key_map_(keymap)
31 value_type get_value(
float time)
const
33 auto itUpper = key_map_.upper_bound(time + 1e-6f);
34 auto itLower = itUpper;
37 if(itLower == key_map_.end())
39 return itUpper->second;
42 if(itUpper == key_map_.end())
44 return itLower->second;
47 float lowerTime = itLower->first;
48 const auto& lowerVal = itLower->second;
49 float upperTime = itUpper->first;
50 const auto& upperVal = itUpper->second;
52 if(lowerTime == upperTime)
57 return interpolate(lowerTime, lowerVal, upperTime, upperVal, time);
61 value_type interpolate(
float lowerTime,
62 const value_type& lowerVal,
64 const value_type& upperVal,
67 const float tt = (time - lowerTime) / (upperTime - lowerTime);
68 const auto result = bx::lerp(lowerVal, upperVal, tt);
72 const key_map& key_map_;
76static constexpr float M_XYZ2RGB[] = {
91 Color rgb(bx::InitNone);
92 rgb.x = M_XYZ2RGB[0] * xyz.x + M_XYZ2RGB[3] * xyz.y + M_XYZ2RGB[6] * xyz.z;
93 rgb.y = M_XYZ2RGB[1] * xyz.x + M_XYZ2RGB[4] * xyz.y + M_XYZ2RGB[7] * xyz.z;
94 rgb.z = M_XYZ2RGB[2] * xyz.x + M_XYZ2RGB[5] * xyz.y + M_XYZ2RGB[8] * xyz.z;
102static std::map<float, Color> sunLuminanceXYZTable = {
103 {5.0f, {0.000000f, 0.000000f, 0.000000f}},
104 {7.0f, {12.703322f, 12.989393f, 9.100411f}},
105 {8.0f, {13.202644f, 13.597814f, 11.524929f}},
106 {9.0f, {13.192974f, 13.597458f, 12.264488f}},
107 {10.0f, {13.132943f, 13.535914f, 12.560032f}},
108 {11.0f, {13.088722f, 13.489535f, 12.692996f}},
109 {12.0f, {13.067827f, 13.467483f, 12.745179f}},
110 {13.0f, {13.069653f, 13.469413f, 12.740822f}},
111 {14.0f, {13.094319f, 13.495428f, 12.678066f}},
112 {15.0f, {13.142133f, 13.545483f, 12.526785f}},
113 {16.0f, {13.201734f, 13.606017f, 12.188001f}},
114 {17.0f, {13.182774f, 13.572725f, 11.311157f}},
115 {18.0f, {12.448635f, 12.672520f, 8.267771f}},
116 {20.0f, {0.000000f, 0.000000f, 0.000000f}},
124static std::map<float, Color> skyLuminanceXYZTable = {
125 {0.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
129 {4.0f, bx::mul({0.258f, 0.258f, 0.344f}, 0.05f)},
130 {5.0f, {0.258f, 0.258f, 0.344f}},
131 {7.0f, {0.962851f, 1.000000f, 1.747835f}},
132 {8.0f, {0.967787f, 1.000000f, 1.776762f}},
133 {9.0f, {0.970173f, 1.000000f, 1.788413f}},
134 {10.0f, {0.971431f, 1.000000f, 1.794102f}},
135 {11.0f, {0.972099f, 1.000000f, 1.797096f}},
136 {12.0f, {0.972385f, 1.000000f, 1.798389f}},
137 {13.0f, {0.972361f, 1.000000f, 1.798278f}},
138 {14.0f, {0.972020f, 1.000000f, 1.796740f}},
139 {15.0f, {0.971275f, 1.000000f, 1.793407f}},
140 {16.0f, {0.969885f, 1.000000f, 1.787078f}},
141 {17.0f, {0.967216f, 1.000000f, 1.773758f}},
142 {18.0f, {0.961668f, 1.000000f, 1.739891f}},
143 {20.0f, {0.264f, 0.264f, 0.352f}},
144 {21.0f, bx::mul({0.264f, 0.264f, 0.352f}, 0.05f)},
146 {23.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
147 {24.0f, bx::mul({0.308f, 0.308f, 0.411f}, 0.0f)},
153static constexpr Color ABCDE[] = {
154 {-0.2592f, -0.2608f, -1.4630f},
155 {0.0008f, 0.0092f, 0.4275f},
156 {0.2125f, 0.2102f, 5.3251f},
157 {-0.8989f, -1.6537f, -2.5771f},
158 {0.0452f, 0.0529f, 0.3703f},
161static constexpr Color ABCDE_t[] = {
162 {-0.0193f, -0.0167f, 0.1787f},
163 {-0.0665f, -0.0950f, -0.3554f},
164 {-0.0004f, -0.0079f, -0.0227f},
165 {-0.0641f, -0.0441f, 0.1206f},
166 {-0.0033f, -0.0109f, -0.0670f},
169void compute_perez_coeff(
float _turbidity,
float* _outPerezCoeff)
171 const bx::Vec3 turbidity = {_turbidity, _turbidity, _turbidity};
172 for(uint32_t ii = 0; ii < 5; ++ii)
174 const bx::Vec3 tmp = bx::mad(ABCDE_t[ii], turbidity, ABCDE[ii]);
175 float* out = _outPerezCoeff + 4 * ii;
181float hour_of_day(math::vec3 sun_dir)
184 math::vec3
normal(0.0, -1.0, 0.0);
188 auto ref = math::vec3(-1.0f, 0.0f, 0.0f);
190 float angle = math::orientedAngle(v1, v2, ref);
191 angle = math::mod(angle, 2 * math::pi<float>());
192 angle = math::degrees(angle);
195 float hour_of_day = angle / 15;
213 auto fs_sky = am.get_asset<
gfx::shader>(
"engine:/data/shaders/atmospherics/fs_sky.sc");
215 atmospheric_program_.program = std::make_unique<gpu_program>(vs_sky, fs_sky);
216 atmospheric_program_.cache_uniforms();
218 int vertical_count = 32;
219 int horizontal_count = 32;
220 std::vector<gfx::screen_pos_vertex> vertices(vertical_count * horizontal_count);
222 for(
int i = 0; i < vertical_count; i++)
224 for(
int j = 0; j < horizontal_count; j++)
227 v.x = float(j) / (horizontal_count - 1) * 2.0f - 1.0f;
228 v.y = float(i) / (vertical_count - 1) * 2.0f - 1.0f;
232 std::vector<uint16_t> indices((vertical_count - 1) * (horizontal_count - 1) * 6);
235 for(
int i = 0; i < vertical_count - 1; i++)
237 for(
int j = 0; j < horizontal_count - 1; j++)
239 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 0));
240 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 0));
241 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 1));
243 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 0));
244 indices[k++] = (uint16_t)(j + 1 + horizontal_count * (i + 1));
245 indices[k++] = (uint16_t)(j + 0 + horizontal_count * (i + 1));
249 vb_ = std::make_unique<gfx::vertex_buffer>(
252 ib_ = std::make_unique<gfx::index_buffer>(
gfx::copy(indices.data(),
sizeof(uint16_t) * k));
265 hour_ += time_scale_ * dt.count();
266 hour_ = bx::mod(hour_, 24.0f);
272 const auto surface =
input.get();
273 const auto output_size = surface->get_size();
278 if(atmospheric_program_.program->is_valid())
280 atmospheric_program_.program->begin();
286 ANONYMOUS::dynamic_value_controller sun_luminance_dc(ANONYMOUS::sunLuminanceXYZTable);
287 ANONYMOUS::dynamic_value_controller sky_luminance_dc(ANONYMOUS::skyLuminanceXYZTable);
289 auto sunLuminanceXYZ = sun_luminance_dc.get_value(hour_);
290 auto sunLuminanceRGB = ANONYMOUS::xyzToRgb(sunLuminanceXYZ);
291 math::vec3 sun_luminance_rgb(sunLuminanceRGB.x, sunLuminanceRGB.y, sunLuminanceRGB.z);
293 auto skyLuminanceXYZ = sky_luminance_dc.get_value(hour_);
294 math::vec3 sky_luminance_xyz(skyLuminanceXYZ.x, skyLuminanceXYZ.y, skyLuminanceXYZ.z);
295 auto skyLuminanceRGB = ANONYMOUS::xyzToRgb(skyLuminanceXYZ);
296 math::vec3 sky_luminance_rgb(skyLuminanceRGB.x, skyLuminanceRGB.y, skyLuminanceRGB.z);
298 float exposition[4] = {0.02f, 3.0f, 0.1f, hour_};
299 float perezCoeff[4 * 5];
300 ANONYMOUS::compute_perez_coeff(params.
turbidity, perezCoeff);
304 gfx::set_uniform(atmospheric_program_.u_skyLuminanceXYZ, sky_luminance_xyz);
314 gfx::set_state(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_DEPTH_TEST_EQUAL);
317 gfx::submit(pass.
id, atmospheric_program_.program->native_handle());
320 atmospheric_program_.program->end();
std::shared_ptr< frame_buffer > ptr
Manages assets, including loading, unloading, and storage.
auto get_asset(const std::string &key, load_flags flags=load_flags::standard) -> asset_handle< T >
Gets an asset by its key.
auto init(rtti::context &ctx) -> bool
~atmospheric_pass_perez()
void run(gfx::frame_buffer::ptr input, const camera &camera, gfx::render_view &rview, delta_t dt, const run_params ¶ms)
Class representing a camera. Contains functionality for manipulating and updating a camera....
auto get_projection() const -> const math::transform &
Retrieves the current projection matrix.
auto get_view_relative() const -> const math::transform &
std::chrono::duration< float > delta_t
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)
void set_state(uint64_t _state, uint32_t _rgba)
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)
void set_uniform(uniform_handle _handle, const void *_value, uint16_t _num)
void set_index_buffer(index_buffer_handle _handle)
void set_view_proj(const float *v, const float *p)
void bind(const frame_buffer *fb=nullptr) const
static auto get_layout() -> const vertex_layout &
math::vec3 light_direction