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
+12
View File
@@ -0,0 +1,12 @@
layout(std140, set = 1, binding = 0) uniform CameraBuffer
{
mat4 m_view_matrix;
mat4 m_projection_matrix;
mat4 m_inverse_view_matrix;
mat4 m_inverse_projection_matrix;
mat4 m_projection_view_matrix;
mat4 m_inverse_projection_view_matrix;
vec4 m_viewport;
vec2 m_screensize;
vec2 m_padding;
} u_camera;
@@ -0,0 +1,20 @@
layout (constant_id = 0) const bool u_ibl = true;
layout (constant_id = 1) const float u_specular_levels_minus_one = 0.0;
layout (constant_id = 2) const bool u_deferred = false;
layout (constant_id = 3) const bool u_has_skybox = true;
layout (constant_id = 4) const bool u_ssr = false;
layout (constant_id = 5) const uint u_hiz_iterations = 0;
vec3 convertColor(vec3 input_color)
{
if (u_ibl)
{
return (input_color * (6.5 * input_color + 0.45)) /
(input_color * (5.0 * input_color + 1.75) + 0.05);
}
else
{
return (input_color * (7.0 * input_color + 0.75)) /
(input_color * (5.0 * input_color + 1.75) + 0.05);
}
}
@@ -0,0 +1,47 @@
// Push constants to pass face index, dimensions, and sample count.
layout(push_constant) uniform PushConstants {
int size; // width and height for current mipmap level
int sampleCount; // number of samples for integration
int mipmapLevel; // current mipmap level
int mipmapCount; // total mipmap levels
} pc;
// Returns the radical inverse of "bits" with base 2.
float RadicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10;
}
// Generate a 2D Hammersley sequence value.
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i) / float(N), RadicalInverse_VdC(i));
}
// Converts face index and UV coordinates in [0,1] to a normalized direction vector.
vec3 FaceUVtoDir(int face, vec2 uv)
{
// Map UV from [0, 1] to [-1, 1]
uv = uv * 2.0 - 1.0;
vec3 dir;
if (face == 0) // +X
dir = vec3(1.0, -uv.y, -uv.x);
else if (face == 1) // -X
dir = vec3(-1.0, -uv.y, uv.x);
else if (face == 2) // +Y
dir = vec3(uv.x, 1.0, uv.y);
else if (face == 3) // -Y
dir = vec3(uv.x, -1.0, -uv.y);
else if (face == 4) // +Z
dir = vec3(uv.x, -uv.y, 1.0);
else if (face == 5) // -Z
dir = vec3(-uv.x, -uv.y, -1.0);
return normalize(dir);
}
const float PI = 3.14159265359;
@@ -0,0 +1,9 @@
vec4 getVertexColor(uint packed)
{
vec4 vertex_color;
vertex_color.a = float(packed >> 24) / 255.0;
vertex_color.r = float((packed >> 16) & 0xff) / 255.0;
vertex_color.g = float((packed >> 8) & 0xff) / 255.0;
vertex_color.b = float(packed & 0xff) / 255.0;
return vertex_color;
}
@@ -0,0 +1,21 @@
struct LightData
{
vec4 m_position_radius;
vec4 m_color_inverse_square_range;
vec4 m_direction_scale_offset; // Spotlight only
};
const int MAX_LIGHT = 32;
layout(std140, set = 1, binding = 3) uniform GlobalLightBuffer
{
vec3 m_ambient_color;
float m_sun_scatter;
vec3 m_sun_color;
float m_sun_angle_tan_half;
vec3 m_sun_direction;
float m_fog_density;
vec4 m_fog_color;
vec3 m_skytop_color;
int m_light_count;
LightData m_lights[MAX_LIGHT];
} u_global_light;
@@ -0,0 +1,60 @@
layout (set = 2, binding = 0) uniform samplerCube u_diffuse;
layout (set = 2, binding = 1) uniform samplerCube u_specular;
#include "camera.glsl"
#include "constants_utils.glsl"
#include "spm_data.glsl"
#include "pbr_utils.glsl"
#include "global_light_data.glsl"
#include "pbr_light.glsl"
#include "sun_direction.glsl"
vec3 handlePBRDeferred(vec3 diffuse_color, vec3 pbr, vec3 world_normal,
vec3 eyedir, vec3 normal, float perceptual_roughness)
{
float radiance_level = perceptual_roughness * u_specular_levels_minus_one;
vec3 reflection = reflect(-eyedir, normal);
vec3 irradiance = vec3(0.0);
vec3 radiance = vec3(0.0);
if (u_ibl)
{
vec3 world_reflection = (u_camera.m_inverse_view_matrix *
vec4(reflection, 0.0)).xyz;
irradiance = texture(u_diffuse, world_normal).rgb;
radiance = textureLod(u_specular, world_reflection, radiance_level).rgb;
}
vec3 lightdir = sunDirection(reflection,
u_global_light.m_sun_direction, u_global_light.m_sun_angle_tan_half,
u_camera.m_inverse_view_matrix);
vec3 mixed_color = PBRSunAmbientEmitLight(
normal, eyedir, lightdir, diffuse_color,
irradiance, radiance,
u_global_light.m_sun_color,
u_global_light.m_ambient_color,
perceptual_roughness, pbr.y, pbr.z);
return mixed_color;
}
vec3 handlePBR(vec3 diffuse_color, vec3 pbr, vec4 world_position,
vec3 world_normal)
{
vec3 xpos = (u_camera.m_view_matrix * world_position).xyz;
vec3 eyedir = -normalize(xpos);
vec3 normal = (u_camera.m_view_matrix * vec4(world_normal, 0.0)).xyz;
float perceptual_roughness = 1.0 - pbr.x;
vec3 mixed_color = handlePBRDeferred(diffuse_color, pbr, world_normal,
eyedir, normal, perceptual_roughness);
mixed_color += accumulateLights(u_global_light.m_light_count,
diffuse_color, normal, xpos, eyedir, perceptual_roughness, pbr.y);
//Disable for deferred shading
//float factor = (1.0 - exp(length(xpos) * -0.0001));
//mixed_color = mixed_color + vec3(0.5) * factor;
return convertColor(mixed_color);
}
@@ -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;
}
@@ -0,0 +1,91 @@
vec2 F_AB(float perceptual_roughness, float NdotV)
{
vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
vec4 r = perceptual_roughness * c0 + c1;
float a004 = min(r.x * r.x, pow(2.0, -9.28 * NdotV)) * r.x + r.y;
return vec2(-1.04, 1.04) * a004 + r.zw;
}
// Lambert model
float F_Schlick(float f0, float f90, float VdotH)
{
return mix(f0, f90, pow(1.0 - VdotH, 5.0));
}
float Fd_Burley(float roughness, float NdotV, float NdotL, float LdotH)
{
// Don't divide by Pi to avoid light being too dim.
float f90 = 0.5 + 2.0 * roughness * LdotH * LdotH;
float lightScatter = F_Schlick(1.0, f90, NdotL);
float viewScatter = F_Schlick(1.0, f90, NdotV);
return lightScatter * viewScatter;
}
// Calculate distribution.
// Based on https://google.github.io/filament/Filament.html#citation-walter07
// D_GGX(h,α) = α^2 / { π ((n⋅h)^2 (α21) + 1)^2 }
// Simple implementation, has precision problems when using fp16 instead of fp32
// see https://google.github.io/filament/Filament.html#listing_speculardfp16
float D_GGX(float roughness, float NdotH)
{
float oneMinusNdotHSquared = 1.0 - NdotH * NdotH;
float a = NdotH * roughness;
float k = roughness / (oneMinusNdotHSquared + a * a);
return k * k * (1.0 / 3.14159265359);
}
// Calculate visibility.
// Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces"
// see https://google.github.io/filament/Filament.html#listing_approximatedspecularv
float V_Smith_GGX_Correlated(float roughness, float NdotV, float NdotL)
{
return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, roughness);
}
// Fresnel function
// see https://google.github.io/filament/Filament.html#citation-schlick94
// F_Schlick(v,h,f_0,f_90) = f_0 + (f_90 f_0) (1 v⋅h)^5
vec3 fresnel(vec3 f0, float f90, float VdotH)
{
return f0 + (f90 - f0) * pow(1.0 - VdotH, 5.0);
}
vec3 envBRDFApprox(vec3 F0, vec2 F_ab)
{
return F0 * F_ab.x + F_ab.y;
}
float perceptualRoughnessToRoughness(float perceptual_roughness)
{
float roughness = clamp(perceptual_roughness, 0.089, 1.0);
return roughness * roughness;
}
vec3 environmentLight(
vec3 irradiance,
vec3 radiance,
float roughness,
vec3 diffuse_color,
vec2 F_ab,
vec3 F0,
float F90,
float NdotV)
{
// Multiscattering approximation: https://www.jcgt.org/published/0008/01/03/paper.pdf
// Useful reference: https://bruop.github.io/ibl
vec3 Fr = max(vec3(1.0 - roughness), F0) - F0;
vec3 kS = F0 + Fr * pow(1.0 - NdotV, 5.0);
float Ess = F_ab.x + F_ab.y;
vec3 FssEss = kS * Ess * F90;
float Ems = 1.0 - Ess;
vec3 Favg = F0 + (1.0 - F0) / 21.0;
vec3 Fms = FssEss * Favg / (1.0 - Ems * Favg);
vec3 FmsEms = Fms * Ems;
vec3 Edss = 1.0 - (FssEss + FmsEms);
vec3 kD = diffuse_color * Edss;
vec3 diffuse = (FmsEms + kD) * irradiance;
vec3 specular = FssEss * radiance;
return diffuse + specular;
}
@@ -0,0 +1,104 @@
#ifdef BIND_MESH_TEXTURES_AT_ONCE
layout(binding = 0) uniform sampler2D f_mesh_textures[SAMPLER_SIZE * TOTAL_MESH_TEXTURE_LAYER];
vec4 sampleMeshTexture0(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 0;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture1(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 1;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture2(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 2;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture3(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 3;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture4(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 4;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture5(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 5;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture6(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 6;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
vec4 sampleMeshTexture7(int material_id, vec2 uv)
{
int id = (TOTAL_MESH_TEXTURE_LAYER * material_id) + 7;
return texture(f_mesh_textures[GE_SAMPLE_TEX_INDEX(id)], uv);
}
#else
layout(binding = 0) uniform sampler2D f_mesh_texture_0;
layout(binding = 1) uniform sampler2D f_mesh_texture_1;
#ifdef PBR_ENABLED
layout(binding = 2) uniform sampler2D f_mesh_texture_2;
layout(binding = 3) uniform sampler2D f_mesh_texture_3;
layout(binding = 4) uniform sampler2D f_mesh_texture_4;
layout(binding = 5) uniform sampler2D f_mesh_texture_5;
layout(binding = 6) uniform sampler2D f_mesh_texture_6;
layout(binding = 7) uniform sampler2D f_mesh_texture_7;
#endif
vec4 sampleMeshTexture0(int material_id, vec2 uv)
{
return texture(f_mesh_texture_0, uv);
}
vec4 sampleMeshTexture1(int material_id, vec2 uv)
{
return texture(f_mesh_texture_1, uv);
}
#ifdef PBR_ENABLED
vec4 sampleMeshTexture2(int material_id, vec2 uv)
{
return texture(f_mesh_texture_2, uv);
}
vec4 sampleMeshTexture3(int material_id, vec2 uv)
{
return texture(f_mesh_texture_3, uv);
}
vec4 sampleMeshTexture4(int material_id, vec2 uv)
{
return texture(f_mesh_texture_4, uv);
}
vec4 sampleMeshTexture5(int material_id, vec2 uv)
{
return texture(f_mesh_texture_5, uv);
}
vec4 sampleMeshTexture6(int material_id, vec2 uv)
{
return texture(f_mesh_texture_6, uv);
}
vec4 sampleMeshTexture7(int material_id, vec2 uv)
{
return texture(f_mesh_texture_7, uv);
}
#endif
#endif
@@ -0,0 +1,31 @@
#ifdef BIND_MESH_TEXTURES_AT_ONCE
#extension GL_ARB_shader_draw_parameters : enable
#endif
struct ObjectData
{
vec3 m_translation;
float m_hue_change;
vec4 m_rotation;
vec3 m_scale;
uint m_custom_vertex_color;
int m_skinning_offset;
int m_material_id;
vec2 m_texture_trans;
};
layout(std140, set = 1, binding = 1) readonly buffer ObjectBuffer
{
ObjectData m_objects[];
} u_object_buffer;
layout(std140, set = 1, binding = 2) readonly buffer SkinningMatrices
{
mat4 m_mat[];
} u_skinning_matrices;
#ifdef BIND_MESH_TEXTURES_AT_ONCE
layout(std430, set = 1, binding = 4) readonly buffer MaterialIDs
{
int m_material_id[];
} u_material_ids;
#endif
@@ -0,0 +1,18 @@
layout(location = 0) in vec3 v_position;
layout(location = 1) in vec4 v_normal;
layout(location = 2) in vec4 v_color;
layout(location = 3) in vec2 v_uv;
layout(location = 4) in vec2 v_uv_two;
layout(location = 5) in vec4 v_tangent;
layout(location = 6) in ivec4 v_joint;
layout(location = 7) in vec4 v_weight;
layout(location = 0) out vec4 f_vertex_color;
layout(location = 1) out vec2 f_uv;
layout(location = 2) out vec2 f_uv_two;
layout(location = 3) flat out int f_material_id;
layout(location = 4) out float f_hue_change;
layout(location = 5) out vec3 f_normal;
layout(location = 6) out vec3 f_tangent;
layout(location = 7) out vec3 f_bitangent;
layout(location = 8) out vec4 f_world_position;
@@ -0,0 +1,14 @@
// Sun Most Representative Point (used for MRP area lighting method)
// From "Frostbite going PBR" paper
vec3 sunDirection(vec3 R, vec3 sun_direction, float sun_angle_tan_half, mat4 inverse_view_matrix)
{
sun_direction = normalize((transpose(inverse_view_matrix) * vec4(sun_direction, 0.)).xyz);
float DdotR = dot(sun_direction, R);
vec3 S = normalize(R - DdotR * sun_direction);
float sun_angle_tan_half2 = 1 + sun_angle_tan_half * sun_angle_tan_half;
vec2 sun_angle_sin_cos = vec2(2 * sun_angle_tan_half, 2 - sun_angle_tan_half2) / sun_angle_tan_half2;
// Equivalent to DdotR < cos(sun_angle)
float factor = step(DdotR, sun_angle_sin_cos.y);
return mix(R, normalize(sun_direction * sun_angle_sin_cos.y + S * sun_angle_sin_cos.x), factor);
}
@@ -0,0 +1,17 @@
vec3 getPosFromFragCoord(vec4 frag_coord, vec4 viewport, mat4 inverse_projection_matrix)
{
vec2 ndc = vec2((frag_coord.x - viewport.x) / viewport.z * 2.0 - 1.0,
(frag_coord.y - viewport.y) / viewport.w * 2.0 - 1.0);
vec4 clip = vec4(ndc, 1.0, 1.0);
vec4 view_space = inverse_projection_matrix * clip;
return view_space.xyz / frag_coord.w;
}
vec3 getPosFromUVDepth(vec3 uv_depth, vec4 viewport, mat4 inverse_projection_matrix)
{
vec2 ndc = vec2((uv_depth.x - viewport.x) / viewport.z * 2.0 - 1.0,
(uv_depth.y - viewport.y) / viewport.w * 2.0 - 1.0);
vec4 clip = vec4(ndc, uv_depth.z, 1.0);
vec4 view_space = inverse_projection_matrix * clip;
return view_space.xyz / view_space.w;
}