Point light working

This commit is contained in:
Confideo-IOM
2026-08-16 13:47:11 +01:00
parent f9b696f9e8
commit 98ff54c106
50 changed files with 1187 additions and 357 deletions
@@ -2,7 +2,7 @@
#version 460 core
#extension GL_ARB_bindless_texture : require
#extension GL_ARB_gpu_shader5 : enable
uint INVALID_HYDRA_ID = 4294967295;
uint DEPTH_TEXTURE_ID = 0;
@@ -59,6 +59,21 @@ struct SpotShadowMapSet
mat4 light_space_view;
};
struct PointShadowMapSet
{
uint entity_id;
uint shadow_id;
uint shadow_texture_id;
uint frame_buffer_id;
float near_plane;
float far_plane;
uint padding[2];
mat4 light_space_proj;
mat4 light_space_view[6];
};
uniform samplerCube depth_map;
layout(binding = 0) uniform uniform_per_frame
{
mat4 view;
@@ -96,6 +111,12 @@ layout (std430, binding = 6) readonly buffer spot_shadow_map_sets
{
SpotShadowMapSet spot_shadows[];
};
layout (std430, binding = 7) readonly buffer point_shadow_map_sets
{
PointShadowMapSet point_shadows[];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
@@ -224,14 +245,16 @@ vec3 PointShading(vec3 normal,
float light_linear,
float light_quadratic,
vec3 world_pos,
vec3 view_pos)
vec3 view_pos,
float shadow_val)
{
float distance = length(light_pos - world_pos);
float attenuation = 1.0;
attenuation = light_intensity / (light_constant + (light_linear * distance) + (light_quadratic * distance * distance));
vec3 radiance = diffuse * attenuation;
vec3 light_dir = normalize(light_pos - world_pos);
vec3 radiance = diffuse * attenuation * (1.0-shadow_val);
vec3 light_dir = normalize(light_pos - world_pos);
vec3 Lo = CalculatePBR(normal, view_pos, world_pos, light_dir, diffuse, radiance, roughness, metallic);
return Lo;
@@ -415,6 +438,56 @@ float CalculateSpotShadow(vec4 world_pos, uint shadow_idx, vec3 normal, vec3 lig
return shadow;
}
float SampleCubemapShadow(vec3 frag_to_light, float far_plane, float view_distance, samplerCube sampler_shadow_map)
{
vec3 sample_offset_directions[20] = vec3[]
(
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
);
float shadow = 0.0;
float bias = 0.01;
int samples = 20;
float disk_radius = (1.0 + (view_distance / far_plane)) / 50.0;
float frag_depth = length(frag_to_light);
for(int i = 0; i < samples; ++i)
{
//float closest_depth = texture(sampler_shadow_map, frag_to_light).r;
float closest_depth = texture(sampler_shadow_map, frag_to_light + sample_offset_directions[i] * disk_radius).r;
closest_depth *= far_plane; // undo mapping [0;1]
if(frag_depth - bias > closest_depth)
shadow += 1.0;
}
shadow /= float(samples);
return shadow;
// float frag_depth = length(frag_to_light);
// closest_depth = closest_depth * far_plane;
// float bias = 0.05f;
// float shadow = (frag_depth - bias) > closest_depth ? 1.0 : 0.0;
// return shadow;
}
float CalculatePointShadow(vec3 world_pos, uint shadow_idx, float view_distance, vec3 light_position)
{
vec3 frag_to_light = light_position - world_pos;
uvec2 shadow_handle = textures[point_shadows[shadow_idx].shadow_texture_id];
float far_plane = point_shadows[shadow_idx].far_plane;
return SampleCubemapShadow(frag_to_light, far_plane, view_distance, samplerCube(shadow_handle));
}
void main()
{
uvec2 diffuse_handle = textures[texture_ids[DIFFUSE_TEXTURE_ID]];
@@ -431,6 +504,7 @@ void main()
vec3 normal = texture(sampler2D(normal_handle), vs_out.vsUV.xy).xyz;
vec3 metal_rough = texture(sampler2D(metal_rough_handle), vs_out.vsUV.xy).xyz;
vec3 world_pos = texture(sampler2D(world_pos_handle), vs_out.vsUV.xy).xyz;
float rough = metal_rough[1];
float metal = metal_rough[2];
float ao = 1;
@@ -448,14 +522,19 @@ void main()
Lo += DirectionalShading(normal, diffuse.xyz, rough, metal, lights[i].intensity, light_direction, light_pos, world_pos, ubo_per_frame.viewer_pos);
if(lights[i].shadow_caster == 1)
{
vec3 shadow = CalculateDirectionalShadow(vec4(world_pos, 1.0), lights[i].shadow_map_id, normal, light_direction, ubo_per_frame.viewer_pos);
//Lo = Lo * vec3(shadow);
vec3 shadow = CalculateDirectionalShadow(vec4(world_pos, 1.0), lights[i].shadow_map_id, normal, light_direction, ubo_per_frame.viewer_pos);
Lo = Lo * shadow;
}
}
else if(lights[i].light_type == HYDRA_LIGHT_POINT)
{
float shadow = 0;
if(lights[i].shadow_caster == 1)
{
float view_to_frag = length(light_pos - ubo_per_frame.viewer_pos );
shadow = CalculatePointShadow(world_pos, i, view_to_frag, light_pos);
}
Lo += PointShading(normal,
diffuse.xyz,
rough,
@@ -466,14 +545,16 @@ void main()
lights[i].linear,
lights[i].quadratic,
world_pos,
ubo_per_frame.viewer_pos);
ubo_per_frame.viewer_pos,
shadow);
}
else if(lights[i].light_type == HYDRA_LIGHT_SPOT)
{
float shadow = 0;
if(lights[i].shadow_caster == 1)
if(lights[i].shadow_caster == 1)
{
float distance = length(light_pos - world_pos);
// float distance = length(light_pos - world_pos);
shadow = CalculateSpotShadow(vec4(world_pos, 1.0),
lights[i].shadow_map_id,
normal,