feat(7): Task 7

This commit is contained in:
Tibo De Peuter 2024-12-13 21:35:27 +01:00
parent fa72983f52
commit 4ee02fd3b9
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2

View file

@ -22,6 +22,160 @@ out vec3 color;
// perlin_noise, tangent
void main()
{
color = vec3(0,0,1);
}
const float sun_orbit = 10.0;
const float sun_height = 8.0;
const float sun_frequency = 8.0;
const float epsilon = 0.0001;
const float cloud_scale = 0.9;
const float cloud_intensity = 32.5;
const float cloud_speed = 0.5;
const float light_intensity = 5.0;
const float twinkle_speed = 0.2;
/* * * * * *
* Sun *
* * * * * */
float sun_x = sun_orbit * cos(2.0 * M_PI * animation_seconds / sun_frequency);
float sun_z = sun_orbit * sin(2.0 * M_PI * animation_seconds / sun_frequency);
vec3 sun_pos = (view * vec4(vec3(sun_x, sun_height, sun_z), 1.0)).xyz;
vec3 light_dir = normalize(sun_pos - view_pos_fs_in.xyz);
vec3 view_dir = normalize(-view_pos_fs_in.xyz);
vec3 normal_dir = normalize(normal_fs_in);
/* * * * * * *
* Bumps *
* * * * * * */
vec3 T, B;
tangent(normalize(sphere_fs_in), T, B);
vec3 normal = cross(
(bump_position(is_moon, sphere_fs_in + epsilon * T) - bump_position(is_moon, sphere_fs_in)) / epsilon,
(bump_position(is_moon, sphere_fs_in + epsilon * B) - bump_position(is_moon, sphere_fs_in)) / epsilon
);
normal = (view * model(is_moon, animation_seconds) * vec4(normal, 0.0)).xyz;
normal = normalize(normal);
/* * * * * * *
* Color *
* * * * * * */
float sun_specular_exponent = 1000.0;
vec3 ka = vec3(0.1, 0.1, 0.1);
vec3 kd;
vec3 ks = vec3(1.0, 1.0, 1.0);
float bump = bump_height(is_moon, normalize(sphere_fs_in));
if (!is_moon) {
if (bump < 0.0) { /* Water */
kd = vec3(0.2, 0.35, 0.8);
sun_specular_exponent = 4000.0;
float terrain_color = clamp(1 + 15 * bump, 0, 1); /* Still show the depth in the color */
kd *= terrain_color;
// Create very small waves, by multiplying the normal with a perlin value
float wave = perlin_noise(sphere_fs_in * 30 + animation_seconds);
wave = pow(wave, 0.1);
wave = 0.1 * smoothstep(0.1, 0.9, wave);
wave = clamp(wave, 0.0, 1.0);
normal = normal_dir + normal*wave;
normal = normalize(normal);
} else { /* Land */
ks = vec3(0.0, 0.0, 0.0);
kd = vec3(0.2, 0.8, 0.3);
vec3 beach = vec3(0.9, 0.8, 0.5);
vec3 lush = vec3(0.2, 0.8, 0.3);
vec3 barren = vec3(0.5, 0.5, 0.5);
if (bump < 0.05) {
kd = mix(beach, lush, smoothstep(0.0, 0.05, bump));
} else {
kd = mix(lush, barren, smoothstep(0.05, 1.0, bump));
}
float terrain_color = clamp(1 + 15 * bump, 0, 1);
kd *= terrain_color;
}
// Generate clouds, by creating cloud clusters and then filling those clusters with clouds.
vec3 cloud_rotation = vec3(animation_seconds * cloud_speed, 0.0, animation_seconds * cloud_speed);
float base_cloud = perlin_noise(sphere_fs_in.xyz * 1.3 + cloud_rotation / 5.0);
base_cloud = pow(base_cloud, 1.1);
base_cloud = 100.0 * smoothstep(0.1, 0.9, base_cloud);
base_cloud = clamp(base_cloud, 0.0, 1.0);
float top_cloud = perlin_noise(sphere_fs_in.xyz * 3.5 + cloud_rotation);
top_cloud = pow(top_cloud, 1.125);
top_cloud = 3.8 * smoothstep(0.1, 0.9, top_cloud);
top_cloud = clamp(top_cloud, 0.0, 1.0);
/* Combine the base and top cloud */
float cloud = top_cloud * base_cloud;
kd = mix(kd, vec3(1.0, 1.0, 1.0), cloud);
kd = clamp(kd, 0.0, 1.0);
// Modify the normals to make the clouds look fluffy
normal = mix(normal, normal_dir, cloud);
color = blinn_phong(ka, kd, ks, sun_specular_exponent, normal, view_dir, light_dir);
/* Twinking lights */
float light_factor = dot(normal, light_dir);
if (light_factor < -0.2 && 0.0 < bump) { // Only show the twinkle when the light is coming from the front
vec3 twinkle_vector = vec3(animation_seconds * twinkle_speed, 0.0, animation_seconds * twinkle_speed);
float twinkle_pos = perlin_noise(sphere_fs_in * 100 + twinkle_vector);
twinkle_pos = pow(twinkle_pos, 1.35);
float twinkle_intensity = perlin_noise(sphere_fs_in * 0.5 * twinkle_vector);
twinkle_pos = twinkle_intensity * 100.0 * smoothstep(0.3, 1.0, twinkle_pos);
twinkle_pos = clamp(twinkle_pos, 0.0, 1.0);
// RGB LIGHTS! (Groetjes aan Julie)
float r_mix = perlin_noise(sphere_fs_in * twinkle_vector * animation_seconds + 1.0);
r_mix = 1000 * smoothstep(0.01, 0.95, r_mix);
r_mix = clamp(r_mix, 0.0, 1.0);
float g_mix = perlin_noise(sphere_fs_in * twinkle_vector * animation_seconds + 2.0);
g_mix = 1000 * smoothstep(0.01, 0.95, g_mix);
g_mix = clamp(g_mix, 0.0, 1.0);
float b_mix = perlin_noise(sphere_fs_in * twinkle_vector * animation_seconds + 3.0);
b_mix = 1000 * smoothstep(0.01, 0.95, b_mix);
b_mix = clamp(b_mix, 0.0, 1.0);
vec3 twinkle_color = vec3(r_mix, g_mix, b_mix);
vec3 final_twinkle_color = mix(vec3(1.0, 1.0, 1.0), twinkle_color, r_mix);
color = mix(color, final_twinkle_color, twinkle_pos);
color = clamp(color, 0.0, 1.0);
}
} else {
kd = vec3(0.2, 0.2, 0.2);
sun_specular_exponent = 500.0;
ks = vec3(0.1, 0.1, 0.1);
float charcoal = perlin_noise(sphere_fs_in.xyz * 2.3);
charcoal = pow(charcoal, 0.3);
charcoal = 1.1 * smoothstep(0.1, 0.9, charcoal);
charcoal = clamp(charcoal, 0.0, 1.0);
kd = mix(kd, vec3(1.0, 0.0, 0.0), 1.0 - charcoal);
// Smoothen the bumped normal
normal = mix(normal, normal_dir, 1 - charcoal);
color = blinn_phong(ka, kd, ks, sun_specular_exponent, normal, view_dir, light_dir);
/* Add charcoal glow */
color = mix(color, kd, 1.0 - charcoal);
float glow_intensity = perlin_noise(vec3(0.25 * animation_seconds));
glow_intensity = pow(glow_intensity, 0.3);
glow_intensity = 1.1 * smoothstep(0.1, 0.9, glow_intensity);
glow_intensity = clamp(glow_intensity, 0.2, 1.0);
color *= glow_intensity;
}
}