Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: cascaded shadow mapping for directional lights #13

Merged
merged 23 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4c7f78b
feat: add initial entity selection
May 3, 2024
fb03933
refac: change global allocator critical section to mutex
May 7, 2024
962834d
build: update pl_math to 0.6.4
May 7, 2024
50a0f58
feat: add support for 8 texture channels to ecs ext
May 7, 2024
94fbfd8
refac: change material jobs to load all textures in same thread in re…
May 7, 2024
755bc35
chore: model loader tweaks
May 7, 2024
832630e
fix: skin texture staging buffer issue in ref renderer
May 7, 2024
b0d34c8
chore: return app.c to default
May 7, 2024
49fdeee
feat: add light component to ECS extension
May 8, 2024
2336130
refac: return bindgroup slot 0 to draw stream from area in graphics ext
May 9, 2024
796a6fb
feat: add variable point & directional lights to metal/glsl shaders
May 9, 2024
cd238d4
feat: add "camera look at" function to ecs ext
May 14, 2024
304677d
feat: add max anisotropy option to samplers in graphics ext
May 14, 2024
a34eb9e
refac: add variable descriptor count option to texture bindings
May 14, 2024
04dc82d
feat: add support for texture arrays for graphics ext
May 14, 2024
aaa07e9
feat: add buffer binding offset options for graphics ext. vulkan backend
May 14, 2024
cf12876
fix: allow no pixel shader option to vulkan backend
May 14, 2024
bb94b89
fix: stencil buffer support in metal backend
May 14, 2024
c5a98de
refac: change metal texture views to be emulated
May 14, 2024
3dd2470
feat: add cascaded shadow support to lights in ecs ext
May 14, 2024
99f0a77
build: remove gltf environment repo
May 14, 2024
e77cfa6
feat: add support for directional light cascaded shadow mapping
May 14, 2024
33a4f5f
chore: add quick bubble sort for shaders
May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 77 additions & 62 deletions apps/app.c

Large diffs are not rendered by default.

28 changes: 25 additions & 3 deletions apps/helper_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include "pl_ds.h"
#include "pl_string.h"

static void
static plEntity
pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbShowWindow)
{
static int iSelectedEntity = -1;
static plEntity tSelectedEntity = {UINT32_MAX, UINT32_MAX};
if(pl_begin_window("Entities", pbShowWindow, false))
{
const plVec2 tWindowSize = pl_get_window_size();
Expand All @@ -21,8 +23,7 @@ pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbS
pl_layout_dynamic(0.0f, 1);
pl_separator();
pl_layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, tWindowSize.y - 75.0f, 2, pfRatios);
static int iSelectedEntity = -1;
static plEntity tSelectedEntity = {0};


if(pl_begin_child("Entities"))
{
Expand All @@ -48,7 +49,11 @@ pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbS
tSelectedEntity = ptLibrary->tTagComponentManager.sbtEntities[i];
}
else
{
iSelectedEntity = -1;
tSelectedEntity.uIndex = UINT32_MAX;
tSelectedEntity.uGeneration = UINT32_MAX;
}
}
}
}
Expand All @@ -73,6 +78,7 @@ pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbS
plCameraComponent* ptCameraComp = ptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_CAMERA, tSelectedEntity);
plAnimationComponent* ptAnimationComp = ptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_ANIMATION, tSelectedEntity);
plInverseKinematicsComponent* ptIKComp = ptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_INVERSE_KINEMATICS, tSelectedEntity);
plLightComponent* ptLightComp = ptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_LIGHT, tSelectedEntity);

pl_text("Entity: %u, %u", tSelectedEntity.uIndex, tSelectedEntity.uGeneration);

Expand Down Expand Up @@ -137,6 +143,20 @@ pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbS
pl_end_collapsing_header();
}

