Skip to content

Commit

Permalink
feat: add light cluster
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Pollind <[email protected]>
  • Loading branch information
pollend committed Dec 10, 2023
1 parent be8c39f commit 56053e3
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 253 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ add_definitions(
# -DUSE_FORWARD_PLUS_BACKEND # prototype forward renderer
)

set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

# hack to get to build on windwos
# HACK to correctly set Linux property for newer cmake
Expand Down
12 changes: 4 additions & 8 deletions HPL2/include/graphics/RendererDeferred2.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,13 @@ namespace hpl {
// Lights
SharedRootSignature m_lightClusterRootSignature;
std::array<SharedDescriptorSet, ForgeRenderer::SwapChainLength> m_lightDescriptorPerFrameSet;
SharedShader m_lightClusterPointLightShader;
SharedShader m_lightClusterSpotLightShader;
SharedShader m_lightClusterShader;
SharedShader m_clearLightClusterShader;
SharedPipeline m_pointLightClusterPipeline;
SharedPipeline m_spotLightClusterPipeline;
SharedPipeline m_lightClusterPipeline;
SharedPipeline m_clearClusterPipeline;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_lightClustersBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_pointLightClusterCountBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_spotLightClusterCountBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_pointLightBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_spotlightBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_lightClusterCountBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_lightBuffer;
};
}; // namespace hpl

