SuperTuxKart 1.5 upstream source (from official release tarball)

This commit is contained in:
Benjamin
2026-06-11 20:04:02 +02:00
commit 2957e51aaa
8551 changed files with 1801800 additions and 0 deletions
@@ -0,0 +1,189 @@
vec3 PBRLight(
vec3 normal,
vec3 eyedir,
vec3 lightdir,
vec3 color,
float perceptual_roughness,
float metallic)
{
float NdotV = max(dot(normal, eyedir), 0.0001);
float NdotL = clamp(dot(normal, lightdir), 0.0, 1.0);
vec2 F_ab = F_AB(perceptual_roughness, NdotV);
vec3 H = normalize(eyedir + lightdir);
float NdotH = clamp(dot(normal, H), 0.0, 1.0);
float LdotH = clamp(dot(lightdir, H), 0.0, 1.0);
vec3 diffuse_color = color * (1.0 - metallic);
vec3 F0 = mix(vec3(0.04), color, metallic);
// No real world material has specular values under 0.02, so we use this range as a
// "pre-baked specular occlusion" that extinguishes the fresnel term, for artistic control.
// See: https://google.github.io/filament/Filament.html#specularocclusion
float F90 = clamp(dot(F0, vec3(50.0 * 0.33)), 0.0, 1.0);
float roughness = perceptualRoughnessToRoughness(perceptual_roughness);
vec3 diffuse = diffuse_color * Fd_Burley(roughness, NdotV, NdotL, NdotH);
float D = D_GGX(roughness, NdotH);
float V = V_Smith_GGX_Correlated(roughness, NdotV, NdotL);
vec3 F = fresnel(F0, F90, LdotH);
vec3 specular = D * V * F * (1.0 + F0 * (1.0 / F_ab.x - 1.0));
return NdotL * (diffuse + specular);
}
vec3 PBRSunAmbientEmitLight(
vec3 normal,
vec3 eyedir,
vec3 sundir,
vec3 color,
vec3 irradiance,
vec3 radiance,
vec3 sun_color,
vec3 ambient_color,
float perceptual_roughness,
float metallic,
float emissive)
{
// Copied from PBRLight to use F_ab and F90 again
float NdotV = max(dot(normal, eyedir), 0.0001);
float NdotL = clamp(dot(normal, sundir), 0.0, 1.0);
vec2 F_ab = F_AB(perceptual_roughness, NdotV);
vec3 H = normalize(eyedir + sundir);
float NdotH = clamp(dot(normal, H), 0.0, 1.0);
float LdotH = clamp(dot(sundir, H), 0.0, 1.0);
vec3 diffuse_color = color * (1.0 - metallic);
vec3 F0 = mix(vec3(0.04), color, metallic);
// No real world material has specular values under 0.02, so we use this range as a
// "pre-baked specular occlusion" that extinguishes the fresnel term, for artistic control.
// See: https://google.github.io/filament/Filament.html#specularocclusion
float F90 = clamp(dot(F0, vec3(50.0 * 0.33)), 0.0, 1.0);
float roughness = perceptualRoughnessToRoughness(perceptual_roughness);
vec3 diffuse = diffuse_color * Fd_Burley(roughness, NdotV, NdotL, NdotH);
float D = D_GGX(roughness, NdotH);
float V = V_Smith_GGX_Correlated(roughness, NdotV, NdotL);
vec3 F = fresnel(F0, F90, LdotH);
vec3 specular = D * V * F * (1.0 + F0 * (1.0 / F_ab.x - 1.0));
vec3 sunlight = NdotL * (diffuse + specular);
vec3 diffuse_ambient = envBRDFApprox(diffuse_color, F_AB(1.0, NdotV));
vec3 specular_ambient = F90 * envBRDFApprox(F0, F_ab);
// Other 0.6 comes from skybox
ambient_color *= 0.4;
vec3 environment;
if (u_ibl)
{
environment = environmentLight(irradiance, radiance, roughness,
diffuse_color, F_ab, F0, F90, NdotV);
}
else
{
environment = u_global_light.m_skytop_color * ambient_color *
diffuse_color;
}
vec3 emit = emissive * color * 4.0;
return sun_color * sunlight
+ environment + emit
+ (diffuse_ambient + specular_ambient) * ambient_color;
}
vec3 accumulateLights(int light_count, vec3 diffuse_color, vec3 normal,
vec3 xpos, vec3 eyedir, float perceptual_roughness,
float metallic)
{
vec3 accumulated_color = vec3(0.0);
for (int i = 0; i < light_count; i++)
{
vec3 light_to_frag = (u_camera.m_view_matrix *
vec4(u_global_light.m_lights[i].m_position_radius.xyz,
1.0)).xyz - xpos;
float invrange = u_global_light.m_lights[i].m_color_inverse_square_range.w;
float distance_sq = dot(light_to_frag, light_to_frag);
if (distance_sq * invrange > 1.)
continue;
// SpotLight
float sattenuation = 1.;
float sscale = u_global_light.m_lights[i].m_direction_scale_offset.z;
float distance = sqrt(distance_sq);
float distance_inverse = 1. / distance;
vec3 L = light_to_frag * distance_inverse;
if (sscale != 0.)
{
vec3 sdir =
vec3(u_global_light.m_lights[i].m_direction_scale_offset.xy, 0.);
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
sdir = (u_camera.m_view_matrix * vec4(sdir, 0.0)).xyz;
sattenuation = clamp(dot(-sdir, L) *
abs(sscale) +
u_global_light.m_lights[i].m_direction_scale_offset.w, 0.0, 1.0);
#ifndef TILED_GPU
// Reduce branching in tiled GPU
if (sattenuation == 0.)
continue;
#endif
}
vec3 diffuse_specular = PBRLight(normal, eyedir, L, diffuse_color,
perceptual_roughness, metallic);
float attenuation = 20. / (1. + distance_sq);
float radius = u_global_light.m_lights[i].m_position_radius.w;
attenuation *= (radius - distance) / radius;
attenuation *= sattenuation * sattenuation;
vec3 light_color =
u_global_light.m_lights[i].m_color_inverse_square_range.xyz;
accumulated_color += light_color * attenuation * diffuse_specular;
}
return accumulated_color;
}
// Copied because reusing in a loop will be slower
vec3 calculateLight(int i, vec3 diffuse_color, vec3 normal, vec3 xpos,
vec3 eyedir, float perceptual_roughness, float metallic)
{
vec3 light_to_frag = (u_camera.m_view_matrix *
vec4(u_global_light.m_lights[i].m_position_radius.xyz,
1.0)).xyz - xpos;
float invrange = u_global_light.m_lights[i].m_color_inverse_square_range.w;
float distance_sq = dot(light_to_frag, light_to_frag);
if (distance_sq * invrange > 1.)
return vec3(0.0);
// SpotLight
float sattenuation = 1.;
float sscale = u_global_light.m_lights[i].m_direction_scale_offset.z;
float distance = sqrt(distance_sq);
float distance_inverse = 1. / distance;
vec3 L = light_to_frag * distance_inverse;
if (sscale != 0.)
{
vec3 sdir =
vec3(u_global_light.m_lights[i].m_direction_scale_offset.xy, 0.);
sdir.z = sqrt(1. - dot(sdir, sdir)) * sign(sscale);
sdir = (u_camera.m_view_matrix * vec4(sdir, 0.0)).xyz;
sattenuation = clamp(dot(-sdir, L) *
abs(sscale) +
u_global_light.m_lights[i].m_direction_scale_offset.w, 0.0, 1.0);
if (sattenuation == 0.)
return vec3(0.0);
}
vec3 diffuse_specular = PBRLight(normal, eyedir, L, diffuse_color,
perceptual_roughness, metallic);
float attenuation = 20. / (1. + distance_sq);
float radius = u_global_light.m_lights[i].m_position_radius.w;
attenuation *= (radius - distance) / radius;
attenuation *= sattenuation * sattenuation;
vec3 light_color =
u_global_light.m_lights[i].m_color_inverse_square_range.xyz;
return light_color * attenuation * diffuse_specular;
}