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
+3 -3
View File
@@ -39,9 +39,9 @@ bool HydraGame::Initialise()
// GetEngine()->ActorManager()->SetPosition(m_cube_actor_id, glm::dvec3(0, -2, 0)); // GetEngine()->ActorManager()->SetPosition(m_cube_actor_id, glm::dvec3(0, -2, 0));
// GetEngine()->ActorManager()->SetRelationship(m_plane_actor_id, m_cube_actor_id); // GetEngine()->ActorManager()->SetRelationship(m_plane_actor_id, m_cube_actor_id);
// m_gltf_id = GetEngine()->ActorManager()->LoadActor("c:/Code/HydraV3/Media/Tree1.glb"); m_gltf_id = GetEngine()->ActorManager()->LoadActor("c:/Code/HydraV3/Media/AntiqueCamera.glb");
// GetEngine()->ActorManager()->InitialiseActor(m_gltf_id); GetEngine()->ActorManager()->InitialiseActor(m_gltf_id);
// GetEngine()->ActorManager()->SetPosition(m_gltf_id, glm::dvec3(0, 0, 0)); GetEngine()->ActorManager()->SetPosition(m_gltf_id, glm::dvec3(0, 0, 0));
// m_gltf_id1 = GetEngine()->ActorManager()->LoadActor("c:/Code/HydraV3/Media/Tree1.glb"); // m_gltf_id1 = GetEngine()->ActorManager()->LoadActor("c:/Code/HydraV3/Media/Tree1.glb");
// GetEngine()->ActorManager()->InitialiseActor(m_gltf_id); // GetEngine()->ActorManager()->InitialiseActor(m_gltf_id);
@@ -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; 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 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) if(frag_light_space.z > shadow_map_depth)
{ {
return 0; 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; 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) // calculate bias (based on depth map resolution and slope)
float bias = max(0.0005 * (1.0 - dot(normal, light_dir)), 0.00005);
float bias = max(0.005 * (1.0 - dot(normal, light_dir)), 0.0005);
// check whether current frag pos is in shadow // check whether current frag pos is in shadow
// float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
// PCF // PCF
//bias = 0;
float shadow = 0.0; float shadow = 0.0;
vec2 texel_size = 1.0 / textureSize(sampler_shadow_map, 0).xy; vec2 texel_size = 1.0 / textureSize(sampler_shadow_map, 0).xy;
if((frag_light_space.x >= 0.0)&&(frag_light_space.y >= 0.0)
for(int x = -1; x <= 1; ++x) &&(frag_light_space.x <= 1.0)&&(frag_light_space.y <= 1.0))
{ {
for(int y = -1; y <= 1; ++y) for(int x = -1; x <= 1; ++x)
{ {
shadow_map_depth = texture(sampler_shadow_map, vec3(frag_light_space.xy + vec2(x, y) * texel_size, shadow_trans_idx)).r; for(int y = -1; y <= 1; ++y)
shadow += frag_light_space.z - bias > shadow_map_depth ? 1.0 : 0.0; {
} 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; }
}
shadow /= 9.0;
}
// keep the shadow at 0.0 when outside the far_plane region of the light's frustum. // keep the shadow at 0.0 when outside the far_plane region of the light's frustum.
if(frag_light_space.z > 1.0) if(frag_light_space.z > 1.0)
shadow = 0.0; shadow = 0.0;
@@ -318,48 +319,52 @@ float SampleShadow(vec4 frag_clip_space, sampler2DArray sampler_shadow_map, uint
return shadow; 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; 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
//measure the distance of the fragment from the light float frag_distance = abs(length(viewer_pos - world_pos.xyz));
float frag_distance = length(frag_in_light_space.xyz);
uint shadow_trans_idx = 5;
uint shadow_trans_idx = 0; uint ignore_shadow = 0;
uint ignore_shadow = 0; //Work out which shadowmap is appropriate for this distance
for(uint i = 0; i < 6; i++)
shadow_idx = 0; {
//Work out which shadowmap is appropriate for this distance if(frag_distance <= shadows[shadow_idx].far_plane[i])
for(uint i = 0; i < 6; i++)
{ {
if(frag_distance <= shadows[shadow_idx].far_plane[i]) //record the shadow map level
{ shadow_trans_idx = i;
//record the shadow map level //and indicate that this has a level
shadow_trans_idx = i; ignore_shadow = 1;
//and indicate that this has a level break;
ignore_shadow = 1;
break;
}
} }
}
if(ignore_shadow == 1) if(ignore_shadow == 1)
{ {
vec4 translated_pixel = shadows[shadow_idx].light_space_proj[shadow_trans_idx] *
vec4 translated_pixel = shadows[shadow_idx].light_space_proj[shadow_trans_idx] * shadows[shadow_idx].light_space_view[shadow_trans_idx] *
shadows[shadow_idx].light_space_view[shadow_trans_idx] * world_pos;
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);
uvec2 shadow_handle = textures[shadows[shadow_idx].shadow_texture_id]; }
return vec3(shadow);
//return 1.0 - shadow;
shadow = SampleShadow(translated_pixel, sampler2DArray(shadow_handle), shadow_trans_idx, normal, light_dir ); if(shadow_trans_idx == 0)
{
} return vec3(1,0,0) * shadow;
}
return 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); 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) if(lights[i].shadow_caster == 1)
{ {
float shadow = CalculateDirectionalShadow(vec4(world_pos, 1.0), lights[i].shadow_map_id, normal, light_direction); vec3 shadow = CalculateDirectionalShadow(vec4(world_pos, 1.0), lights[i].shadow_map_id, normal, light_direction, ubo_per_frame.viewer_pos);
Lo = Lo * vec3(1-shadow); //Lo = Lo * vec3(shadow);
Lo = Lo * shadow;
} }
} }
else if(lights[i].light_type == HYDRA_LIGHT_POINT) 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_y = 0.5f * scale_y;
float max_z = 0.5f * scale_z; float max_z = 0.5f * scale_z;
float min_u = 1; float min_u = 0;
float min_v = 1; float min_v = 0;
float max_u = 0; float max_u = 1;
float max_v = 0; float max_v = 1;
// 1---2 5---6 // 1---2 5---6
// | / | | / | // | / | | / |
@@ -89,43 +89,44 @@ void HydraDirectionalShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id); HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
float view_size = 20.0f; float view_size = 20.0f;
float view_near = -10.0f; float view_near = 0.1f;
float view_far = 10.0f; float view_far = 20.0f;
float PI = 3.1415927; float PI = 3.1415927;
float TWO_PI = 6.2831854; 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(); glm::vec3 camera_pos = GetEngine()->Camera()->GetPosition();
float light_distance = 2;
for (uint32_t i = 0; i < 6; i++) 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)); if (glm::abs(glm::dot(light_dir, up_vector)) > 0.99f)
glm::mat4 light_orient = glm::eulerAngleXYZ(light_euler.x, light_euler.y, light_euler.z); {
up_vector = glm::vec3(1.0f, 0.0f, 0.0f); // Prevent gimbal lock
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);
shad_comp.far_plane[i] = view_far; glm::mat4 view = glm::lookAt(light_pos, target_pos, up_vector);
shad_comp.near_plane[i] = view_near; glm::mat4 proj = glm::ortho(-view_size, view_size, -view_size, view_size, view_near, view_far);
shad_comp.light_space_proj[i] = proj;
shad_comp.light_space_view[i] = view;
view_far *= 3.0f; // Save data to component
view_near = -view_far; shad_comp.far_plane[i] = view_far;
view_size *= 3.0f; 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) void HydraDirectionalShadowSourceSystem::_InitialiseDirectionalLight(HydraID entity_id)
{ {
HydraEngine *engine = GetEngine(); HydraEngine *engine = GetEngine();
@@ -134,7 +135,7 @@ void HydraDirectionalShadowSourceSystem::_InitialiseDirectionalLight(HydraID ent
HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id); HydraDirectionalShadowSourceComponent &shad_comp = ecs->GetComponent<HydraDirectionalShadowSourceComponent>(entity_id);
HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id); HydraLightComponent &light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
light_comp.shadow_caster = 1;
shad_comp.entity_id = entity_id; shad_comp.entity_id = entity_id;
shad_comp.cascade_count = 6; shad_comp.cascade_count = 6;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.