mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-30 13:10:29 +01:00
Place the sun and the moon where they are and light the night by the phase of the moon
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
// the sun, the moon and the textured sprite of the easter egg, drawn over the sky on a quad around the direction of the body
|
||||
// (celestial.vert). param[0]: colour (rgb) and alpha, param[1]: position in view space and half the size of the quad,
|
||||
// param[2].xy: corner (sprite) or centre (moon) of the picture in the texture, param[2].z: its size (sprite) or the radius of
|
||||
// the disc in it (moon), in texture units, param[2].w: kind of body, 0: textured sprite, 1: sun, 2: moon.
|
||||
// the colour goes out premultiplied, the alpha is how much of the sky behind the body it hides (blending ONE, ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
in vec2 f_coord;
|
||||
in vec2 f_local;
|
||||
|
||||
#texture (tex1, 0, sRGB_A)
|
||||
uniform sampler2D tex1;
|
||||
@@ -6,6 +13,14 @@ uniform sampler2D tex1;
|
||||
#include <common>
|
||||
#include <tonemapping.glsl>
|
||||
|
||||
// shape and light of the sun and the moon, set by opengl46_renderer::Render(world_environment *):
|
||||
// [0].xy: direction to the zenith on the quad, [0].z: height over width of the disc (flattened by the refraction near the
|
||||
// horizon), [0].w: radius of the disc in units of half the quad
|
||||
// [1].xyz: direction to the sun in view space, [1].w: light of the earth on the dark part of the moon, against the light of
|
||||
// the sun on the lit part
|
||||
// [2].rgb: limb darkening of the sun per channel (linear law)
|
||||
layout(location = 0) uniform vec4 body[3];
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
#if MOTIONBLUR_ENABLED
|
||||
layout(location = 1) out vec4 out_motion;
|
||||
@@ -13,11 +28,54 @@ layout(location = 1) out vec4 out_motion;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tex_color = texture(tex1, f_coord);
|
||||
int kind = int(param[2].w + 0.5);
|
||||
vec4 color = vec4(0.0);
|
||||
if (kind == 0)
|
||||
{
|
||||
vec4 tex_color = texture(tex1, f_coord) * param[0];
|
||||
color = vec4(tex_color.rgb * tex_color.a, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the point on the disc in its radii, x along the horizon, y to the zenith, with the flattening undone
|
||||
vec2 zenith = body[0].xy;
|
||||
vec2 across = vec2(zenith.y, -zenith.x);
|
||||
vec2 p = vec2(dot(f_local, across), dot(f_local, zenith)) / body[0].w;
|
||||
p.y /= body[0].z;
|
||||
float r = length(p);
|
||||
float coverage = clamp((1.0 - r) / max(fwidth(r), 1e-4) + 0.5, 0.0, 1.0);
|
||||
// the horizon hides what is under it
|
||||
vec3 direction = normalize(param[1].xyz + vec3(f_local * param[1].w, 0.0));
|
||||
float height = (mat3(inv_view) * direction).y;
|
||||
coverage *= clamp(height / max(fwidth(height), 1e-7) + 0.5, 0.0, 1.0);
|
||||
// cosine of the angle between the line of sight and the surface of the sphere
|
||||
float mu = sqrt(max(1.0 - r * r, 0.0));
|
||||
if (kind == 1)
|
||||
{
|
||||
// limb darkening, kept to the average brightness of the disc
|
||||
vec3 limb = (vec3(1.0) - body[2].rgb * (1.0 - mu)) / (vec3(1.0) - body[2].rgb / 3.0);
|
||||
color = vec4(param[0].rgb * limb * coverage, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the moon as a sphere lit from the direction of the sun. the frame of the disc in view space, z to the viewer
|
||||
vec3 z = -normalize(param[1].xyz);
|
||||
vec3 x = vec3(across, 0.0);
|
||||
x = normalize(x - z * dot(x, z));
|
||||
vec3 y = cross(z, x);
|
||||
vec2 q = p / max(r, 1.0);
|
||||
vec3 normal = q.x * x + q.y * y + mu * z;
|
||||
float mu0 = max(dot(normal, normalize(body[1].xyz)), 0.0);
|
||||
// Lommel-Seeliger law: an even disc at the full moon, as the real one, no darkening towards the limb
|
||||
float lit = 2.0 * mu0 / (mu0 + max(mu, 1e-3));
|
||||
vec3 albedo = texture(tex1, param[2].xy + p * param[2].z).rgb;
|
||||
color = vec4(albedo * param[0].rgb * ((lit + body[1].w) * coverage), coverage * param[0].a);
|
||||
}
|
||||
}
|
||||
#if POSTFX_ENABLED
|
||||
out_color = tex_color * param[0];
|
||||
out_color = color;
|
||||
#else
|
||||
out_color = tonemap(tex_color * param[0]);
|
||||
out_color = vec4(tonemap(vec4(color.rgb, 1.0)).rgb, color.a);
|
||||
#endif
|
||||
#if MOTIONBLUR_ENABLED
|
||||
out_motion = vec4(0.0f);
|
||||
|
||||
@@ -7,6 +7,8 @@ const vec2 vert[4] = vec2[]
|
||||
);
|
||||
|
||||
out vec2 f_coord;
|
||||
// the corner of the quad, -1...1 across it
|
||||
out vec2 f_local;
|
||||
|
||||
#include <common>
|
||||
|
||||
@@ -14,6 +16,8 @@ void main()
|
||||
{
|
||||
gl_Position = projection * (vec4(param[1].xyz, 1.0) + vec4(vert[gl_VertexID] * param[1].w, 0.0, 0.0));
|
||||
|
||||
f_local = vert[gl_VertexID];
|
||||
|
||||
vec2 coord = param[2].xy;
|
||||
float size = param[2].z;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user