Directional Works

This commit is contained in:
Confideo-IOM
2026-08-04 20:06:37 +01:00
parent 2b3785e6af
commit f51b435a9d
13 changed files with 96 additions and 89 deletions
@@ -275,7 +275,8 @@ float SimpleSampleShadow(vec4 frag_clip_space, sampler2DArray sampler_shadow_map
float shadow_map_depth = texture(sampler_shadow_map, vec3(frag_light_space.xy, shadow_trans_idx)).r;
// return frag_light_space.z - shadow_map_depth;
// return shadow_map_depth ;
//return shadow_map_depth ;
//return frag_light_space.z;
if(frag_light_space.z > shadow_map_depth)
{
return 0;
@@ -290,27 +291,27 @@ float SampleShadow(vec4 frag_clip_space, sampler2DArray sampler_shadow_map, uint
float shadow_map_depth = texture(sampler_shadow_map, vec3(frag_light_space.xy, shadow_trans_idx)).r;
// calculate bias (based on depth map resolution and slope)
float bias = max(0.005 * (1.0 - dot(normal, light_dir)), 0.0005);
float bias = max(0.0005 * (1.0 - dot(normal, light_dir)), 0.00005);
// check whether current frag pos is in shadow
// float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
// PCF
//bias = 0;
float shadow = 0.0;
vec2 texel_size = 1.0 / textureSize(sampler_shadow_map, 0).xy;
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
shadow_map_depth = texture(sampler_shadow_map, vec3(frag_light_space.xy + vec2(x, y) * texel_size, shadow_trans_idx)).r;
shadow += frag_light_space.z - bias > shadow_map_depth ? 1.0 : 0.0;
}
}
shadow /= 9.0;
if((frag_light_space.x >= 0.0)&&(frag_light_space.y >= 0.0)
&&(frag_light_space.x <= 1.0)&&(frag_light_space.y <= 1.0))
{
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
shadow_map_depth = texture(sampler_shadow_map, vec3(frag_light_space.xy + vec2(x, y) * texel_size, shadow_trans_idx)).r;
shadow += frag_light_space.z - bias > shadow_map_depth ? 1.0 : 0.0;
}
}
shadow /= 9.0;
}
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
if(frag_light_space.z > 1.0)
shadow = 0.0;
@@ -318,48 +319,52 @@ float SampleShadow(vec4 frag_clip_space, sampler2DArray sampler_shadow_map, uint
return shadow;
}
float CalculateDirectionalShadow(vec4 world_pos, uint shadow_idx, vec3 normal, vec3 light_dir)
vec3 CalculateDirectionalShadow(vec4 world_pos, uint shadow_idx, vec3 normal, vec3 light_dir, vec3 viewer_pos)
{
float shadow = 0;
//Move the fragment to light space
vec4 frag_in_light_space = shadows[shadow_idx].light_space_view[5] * world_pos;
//measure the distance of the fragment from the light
float frag_distance = length(frag_in_light_space.xyz);
uint shadow_trans_idx = 0;
uint ignore_shadow = 0;
shadow_idx = 0;
//Work out which shadowmap is appropriate for this distance
for(uint i = 0; i < 6; i++)
float shadow = 0;
//measure the distance of the fragment from the light
float frag_distance = abs(length(viewer_pos - world_pos.xyz));
uint shadow_trans_idx = 5;
uint ignore_shadow = 0;
//Work out which shadowmap is appropriate for this distance
for(uint i = 0; i < 6; i++)
{
if(frag_distance <= shadows[shadow_idx].far_plane[i])
{
if(frag_distance <= shadows[shadow_idx].far_plane[i])
{
//record the shadow map level
shadow_trans_idx = i;
//and indicate that this has a level
ignore_shadow = 1;
break;
}
//record the shadow map level
shadow_trans_idx = i;
//and indicate that this has a level
ignore_shadow = 1;
break;
}
if(ignore_shadow == 1)
{
vec4 translated_pixel = shadows[shadow_idx].light_space_proj[shadow_trans_idx] *
shadows[shadow_idx].light_space_view[shadow_trans_idx] *
world_pos;
uvec2 shadow_handle = textures[shadows[shadow_idx].shadow_texture_id];
shadow = SampleShadow(translated_pixel, sampler2DArray(shadow_handle), shadow_trans_idx, normal, light_dir );
}
return shadow;
}
if(ignore_shadow == 1)
{
vec4 translated_pixel = shadows[shadow_idx].light_space_proj[shadow_trans_idx] *
shadows[shadow_idx].light_space_view[shadow_trans_idx] *
world_pos;
uvec2 shadow_handle = textures[shadows[shadow_idx].shadow_texture_id];
shadow = 1.0 - SampleShadow(translated_pixel, sampler2DArray(shadow_handle), shadow_trans_idx, normal, light_dir);
}
return vec3(shadow);
//return 1.0 - shadow;
if(shadow_trans_idx == 0)
{
return vec3(1,0,0) * shadow;
}
if(shadow_trans_idx == 1)
{
return vec3(0,1,0) * shadow;
}
if(shadow_trans_idx == 2)
{
return vec3(0,0,1) * shadow;
}
return vec3(0,1,1) * shadow;
}
@@ -396,8 +401,9 @@ 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)
{
float shadow = CalculateDirectionalShadow(vec4(world_pos, 1.0), lights[i].shadow_map_id, normal, light_direction);
Lo = Lo * vec3(1-shadow);
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);
Lo = Lo * shadow;
}
}
else if(lights[i].light_type == HYDRA_LIGHT_POINT)
@@ -36,11 +36,11 @@ void HydraTextureDebugActor::_CreateMesh()
float max_y = 0.5f * scale_y;
float max_z = 0.5f * scale_z;
float min_u = 1;
float min_v = 1;
float min_u = 0;
float min_v = 0;
float max_u = 0;
float max_v = 0;
float max_u = 1;
float max_v = 1;
// 1---2 5---6
// | / | | / |
@@ -89,43 +89,44 @@ void HydraDirectionalShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
float view_size = 20.0f;
float view_near = -10.0f;
float view_far = 10.0f;
float view_near = 0.1f;
float view_far = 20.0f;
float PI = 3.1415927;
float TWO_PI = 6.2831854;
glm::mat4 light_rot = glm::eulerAngleXYZ(pos_comp.orientation.x, pos_comp.orientation.y, pos_comp.orientation.z);
glm::vec3 light_dir = glm::normalize(glm::vec3(light_rot * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f)));
glm::vec3 light_dir = glm::vec3(0, 0, -1);
glm::mat3 light_rot = glm::mat3(1);
glm::vec3 light_euler = pos_comp.orientation * glm::vec3(-1,-1,-1);
light_rot = glm::eulerAngleXYZ(light_euler.x, light_euler.y, light_euler.z);
light_dir = light_rot * light_dir;
light_dir = glm::normalize(light_dir);
glm::vec3 camera_pos = GetEngine()->Camera()->GetPosition();
float light_distance = 2;
for (uint32_t i = 0; i < 6; i++)
{
glm::vec3 light_pos = camera_pos - (light_dir * light_distance);
glm::vec3 light_pos = camera_pos - (light_dir * 2.0f);
glm::vec3 target_pos = light_pos + light_dir;
glm::vec3 up_vector = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 light_trans = glm::translate(light_pos * glm::vec3(-1, 1, -1));
glm::mat4 light_orient = glm::eulerAngleXYZ(light_euler.x, light_euler.y, light_euler.z);
glm::mat4 view = light_orient * light_trans;
glm::mat4 proj = glm::ortho<float>(-view_size, view_size, view_size, -view_size, view_near, view_far);
if (glm::abs(glm::dot(light_dir, up_vector)) > 0.99f)
{
up_vector = glm::vec3(1.0f, 0.0f, 0.0f); // Prevent gimbal lock
}
shad_comp.far_plane[i] = view_far;
shad_comp.near_plane[i] = view_near;
shad_comp.light_space_proj[i] = proj;
shad_comp.light_space_view[i] = view;
glm::mat4 view = glm::lookAt(light_pos, target_pos, up_vector);
glm::mat4 proj = glm::ortho(-view_size, view_size, -view_size, view_size, view_near, view_far);
view_far *= 3.0f;
view_near = -view_far;
view_size *= 3.0f;
// Save data to component
shad_comp.far_plane[i] = view_far;
shad_comp.near_plane[i] = view_near;
shad_comp.light_space_proj[i] = proj;
shad_comp.light_space_view[i] = view;
// Scale bounds exponentially for the next cascade tier
view_size *= 3.5f;
view_far *= 3.5f;
}
}
void HydraDirectionalShadowSourceSystem::_InitialiseDirectionalLight(HydraID entity_id)
{
HydraEngine *engine = GetEngine();
@@ -134,7 +135,7 @@ void HydraDirectionalShadowSourceSystem::_InitialiseDirectionalLight(HydraID ent
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
light_comp.shadow_caster = 1;
shad_comp.entity_id = entity_id;
shad_comp.cascade_count = 6;