if(ptLightComp && pl_collapsing_header("Light"))
{
static const char* apcLightTypes[] = {
"PL_LIGHT_TYPE_DIRECTIONAL",
"PL_LIGHT_TYPE_POINT"
};
pl_text("Type: %s", apcLightTypes[ptLightComp->tType]);
pl_text("Position: (%0.3f, %0.3f, %0.3f)", ptLightComp->tPosition.r, ptLightComp->tPosition.g, ptLightComp->tPosition.b);
pl_text("Color: (%0.3f, %0.3f, %0.3f)", ptLightComp->tColor.r, ptLightComp->tColor.g, ptLightComp->tColor.b);
pl_text("Direction: (%0.3f, %0.3f, %0.3f)", ptLightComp->tDirection.r, ptLightComp->tDirection.g, ptLightComp->tDirection.b);
pl_text("Intensity: %0.3f", ptLightComp->fIntensity);
pl_text("Cast Shadow: %s", ptLightComp->tFlags & PL_LIGHT_FLAG_CAST_SHADOW ? "true" : "false");
}

if(ptMaterialComp && pl_collapsing_header("Material"))
{
pl_text("Base Color: (%0.3f, %0.3f, %0.3f, %0.3f)", ptMaterialComp->tBaseColor.r, ptMaterialComp->tBaseColor.g, ptMaterialComp->tBaseColor.b, ptMaterialComp->tBaseColor.a);
Expand Down Expand Up @@ -273,4 +293,6 @@ pl_show_ecs_window(const plEcsI* ptECS, plComponentLibrary* ptLibrary, bool* pbS

pl_end_window();
}

return tSelectedEntity;
}
2 changes: 1 addition & 1 deletion dependencies/pilotlight-libs
128 changes: 109 additions & 19 deletions extensions/pl_ecs_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,18 @@ static void* pl_ecs_get_component (plComponentLibrary* ptLibrary, plC
static void* pl_ecs_add_component (plComponentLibrary* ptLibrary, plComponentType tType, plEntity tEntity);

// components
static plEntity pl_ecs_create_tag (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_mesh (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_object (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_transform (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_material (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_skin (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_animation (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_animation_data (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_perspective_camera(plComponentLibrary* ptLibrary, const char* pcName, plVec3 tPos, float fYFov, float fAspect, float fNearZ, float fFarZ);
static plEntity pl_ecs_create_tag (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_mesh (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_object (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_transform (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_material (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_skin (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_animation (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_animation_data (plComponentLibrary* ptLibrary, const char* pcName);
static plEntity pl_ecs_create_perspective_camera (plComponentLibrary* ptLibrary, const char* pcName, plVec3 tPos, float fYFov, float fAspect, float fNearZ, float fFarZ);
static plEntity pl_ecs_create_orthographic_camera(plComponentLibrary* ptLibrary, const char* pcName, plVec3 tPos, float fWidth, float fHeight, float fNearZ, float fFarZ);
static plEntity pl_ecs_create_directional_light (plComponentLibrary*, const char* pcName, plVec3 tDirection);
static plEntity pl_ecs_create_point_light (plComponentLibrary*, const char* pcName, plVec3 tPosition);

// heirarchy
static void pl_ecs_attach_component (plComponentLibrary* ptLibrary, plEntity tEntity, plEntity tParent);
Expand All @@ -100,6 +102,7 @@ static void pl_camera_set_pitch_yaw (plCameraComponent* ptCamera, float fPitch,
static void pl_camera_translate (plCameraComponent* ptCamera, float fDx, float fDy, float fDz);
static void pl_camera_rotate (plCameraComponent* ptCamera, float fDPitch, float fDYaw);
static void pl_camera_update (plCameraComponent* ptCamera);
static void pl_camera_look_at (plCameraComponent* ptCamera, plVec3 tEye, plVec3 tTarget);

static inline float
pl__wrap_angle(float tTheta)
Expand Down Expand Up @@ -145,6 +148,8 @@ pl_load_ecs_api(void)
.create_skin = pl_ecs_create_skin,
.create_animation = pl_ecs_create_animation,
.create_animation_data = pl_ecs_create_animation_data,
.create_directional_light = pl_ecs_create_directional_light,
.create_point_light = pl_ecs_create_point_light,
.attach_component = pl_ecs_attach_component,
.deattach_component = pl_ecs_deattach_component,
.calculate_normals = pl_calculate_normals,
Expand All @@ -170,7 +175,8 @@ pl_load_camera_api(void)
.set_pitch_yaw = pl_camera_set_pitch_yaw,
.translate = pl_camera_translate,
.rotate = pl_camera_rotate,
.update = pl_camera_update
.update = pl_camera_update,
.look_at = pl_camera_look_at,
};
return &tApi;
}
Expand Down Expand Up @@ -216,6 +222,9 @@ pl_ecs_init_component_library(plComponentLibrary* ptLibrary)
ptLibrary->tInverseKinematicsComponentManager.tComponentType = PL_COMPONENT_TYPE_INVERSE_KINEMATICS;
ptLibrary->tInverseKinematicsComponentManager.szStride = sizeof(plInverseKinematicsComponent);

ptLibrary->tLightComponentManager.tComponentType = PL_COMPONENT_TYPE_LIGHT;
ptLibrary->tLightComponentManager.szStride = sizeof(plLightComponent);

ptLibrary->_ptManagers[0] = &ptLibrary->tTagComponentManager;
ptLibrary->_ptManagers[1] = &ptLibrary->tTransformComponentManager;
ptLibrary->_ptManagers[2] = &ptLibrary->tMeshComponentManager;
Expand All @@ -227,6 +236,7 @@ pl_ecs_init_component_library(plComponentLibrary* ptLibrary)
ptLibrary->_ptManagers[8] = &ptLibrary->tAnimationComponentManager;
ptLibrary->_ptManagers[9] = &ptLibrary->tAnimationDataComponentManager;
ptLibrary->_ptManagers[10] = &ptLibrary->tInverseKinematicsComponentManager;
ptLibrary->_ptManagers[11] = &ptLibrary->tLightComponentManager;

for(uint32_t i = 0; i < PL_COMPONENT_TYPE_COUNT; i++)
ptLibrary->_ptManagers[i]->ptParentLibrary = ptLibrary;
Expand Down Expand Up @@ -277,6 +287,12 @@ pl_ecs_cleanup_component_library(plComponentLibrary* ptLibrary)
pl_sb_free(sbtMeshes[i].sbtVertexJoints[1]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[0]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[1]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[2]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[3]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[4]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[5]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[6]);
pl_sb_free(sbtMeshes[i].sbtVertexTextureCoordinates[7]);
pl_sb_free(sbtMeshes[i].sbuIndices);
}

Expand Down Expand Up @@ -427,6 +443,13 @@ pl_ecs_remove_entity(plComponentLibrary* ptLibrary, plEntity tEntity)
pl_sb_del_swap(sbComponents, uEntityValue);
break;
}

case PL_COMPONENT_TYPE_LIGHT:
{
plLightComponent* sbComponents = ptLibrary->_ptManagers[i]->pComponents;
pl_sb_del_swap(sbComponents, uEntityValue);
break;
}
}
}
}
Expand Down Expand Up @@ -540,7 +563,7 @@ pl_ecs_add_component(plComponentLibrary* ptLibrary, plComponentType tType, plEnt
if(bAddSlot)
pl_sb_add(sbComponents);
ptManager->pComponents = sbComponents;
sbComponents[uComponentIndex] = (plObjectComponent){0};
sbComponents[uComponentIndex] = (plObjectComponent){.tMesh= {UINT32_MAX, UINT32_MAX}, .tTransform ={UINT32_MAX, UINT32_MAX}};
return &sbComponents[uComponentIndex];
}

Expand Down Expand Up @@ -644,6 +667,28 @@ pl_ecs_add_component(plComponentLibrary* ptLibrary, plComponentType tType, plEnt
return &sbComponents[uComponentIndex];
}

case PL_COMPONENT_TYPE_LIGHT:
{
plLightComponent* sbComponents = ptManager->pComponents;
if(bAddSlot)
pl_sb_add(sbComponents);
ptManager->pComponents = sbComponents;
sbComponents[uComponentIndex] = (plLightComponent){
.tPosition = {0.0f, 0.0f, 0.0f},
.tColor = {1.0f, 1.0f, 1.0f},
.tDirection = {0.0f, -1.0f, 0.0f},
.fIntensity = 1.0f,
.fRange = 10.0f,
.tType = PL_LIGHT_TYPE_DIRECTIONAL,
.uCascadeCount = 0,
.tFlags = 0,
.afCascadeSplits = {0}
};
for(uint32_t i = 0; i < PL_MAX_SHADOW_CASCADES; i++)
sbComponents[uComponentIndex].afCascadeSplits[i] = 8 * powf(10.0f, (float)i);
return &sbComponents[uComponentIndex];
}

}

return NULL;
Expand Down Expand Up @@ -675,6 +720,30 @@ pl_ecs_create_mesh(plComponentLibrary* ptLibrary, const char* pcName)
return tNewEntity;
}

static plEntity
pl_ecs_create_directional_light(plComponentLibrary* ptLibrary, const char* pcName, plVec3 tDirection)
{
pcName = pcName ? pcName : "unnamed directional light";
pl_log_debug_to_f(uLogChannel, "created directional light: '%s'", pcName);
plEntity tNewEntity = pl_ecs_create_tag(ptLibrary, pcName);
plLightComponent* ptLight = pl_ecs_add_component(ptLibrary, PL_COMPONENT_TYPE_LIGHT, tNewEntity);
ptLight->tDirection = tDirection;
ptLight->tType = PL_LIGHT_TYPE_DIRECTIONAL;
return tNewEntity;
}

static plEntity
pl_ecs_create_point_light(plComponentLibrary* ptLibrary, const char* pcName, plVec3 tPosition)
{
pcName = pcName ? pcName : "unnamed point light";
pl_log_debug_to_f(uLogChannel, "created point light: '%s'", pcName);
plEntity tNewEntity = pl_ecs_create_tag(ptLibrary, pcName);
plLightComponent* ptLight = pl_ecs_add_component(ptLibrary, PL_COMPONENT_TYPE_LIGHT, tNewEntity);
ptLight->tPosition = tPosition;
ptLight->tType = PL_LIGHT_TYPE_POINT;
return tNewEntity;
}

static plEntity
pl_ecs_create_object(plComponentLibrary* ptLibrary, const char* pcName)
{
Expand Down Expand Up @@ -870,16 +939,28 @@ pl__object_update_job(uint32_t uJobIndex, void* pData)
plObjectComponent* ptObject = &sbtComponents[uJobIndex];
plTransformComponent* ptTransform = pl_ecs_get_component(ptLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptObject->tTransform);
plMeshComponent* ptMesh = pl_ecs_get_component(ptLibrary, PL_COMPONENT_TYPE_MESH, ptObject->tMesh);
plSkinComponent* ptSkinComponent = pl_ecs_get_component(ptLibrary, PL_COMPONENT_TYPE_SKIN, ptMesh->tSkinComponent);

plMat4 tTransform = ptTransform->tWorld;

if(ptSkinComponent)
{
plEntity tJointEntity = ptSkinComponent->sbtJoints[0];
plTransformComponent* ptJointComponent = pl_ecs_get_component(ptLibrary, PL_COMPONENT_TYPE_TRANSFORM, tJointEntity);

const plMat4* ptIBM = &ptSkinComponent->sbtInverseBindMatrices[0];
tTransform = pl_mul_mat4(&ptJointComponent->tWorld, ptIBM);
}

const plVec3 tVerticies[] = {
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&ptTransform->tWorld, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMin.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMin.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMax.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMax.z }),
pl_mul_mat4_vec3(&tTransform, (plVec3){ ptMesh->tAABB.tMin.x, ptMesh->tAABB.tMax.y, ptMesh->tAABB.tMax.z }),
};

// calculate AABB
Expand Down Expand Up @@ -1344,6 +1425,15 @@ pl_camera_rotate(plCameraComponent* ptCamera, float fDPitch, float fDYaw)
ptCamera->fPitch = pl_clampf(0.995f * -PL_PI_2, ptCamera->fPitch, 0.995f * PL_PI_2);
}

static void
pl_camera_look_at(plCameraComponent* ptCamera, plVec3 tEye, plVec3 tTarget)
{
const plVec3 tDirection = pl_norm_vec3(pl_sub_vec3(tTarget, tEye));
ptCamera->fYaw = atan2f(tDirection.x, tDirection.z);
ptCamera->fPitch = asinf(tDirection.y);
ptCamera->tPos = tEye;
}

static void
pl_camera_update(plCameraComponent* ptCamera)
{
Expand Down
Loading
Loading