52 changes: 37 additions & 15 deletions HPL2/include/graphics/SceneResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ namespace hpl::resource {

static constexpr uint32_t MaterialIDMask = 0xff; // 0000 0000 0000 0000 0000 0000 1111 1111
static constexpr uint32_t MaterialIndexMask = 0xffff00; // 0000 0000 1111 1111 1111 1111 0000 0000
static constexpr uint32_t InvalidSceneTexsture = 0xffff;
static constexpr uint32_t InvalidSceneTexture = 0xffff;
uint32_t encodeMaterialID(hpl::MaterialID id, uint32_t handle);

enum LightType {
PointLight = 0,
SpotLight = 1
};


uint32_t constexpr IsAlphaSingleChannel = 0x1;
uint32_t constexpr IsHeightSingleChannel = 0x2;
Expand Down Expand Up @@ -78,23 +83,40 @@ namespace hpl::resource {
mat4 m_uvMat;
};

struct ScenePointLight {
float3 m_worldPos;
// struct ScenePointLight {
// float3 m_worldPos;
// float m_radius;
// float4 m_lightColor;
// };

// struct SceneSpotLight {
// mat4 m_viewProjection;
// float3 m_worldPos;
// uint m_config;
// float3 m_direction;
// float m_angle;
// float4 m_lightColor;
// float m_radius;
// uint32_t m_goboTexture;
// uint32_t m_pad1;
// uint32_t m_pad2;
// };

struct LightConstant {
float3 m_direction;
uint m_lightType;

float3 m_position;
float m_radius;
float4 m_lightColor;
};

struct SceneSpotLight {
mat4 m_viewProjection;
float3 m_worldPos;
uint m_config;
float3 m_direction;
float4 m_color;

uint m_attenuationTexture;
float m_angle;
float4 m_lightColor;
float m_radius;
uint32_t m_goboTexture;
uint32_t m_pad1;
uint32_t m_pad2;
uint m_goboTexture;
uint m_pad2;

mat4 m_viewProjection;
};

struct DiffuseMaterial {
Expand Down
10 changes: 5 additions & 5 deletions HPL2/resource/ShaderList.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,13 @@
#include "visibilityBuffer_alpha_pass.frag.fsl"
#end

#comp scene_light_cluster_pointlight.comp
#include "scene_light_cluster_pointlight.comp.fsl"
#comp scene_light_cluster.comp
#include "scene_light_cluster.comp.fsl"
#end

#comp scene_light_cluster_spotlight.comp
#include "scene_light_cluster_spotlight.comp.fsl"
#end
//#comp scene_light_cluster_spotlight.comp
// #include "scene_light_cluster_spotlight.comp.fsl"
//#end

#comp scene_light_cluster_clear.comp
#include "scene_light_cluster_clear.comp.fsl"
Expand Down
38 changes: 28 additions & 10 deletions HPL2/resource/scene_defs.h.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,38 @@ STRUCT(PointLight) {
DATA(float4, lightColor, none);
};

STRUCT(SpotLight) {
DATA(mat4, viewProjection, none);
DATA(float3, lightPos, none);
DATA(uint, config, none);
#define LIGHT_TYPE_POINT_LIGHT 0
#define LIGHT_TYPE_SPOT_LIGHT 1

STRUCT(Light) {
DATA(float3, direction, none);
DATA(float, angle, none);
DATA(float4, lightColor, none);
DATA(uint, lightType, none);

DATA(float3, position, none);
DATA(float, radius, none);
DATA(uint, goboTexture, NONE);
DATA(uint, __pad1, NONE);

DATA(float4, color, none);

DATA(uint, attenuationTexture, NONE);
DATA(float, angle, none);
DATA(uint, goboTextureIndex, NONE);
DATA(uint, __pad2, NONE);

DATA(mat4, viewProjection, none);
};
#define LIGHT_TYPE_POINT_LIGHT 1
#define LIGHT_TYPE_SPOT_LIGHT 2

//STRUCT(SpotLight) {
// DATA(mat4, viewProjection, none);
// DATA(float3, lightPos, none);
// DATA(uint, config, none);
// DATA(float3, direction, none);
// DATA(float, angle, none);
// DATA(float4, lightColor, none);
// DATA(float, radius, none);
// DATA(uint, goboTexture, NONE);
// DATA(uint, __pad1, NONE);
// DATA(uint, __pad2, NONE);
//};

#define LIGHT_ID_BIT 0
#define LIGHT_INDEX_BIT 8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,23 @@ void CS_MAIN(SV_GroupThreadID(uint3) threadInGroupId, SV_GroupID(uint3) groupId)
float3 minPointAABB = min(min(viewSpaceNearP1, viewSpaceNearP2), min(viewSpaceFarP1, viewSpaceFarP2));
float3 maxPointAABB = max(max(viewSpaceNearP1, viewSpaceNearP2), max(viewSpaceFarP1, viewSpaceFarP2));

PointLight lightData = Get(pointLights)[groupId.x];
float4 lightViewPos = mul(viewInfo.viewMat, float4(lightData.lightPos.xyz, 1.0f));
if (testSphereAABB(lightViewPos.xyz, lightData.lightRadius * 1.2f, minPointAABB, maxPointAABB)) {
Light light = Get(lights)[groupId.x];
float4 sphere; //= mul(viewInfo.viewMat, float4(lightData.lightPos.xyz, 1.0f));

switch(light.lightType) {
case LIGHT_TYPE_POINT_LIGHT:
sphere = float4(mul(viewInfo.viewMat, float4(light.position.xyz, 1.0f)).xyz, light.radius * 1.2f);
break;
case LIGHT_TYPE_SPOT_LIGHT:
float4 boundingSphere = boundingSphereForSpotlight(light.position, light.direction, light.radius, light.angle);
sphere = float4(mul(viewInfo.viewMat, float4(boundingSphere.xyz, 1.0f)).xyz, boundingSphere.w);
break;
}

if (testSphereAABB(sphere.xyz, sphere.w, minPointAABB, maxPointAABB)) {
// Increase light count on this cluster
uint lightArrayPos = 0;
AtomicAdd(Get(pointLightClustersCount)[LIGHT_FROXEL_COUNT_POS(threadInGroupId.x, threadInGroupId.y, groupId.z)], 1, lightArrayPos);
AtomicAdd(Get(lightClustersCount)[LIGHT_FROXEL_COUNT_POS(threadInGroupId.x, threadInGroupId.y, groupId.z)], 1, lightArrayPos);

// Add light id to cluster
AtomicExchange(Get(lightClusters)[LIGHT_FROXEL_DATA_POS(threadInGroupId.x, threadInGroupId.y, groupId.z, lightArrayPos)], groupId.x, lightArrayPos);
Expand Down
3 changes: 1 addition & 2 deletions HPL2/resource/scene_light_cluster_clear.comp.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ NUM_THREADS(LIGHT_CLUSTER_WIDTH, LIGHT_CLUSTER_HEIGHT, 1)
void CS_MAIN(SV_GroupThreadID(uint3) threadInGroupId, SV_GroupID(uint3) groupId)
{
INIT_MAIN;
AtomicStore(Get(pointLightClustersCount)[LIGHT_FROXEL_COUNT_POS(threadInGroupId.x, threadInGroupId.y, groupId.z)], 0);
AtomicStore(Get(spotLightClustersCount)[LIGHT_FROXEL_COUNT_POS(threadInGroupId.x, threadInGroupId.y, groupId.z)], 0);
AtomicStore(Get(lightClustersCount)[LIGHT_FROXEL_COUNT_POS(threadInGroupId.x, threadInGroupId.y, groupId.z)], 0);
RETURN();
}

Expand Down
12 changes: 3 additions & 9 deletions HPL2/resource/scene_light_cluster_resource.h.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ CBUFFER(sceneInfo, UPDATE_FREQ_PER_FRAME, b0, binding = 0) {
DATA(ViewportInfo, viewports[64], None);
};

RES(Buffer(SpotLight), spotLights, UPDATE_FREQ_PER_FRAME, t0, binding = 1);
RES(Buffer(PointLight), pointLights, UPDATE_FREQ_PER_FRAME, t0, binding = 2);
RES(Buffer(Light), lights, UPDATE_FREQ_PER_FRAME, t0, binding = 1);
RES(RWBuffer(atomic_uint), lightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 2);
RES(RWBuffer(atomic_uint), lightClusters, UPDATE_FREQ_PER_FRAME, u1, binding = 3);

// cluster counts
RES(RWBuffer(atomic_uint), pointLightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 3);
RES(RWBuffer(atomic_uint), spotLightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 4);

RES(RWBuffer(atomic_uint), lightClusters, UPDATE_FREQ_PER_FRAME, u1, binding = 5);
RES(Tex2D(float), hiZTexture, UPDATE_FREQ_PER_FRAME, t0, binding = 6);
RES(SamplerState, depthSampler, UPDATE_FREQ_NONE, s0, binding = 7);
8 changes: 4 additions & 4 deletions HPL2/resource/scene_resource.h.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ RES(SamplerState, nearPointWrapSampler, UPDATE_FREQ_NONE, s1, binding = 11);
RES(Tex2D(float4), visibilityTexture, UPDATE_FREQ_PER_FRAME, t0, binding = 12);
RES(Tex2D(float4), dissolveTexture, UPDATE_FREQ_NONE, t0, binding = 13);

RES(Buffer(SpotLight), spotLights, UPDATE_FREQ_PER_FRAME, t0, binding = 14);
RES(Buffer(PointLight), pointLights, UPDATE_FREQ_PER_FRAME, t0, binding = 15);
RES(Buffer(Light), lights, UPDATE_FREQ_PER_FRAME, t0, binding = 14);
//RES(Buffer(PointLight), pointLights, UPDATE_FREQ_PER_FRAME, t0, binding = 15);

RES(RWBuffer(atomic_uint), pointLightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 16);
RES(RWBuffer(atomic_uint), spotLightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 17);
RES(RWBuffer(atomic_uint), lightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 16);
//RES(RWBuffer(atomic_uint), spotLightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 17);

RES(RWBuffer(atomic_uint), lightClusters, UPDATE_FREQ_PER_FRAME, u1, binding = 18);

Expand Down
Loading

0 comments on commit 56053e3

Please sign in to comment.