#version 450
// Rusting shader packs, version 1: the `sky_lut` program. It draws the
// procedural sky into a small equirectangular image every frame, with the
// pack's `#rusting sky_lut 1` file as its hook; the engine compiles it at
// run time only for packs that have one. Scene and sky programs then read
// the image as their environment map (`sky_lut_at`). Fields are only ever
// added at the end of SkyLutInput.
layout(location = 0) out vec4 out_color;
// The procedural sky settings, laid out as sky_param documents them.
layout(push_constant) uniform SkyLutParams {
vec4 sky[4];
} sky_lut_params;
#include "frame.glsl"
vec4 sky_param(int i) {
return sky_lut_params.sky[i];
}
#include "sky.glsl"
// What the engine knows about the LUT texel before the hook runs.
struct SkyLutInput {
// Unit world-space direction the texel stands for.
vec3 direction;
// Texel centre, 0..1: u around +Y starting at -X, v from +Y (0) down
// to -Y (1).
vec2 uv;
// Seconds since start, the same as `frame.time.x`.
float time;
};
#include "sky_lut_hook.glsl"
#ifndef RUSTING_CUSTOM_SKY_LUT
void sky_lut(SkyLutInput i, inout vec3 color) {}
#endif
void main() {
// Matches LUT_EXTENT in sky_lut.rs.
vec2 uv = gl_FragCoord.xy / vec2(256.0, 128.0);
// Inverse of the environment lookup: u = atan(z, x) / 2pi + 0.5,
// v = acos(y) / pi.
float around = (uv.x - 0.5) * 2.0 * 3.14159265;
float down = uv.y * 3.14159265;
vec3 direction = vec3(
sin(down) * cos(around), cos(down), sin(down) * sin(around));
vec3 color = sky_radiance(direction, sky_param(0).xyz, sky_param(1).rgb,
sky_param(1).w, sky_param(2).rgb);
sky_lut(SkyLutInput(direction, uv, frame.time.x), color);
out_color = vec4(max(color, vec3(0.0)), 1.0);
}