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,
@@ -0,0 +1,84 @@
//*PIXEL*
#version 460
#extension GL_ARB_bindless_texture : require
const uint DIRECTIONAL_LIGHT = 1;
const uint POINT_LIGHT = 2;
const uint SPOT_LIGHT = 3;
uint INVALID_HYDRA_ID = 4294967295;
struct MaterialStore
{
vec4 diffuse_colour;
vec4 matalic_rough;
uint diffuse_texture_id;
uint metallic_rough_texture_id;
uint normal_texture_id;
uint padding[1];
};
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];
};
layout(std430, binding = 2) readonly buffer material_buffer
{
MaterialStore materials[1000];
};
layout(std430, binding = 3) readonly buffer texture_buffer
{
uvec2 textures[1000];
};
layout (std430, binding = 7) readonly buffer point_shadow_map_sets
{
PointShadowMapSet point_shadows[];
};
layout (location=0) in GEOM_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
vec4 frag_pos;
flat uint shad_idx;
flat vec3 light_pos;
}geom_out;
layout (location=0) out vec4 output_colour;
void main()
{
MaterialStore mat = materials[geom_out.vsMaterialID];
vec4 diffuse_val = mat.diffuse_colour;
if(mat.diffuse_texture_id != INVALID_HYDRA_ID)
{
uvec2 diffuse_handle = textures[mat.diffuse_texture_id];
diffuse_val = diffuse_val * texture(sampler2D(diffuse_handle), geom_out.vsUV.xy);
}
if(diffuse_val[3] < 1.0)
{
discard;
}
float light_distance = length(geom_out.frag_pos.xyz - geom_out.light_pos);
// map to [0;1] range by dividing by far_plane
light_distance = light_distance / point_shadows[geom_out.shad_idx].far_plane;
// write this as modified depth
gl_FragDepth = light_distance;
}
@@ -0,0 +1,74 @@
#version 450
layout(triangles, invocations = 6) in;
layout(triangle_strip, max_vertices = 3) out;
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];
};
//Push constants updated for each light
layout(binding = 0) uniform shadow_per_frame
{
vec3 camera_pos;
uint shadow_idxs;
};
layout (std430, binding = 7) readonly buffer point_shadow_map_sets
{
PointShadowMapSet point_shadows[];
};
layout (location=0) in VS_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
}vs_in[];
layout (location=0) out GEOM_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
vec4 frag_pos;
flat uint shad_idx;
flat vec3 light_pos;
}geom_out;
void main()
{
mat4 view = point_shadows[shadow_idxs].light_space_view[gl_InvocationID];
mat4 proj = point_shadows[shadow_idxs].light_space_proj;
mat3 rot_mat = mat3(view);
vec3 d = vec3(view[3]); // Column-major translation column
vec3 light_pos = -d * rot_mat;
for (int i = 0; i < 3; ++i)
{
geom_out.light_pos = light_pos;
geom_out.shad_idx = shadow_idxs;
geom_out.frag_pos = gl_in[i].gl_Position;
gl_Layer = gl_InvocationID;
vec4 clip_space_pos = proj * view * gl_in[i].gl_Position;
gl_Position = clip_space_pos;
geom_out.vsMaterialID = vs_in[gl_InvocationID].vsMaterialID;
geom_out.vsUV = vs_in[gl_InvocationID].vsUV;
EmitVertex();
}
EndPrimitive();
}
@@ -0,0 +1,71 @@
//*VERTEX*
#version 460
struct ShadowMapSet
{
uint entity_id;
uint shadow_id;
uint shadow_texture_id;
uint frame_buffer_id;
float near_plane[8];
float far_plane[8];
mat4 light_space_proj[6];
mat4 light_space_view[6];
};
struct SpotShadowMapSet
{
uint entity_id;
uint shadow_id;
uint shadow_texture_id;
uint frame_buffer_id;
float far_plane;
uint padding[3];
mat4 light_space_proj;
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[6];
mat4 light_space_view;
};
layout(binding = 1) readonly buffer positions_buffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout (location = 3) in vec3 inNormal; //8 Bytes : 12
layout (location = 4) in vec3 inBiTangent;
layout (location = 5) in vec3 inTangent;
layout (location=0) out VS_OUT
{
vec2 vsUV;
flat uint vsMaterialID;
}vs_out;
void main()
{
uint chunkid = inChunkID[0];
mat4 model = model_matrix[chunkid];
gl_Position = model * vec4(inPos, 1.0);
vs_out.vsUV = inUV;
vs_out.vsMaterialID = inChunkID[1];
}
@@ -34,30 +34,19 @@ layout (location=0) in VS_OUT
flat uint vsMaterialID;
}vs_out;
layout (location=0) out vec4 output_colour;
void main()
{
MaterialStore mat = materials[vs_out.vsMaterialID];
vec4 diffuse_val = mat.diffuse_colour;
output_colour = vec4(1,0,0,1);
if(mat.diffuse_texture_id != INVALID_HYDRA_ID)
{
output_colour = vec4(0,1,0,1);
uvec2 diffuse_handle = textures[mat.diffuse_texture_id];
diffuse_val = diffuse_val * texture(sampler2D(diffuse_handle), vs_out.vsUV.xy);
if(mat.diffuse_texture_id== 10)
{
output_colour = vec4(0,0,1,1);
}
}
if(diffuse_val[3] < 1.0)
{
discard;
output_colour = vec4(0,1,1,1);
}
}