Skip to content

Commit

Permalink
feat: add dissolve back and started on light clusters
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Pollind <[email protected]>
  • Loading branch information
pollend committed Nov 22, 2023
1 parent bf27565 commit 3b2911f
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 159 deletions.
24 changes: 18 additions & 6 deletions HPL2/include/graphics/RendererDeferred2.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,19 @@ namespace hpl {
static constexpr uint32_t MaxQueryPoolSize = MaxOcclusionDescSize * 2;
static constexpr uint32_t MaxIndirectDrawArgs = 4096;

static constexpr uint32_t TranslucencyBlendModeMask = 0xf;

static constexpr uint32_t TranslucencyReflectionBufferMask = 0x7;
static constexpr uint32_t TranslucencyReflectionBufferOffset = 4;

static constexpr uint32_t PointLightCount = 256;
static constexpr float ShadowDistanceMedium = 10;
static constexpr float ShadowDistanceLow = 20;
static constexpr float ShadowDistanceNone = 40;

static constexpr uint32_t MaxSolidDiffuseMaterials = 512;

static constexpr uint32_t LightClusterWidth = 8;
static constexpr uint32_t LightClusterHeight = 8;
static constexpr uint32_t LightClusterLightCount = 128;



struct ViewportData {
public:
ViewportData() = default;
Expand Down Expand Up @@ -138,7 +140,8 @@ namespace hpl {

UniqueViewportData<ViewportData> m_boundViewportData;

SharedSampler m_nearEdgeClamp;
SharedSampler m_samplerNearEdgeClamp;
SharedSampler m_samplerPointWrap;
std::array<SceneMaterial, cMaterial::MaxMaterialID> m_sceneMaterial;
TextureDescriptorPool m_sceneTexture2DPool;
CommandSignature* m_cmdSignatureVBPass = NULL;
Expand All @@ -155,6 +158,9 @@ namespace hpl {
SharedShader m_visibilityBufferAlphaPassShader;
SharedShader m_visibilityShadePassShader;

SharedShader m_lightClusterShader;
SharedShader m_clearLightClusterShader;

SharedPipeline m_visibilityBufferPass;
SharedPipeline m_visbilityAlphaBufferPass;
SharedPipeline m_visiblityShadePass;
Expand All @@ -166,12 +172,18 @@ namespace hpl {
folly::F14ValueMap<iRenderable*, uint32_t> m_objectDescriptorLookup;

SharedTexture m_emptyTexture;
Image* m_dissolveImage;

uint32_t m_activeFrame = 0;
uint32_t m_objectIndex = 0;
uint32_t m_indirectDrawIndex = 0;

cRenderList m_rendererList;

// Lights
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_lightClustersBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_lightClusterCountBuffer;
std::array<SharedBuffer, ForgeRenderer::SwapChainLength> m_pointLightBuffer;
};
}; // namespace hpl

12 changes: 10 additions & 2 deletions HPL2/include/graphics/SceneResource.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#pragma once


#include "graphics/GraphicsTypes.h"
#include "graphics/TextureDescriptorPool.h"
#include "graphics/Material.h"


#include "Common_3/Utilities/Math/MathTypes.h"
#include <FixPreprocessor.h>

Expand Down Expand Up @@ -35,6 +33,8 @@ namespace hpl::resource {

uint32_t constexpr IsAlphaSingleChannel = 0x1;
uint32_t constexpr IsHeightSingleChannel = 0x2;
uint32_t constexpr UseAlphaDissolveFilter = 0x4;

struct ViewportInfo {
static constexpr uint32_t PrmaryViewportIndex = 0;
mat4 m_invViewMat;
Expand Down Expand Up @@ -76,6 +76,14 @@ namespace hpl::resource {
mat4 m_uvMat;
};

struct ScenePointLight {
mat4 m_mvp;
float3 m_lightPos;
uint m_config;
float4 m_lightColor;
float m_radius;
};

struct DiffuseMaterial {
union {
uint m_texture[4];
Expand Down
10 changes: 10 additions & 0 deletions HPL2/resource/ShaderList.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,14 @@
#frag visibilityBuffer_alpha_pass.frag
#include "visibilityBuffer_alpha_pass.frag.fsl"
#end

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

#comp scene_light_cluster_clear.comp
#include "scene_light_cluster_clear.comp.fsl"
#end



1 change: 1 addition & 0 deletions HPL2/resource/scene_defs.h.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ STRUCT(UniformObject)

#define MATERIAL_IS_ALPHA_SINGLE_CHANNEL (0x1)
#define MATERIAL_IS_HEIGHT_SINGLE_CHANNEL (0x2)
#define MATERIAL_USE_ALPHA_DISSOLVE_FILTER (0x4)

#define MATERIAL_TYPE_SOLID_DIFFUSE 1
#define MATERIAL_TYPE_SOLID_TRANSLUCENT 2
Expand Down
65 changes: 65 additions & 0 deletions HPL2/resource/scene_light_cluster.comp.fsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "scene_resource.h.fsl"

NUM_THREADS(LIGHT_CLUSTER_WIDTH, LIGHT_CLUSTER_HEIGHT, 1)
void CS_MAIN(SV_GroupThreadID(uint3) threadInGroupId, SV_GroupID(uint3) groupId)
{
INIT_MAIN;
const float invClusterWidth = 1.0f / float(LIGHT_CLUSTER_WIDTH);
const float invClusterHeight = 1.0f / float(LIGHT_CLUSTER_HEIGHT);
ViewportInfo viewInfo = Get(viewports)[PRIMARY_VIEWPORT_INDEX];
float2 size = viewInfo.rect.zw;
float4x4 viewProjMat = mul(viewInfo.projMat, viewInfo.viewMat);

const float aspectRatio = size.x / size.y;

PointLight lightData = Get(pointLights)[groupId.x];

float4 lightPosWorldSpace = float4(lightData.lightPos.xyz, 1.0f);
float4 lightPosClipSpace = mul(viewProjMat, lightPosWorldSpace);
float invLightPosW = 1.0f / lightPosClipSpace.w;
float3 lightPos = lightPosClipSpace.xyz * invLightPosW;

float fov = 2.0 * atan(1.0/viewInfo.projMat[1][1]);
float projRadius = 2.0f * lightData.lightRadius * (1 / tan(fov * 0.5f)) * invLightPosW;
projRadius *= size.x > size.y ? aspectRatio : 1 / aspectRatio;

// Early exit light if it's behind the camera
if (lightPosClipSpace.w < 0.0f && -lightPosClipSpace.w > lightData.lightRadius) {
RETURN();
}

lightPos.x *= aspectRatio;

// Cluster coordinates in post perspective clip space
float clusterLeft = float(threadInGroupId.x) * invClusterWidth;
float clusterTop = float(threadInGroupId.y) * invClusterHeight;
float clusterRight = clusterLeft + invClusterWidth;
float clusterBottom = clusterTop + invClusterHeight;

// Transform coordinates from range [0..1] to range [-1..1]
clusterLeft = clusterLeft * 2.0f - 1.0f;
clusterTop = clusterTop * 2.0f - 1.0f;
clusterRight = clusterRight * 2.0f - 1.0f;
clusterBottom = clusterBottom * 2.0f - 1.0f;

clusterLeft *= aspectRatio;
clusterRight *= aspectRatio;

float clusterCenterX = (clusterLeft + clusterRight) * 0.5f;
float clusterCenterY = (clusterTop + clusterBottom) * 0.5f;
float clusterRadius = distance(float2(clusterLeft, clusterTop), float2(clusterRight, clusterBottom)) * 0.5f;

// Check if the light projection overlaps the cluster: add the light bit to this cluster coords
float distanceToCenter = distance(float2(clusterCenterX, clusterCenterY), lightPos.xy);

if (distanceToCenter - clusterRadius < abs(projRadius))
{
// Increase light count on this cluster
uint lightArrayPos = 0;
AtomicAdd(Get(lightClustersCount)[LIGHT_CLUSTER_COUNT_POS(threadInGroupId.x, threadInGroupId.y)], 1, lightArrayPos);

// Add light id to cluster
AtomicExchange(Get(lightClusters)[LIGHT_CLUSTER_DATA_POS(lightArrayPos, threadInGroupId.x, threadInGroupId.y)], groupId.x, lightArrayPos);
}
}

11 changes: 11 additions & 0 deletions HPL2/resource/scene_light_cluster_clear.comp.fsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "scene_resource.h.fsl"

NUM_THREADS(LIGHT_CLUSTER_WIDTH, LIGHT_CLUSTER_HEIGHT, 1)
void CS_MAIN(SV_DispatchThreadID(uint3) threadID)
{
INIT_MAIN;
AtomicStore(Get(lightClustersCount)[LIGHT_CLUSTER_COUNT_POS(threadID.x, threadID.y)], 0);
RETURN();
}


11 changes: 9 additions & 2 deletions HPL2/resource/scene_resource.h.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@ RES(ByteBuffer, vtxOpaqueColor, UPDATE_FREQ_NONE, t4, binding = 8);

RES(Buffer(DiffuseMaterial), sceneDiffuseMat, UPDATE_FREQ_NONE, t0, binding = 9);

RES(SamplerState, linearBorderClamp, UPDATE_FREQ_PER_FRAME, s1, binding = 10);
RES(Tex2D(float4), visibilityTexture, UPDATE_FREQ_PER_FRAME, t0, binding = 11);
RES(SamplerState, nearEdgeClampSampler, UPDATE_FREQ_NONE, s1, binding = 10);
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(PointLight), pointLights, UPDATE_FREQ_PER_FRAME, t0, binding = 14);
RES(RWBuffer(atomic_uint), lightClustersCount, UPDATE_FREQ_PER_FRAME, u0, binding = 15);
RES(RWBuffer(atomic_uint), lightClusters, UPDATE_FREQ_PER_FRAME, u1, binding = 16);

RES(SamplerState, sceneFilters[SCENE_MAX_FILTER_COUNT], UPDATE_FREQ_NONE, s1, binding = 20);
RES(Tex2D(float4), sceneTextures[SCENE_MAX_TEXTURE_COUNT], UPDATE_FREQ_PER_FRAME, t5, binding = 20 + SCENE_MAX_FILTER_COUNT);
Expand Down
35 changes: 29 additions & 6 deletions HPL2/resource/visibilityBuffer_alpha_pass.frag.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID)

SceneTexture alphaTexture = CreateSceneTexture(diffuseMat.samplerIndex, DiffuseMaterial_AlphaTexture_ID(diffuseMat));
SceneTexture heightTexture = CreateSceneTexture(diffuseMat.samplerIndex, DiffuseMaterial_HeightTexture_ID(diffuseMat));

float2 parallax = float2(0,0);
SceneTexture dissolveAlphaTexture = CreateSceneTexture(diffuseMat.samplerIndex, DiffuseMaterial_DissolveAlphaTexture_ID(diffuseMat));

float diffuseAlpha = 1.0;


float2 texCoord = In.uv;
if(IsSceneTextureValid(heightTexture)) {
parallax = ParallaxAdvance(
texCoord += ParallaxAdvance(
In.uv,
0.0,
32.0,
Expand All @@ -44,17 +48,36 @@ PsOut PS_MAIN(PsIn In, SV_PrimitiveID(uint) primitiveID)
heightTexture,
(diffuseMat.materialConfig & MATERIAL_IS_HEIGHT_SINGLE_CHANNEL) > 0);
}
float diffuseAlpha = 1.0;


float4 value;
if(SampleSceneTextureFloat4(alphaTexture, In.uv + parallax, value)) {
if(SampleSceneTextureFloat4(alphaTexture, texCoord, value)) {
if((diffuseMat.materialConfig & MATERIAL_IS_ALPHA_SINGLE_CHANNEL) > 0) {
diffuseAlpha = value.r;
} else {
diffuseAlpha = value.a;
}
}

if(obj.dissolveAmount < 1.0 || IsSceneTextureValid(alphaTexture) || (diffuseMat.materialConfig & MATERIAL_USE_ALPHA_DISSOLVE_FILTER) > 0) {
const float2 dissolveCoord = In.Position.xy * (1.0/128.0); //128 = size of dissolve texture.
float fDissolve = SampleTex2D(Get(dissolveTexture), Get(nearPointWrapSampler), dissolveCoord).x;

if(IsSceneTextureValid(dissolveAlphaTexture)) {
//Get in 0.75 - 1 range
fDissolve = fDissolve * 0.25 + 0.75;

float4 alphaValue;
SampleSceneTextureFloat4(dissolveAlphaTexture, texCoord, alphaValue);
float fDissolveAlpha = alphaValue.r;
fDissolve -= (0.25 - fDissolveAlpha * 0.25);
} else {
//Get in 0.5 - 1 range.
fDissolve = fDissolve*0.5 + 0.5;
}
diffuseAlpha = fDissolve - (1.0 - (obj.dissolveAmount * diffuseAlpha)) * 0.5;
}

if(diffuseAlpha < 0.5) {
discard;
}
Expand Down
2 changes: 1 addition & 1 deletion HPL2/resource/visibility_shade_pass.frag.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ PsOut PS_MAIN(PsIn In)
{
INIT_MAIN;

float4 visRaw = LoadTex2D(Get(visibilityTexture), Get(linearBorderClamp), uint2(In.position.xy), 0);
float4 visRaw = LoadTex2D(Get(visibilityTexture), Get(nearEdgeClampSampler), uint2(In.position.xy), 0);
// Unpack float4 render target data into uint to extract data
uint objectId_triId = packUnorm4x8(visRaw);
uint objectId = SCENE_VIZ_OBJECT_ID(objectId_triId);
Expand Down
Loading

0 comments on commit 3b2911f

Please sign in to comment.