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

feature: shadow cache #96

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions HPL2/include/graphics/IndexPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ namespace hpl {
IndexPool(uint32_t reserve);

uint32_t requestId();
inline uint32_t reserve() {return m_reserve;}
void returnId(uint32_t);
private:
struct IdRange {
uint32_t m_start;
uint32_t m_end;
};
uint32_t m_reserve;
folly::small_vector<IdRange, 256> m_avaliable;
};

Expand Down
3 changes: 3 additions & 0 deletions HPL2/include/graphics/RendererDeferred.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "engine/RTTI.h"

#include "graphics/ShadowCache.h"
#include "scene/Viewport.h"
#include "scene/World.h"
#include "windowing/NativeWindow.h"
Expand Down Expand Up @@ -597,6 +598,7 @@ namespace hpl {
std::array<std::array<LightResourceEntry, MaxLightUniforms>, ForgeRenderer::SwapChainLength> m_lightResources{};
// z pass
SharedShader m_zPassShader;
SharedShader m_zPassShadowShader;
SharedPipeline m_zPassPipelineCCW;
SharedPipeline m_zPassPipelineCW;

Expand Down Expand Up @@ -707,5 +709,6 @@ namespace hpl {
cRenderList m_reflectionRendererList;
std::unique_ptr<renderer::PassHBAOPlus> m_hbaoPlusPipeline;
std::shared_ptr<DebugDraw> m_debug;
ShadowCache m_shadowCache;
};
}; // namespace hpl
69 changes: 69 additions & 0 deletions HPL2/include/graphics/ShadowCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#pragma once

#include "graphics/IndexPool.h"
#include <cstdint>
#include <vector>

#include <folly/small_vector.h>

#include <Common_3/Graphics/Interfaces/IGraphics.h>
#include <Common_3/Utilities/RingBuffer.h>
#include <FixPreprocessor.h>


namespace hpl {
class ShadowCache {
public:

struct ShadowGroup {
public:
static constexpr uint8_t IsLeaf = 0x1;
static constexpr uint8_t HasLeafs = 0x2;
static constexpr uint8_t HasGroups = 0x4;

uint16_t m_idx;

uint16_t m_x;
uint16_t m_y;
uint32_t m_age;

uint16_t m_parent; // the parent of the cache entry
uint16_t m_child; // the start of the group

// linked list for all cut levels at the same cut
uint16_t m_next;
uint16_t m_prev;

uint8_t m_flags;
uint8_t m_occupyMask: 4; // mask for the entires occuped
uint8_t m_slot: 4; // the slot index
uint8_t m_level;

uint16_t m_hashes[4];
};


struct CutLevel {
uint16_t m_begin = UINT16_MAX;
};

ShadowCache(uint32_t width, uint32_t height, uint32_t hDivisions, uint32_t vDivision, uint8_t maxCuts);
void reset(uint32_t age);
uint4 find(uint16_t hash, uint8_t level, uint32_t age);
private:
ShadowGroup* allocGroup();
ShadowCache::ShadowGroup* createCut(ShadowGroup* group);

void freeGroup(ShadowGroup* group);
void freeChildren(ShadowGroup* group);

void updateAge(ShadowCache::ShadowGroup* current, uint32_t age);
void insertAfter(ShadowCache::ShadowGroup* current, ShadowCache::ShadowGroup* grp);
void insertBefore(ShadowCache::ShadowGroup* current, ShadowCache::ShadowGroup* grp);

uint2 m_quadSize;
hpl::IndexPool m_pool;
std::vector<ShadowGroup> m_alloc; // a reserved pool of entries will contain the max possible i.e all the quads are at its lowest cut
std::vector<CutLevel> m_cut; // cut levels for each quad
};
}
12 changes: 10 additions & 2 deletions HPL2/resource/ShaderList.fsl
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
/// Copyright © 2009-2020 Frictional Games
/// Copyright 2023 Michael Pollind
/// SPDX-License-Identifier: GPL-3.0

#vert solid_z.vert
#vert solid_z_shadow.vert
#include "solid_z.vert.fsl"
#end

#frag solid_z_shadow.frag
#define ALPHA_REJECT 0.5
#include "solid_z_shadow.frag.fsl"
#end

#vert solid_z_shadow.vert
#include "solid_z_shadow.vert.fsl"
#end

#frag solid_z.frag
#define SEARCH_SAMPLE_COUNT 4
#define PARALLAX_ENABLED 1
Expand Down
17 changes: 17 additions & 0 deletions HPL2/resource/pbr.h.fsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
//
float3 F_Schlick (float3 f0 , float f90 , float u ){
return f0 + ( f90 - f0 ) * pow (1. f - u , 5. f ) ;
}

float Fr_DisneyDiffuse(float NdotV ,float NdotL ,float LdotH ,float linearRoughness)
{
float energyBias = lerp (0 , 0.5 , linearRoughness ) ;
float energyFactor = lerp (1.0 , 1.0 / 1.51 , linearRoughness ) ;
float fd90 = energyBias + 2.0 * LdotH * LdotH * linearRoughness ;
float3 f0 = float3 (1.0 f , 1.0 f , 1.0 f ) ;
float lightScatter = F_Schlick ( f0 , fd90 , NdotL ) * r ;
float viewScatter = F_Schlick ( f0 , fd90 , NdotV ) * r ;

return lightScatter * viewScatter * energyFactor ;
}
32 changes: 31 additions & 1 deletion HPL2/resource/solid_diffuse.frag.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,38 @@ PsOut PS_MAIN(PsIn In)
}
#endif

float diffuseAlpha;
if(HasAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
if(IsAlphaSingleChannel(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).r;
} else {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).a;
}
} else {
diffuseAlpha = 1.0;
}

const float dissolveAmount = Get(uniformObjectBuffer)[Get(objectId)].dissolveAmount;

if(dissolveAmount < 1.0 || HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig) || HasDissolveFilter(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
float2 vDissolveCoords = In.Position.xy * (1.0/128.0); //128 = size of dissolve texture.
float fDissolve = SampleTex2D(dissolveMap, Get(dissolveSampler), vDissolveCoords).x;

if(HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
//Get in 0.75 - 1 range
fDissolve = fDissolve*0.25 + 0.75;

float fDissolveAlpha = SampleTex2D(Get(dissolveAlphaMap), Get(materialSampler), texCoord.xy).r;
fDissolve -= (0.25 - fDissolveAlpha * 0.25);
} else {
//Get in 0.5 - 1 range.
fDissolve = fDissolve*0.5 + 0.5;
}
diffuseAlpha = fDissolve - (1.0 - (dissolveAmount * diffuseAlpha)) * 0.5;
}

float4 diffuseColor = SampleTex2D(Get(diffuseMap), Get(materialSampler), texCoord.xy);
if(diffuseColor.w < ALPHA_REJECT ) {
if(diffuseColor.w < ALPHA_REJECT || diffuseAlpha < ALPHA_REJECT) {
discard;
}

Expand Down
57 changes: 0 additions & 57 deletions HPL2/resource/solid_z.frag.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,67 +8,10 @@
STRUCT(PsIn)
{
DATA(float4, Position, SV_Position);
DATA(float3, pos, POSITION);
DATA(float2, uv, TEXCOORD0);
DATA(float3, normal, NORMAL);
DATA(float3, tangent, TANGENT);
DATA(float3, bitangent, BITANGENT);
};

float4 PS_MAIN(PsIn In)
{
INIT_MAIN;
float2 texCoord = In.uv.xy;
uint materialID = Get(uniformObjectBuffer)[Get(objectId)].materialID;

#ifdef PARALLAX_ENABLED
if(HasHeight(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
texCoord.xy += ParallaxAdvance(texCoord,
0.0,
8.0,
Get(uniformMaterialBuffer)[materialID].heightMapScale * PARALLAX_MULTIPLIER,
In.pos,
In.normal,
In.tangent,
In.bitangent,
IsHeightMapSingleChannel(Get(uniformMaterialBuffer)[materialID].materialConfig));
}
#endif

float diffuseAlpha;
if(HasAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
if(IsAlphaSingleChannel(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).r;
} else {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).a;
}
} else {
diffuseAlpha = 1.0;
}

const float dissolveAmount = Get(uniformObjectBuffer)[Get(objectId)].dissolveAmount;

if(dissolveAmount < 1.0 || HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig) || HasDissolveFilter(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
float2 vDissolveCoords = In.Position.xy * (1.0/128.0); //128 = size of dissolve texture.
float fDissolve = SampleTex2D(dissolveMap, Get(dissolveSampler), vDissolveCoords).x;

if(HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
//Get in 0.75 - 1 range
fDissolve = fDissolve*0.25 + 0.75;

float fDissolveAlpha = SampleTex2D(Get(dissolveAlphaMap), Get(materialSampler), texCoord.xy).r;
fDissolve -= (0.25 - fDissolveAlpha * 0.25);
} else {
//Get in 0.5 - 1 range.
fDissolve = fDissolve*0.5 + 0.5;
}
diffuseAlpha = fDissolve - (1.0 - (dissolveAmount * diffuseAlpha)) * 0.5;
}


if(diffuseAlpha < ALPHA_REJECT) {
discard;
}

RETURN(float4(0,0,0,0));
}
15 changes: 0 additions & 15 deletions HPL2/resource/solid_z.vert.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,11 @@
STRUCT(VSInput)
{
DATA(float3, Position, POSITION);
DATA(float2, TexCoord, TEXCOORD0);
DATA(float3, Normal, NORMAL);
DATA(float3, Tangent, TANGENT);
};

STRUCT(VSOutput)
{
DATA(float4, Position, SV_Position);
DATA(float3, pos, POSITION);
DATA(float2, uv, TEXCOORD0);
DATA(float3, normal, NORMAL);
DATA(float3, tangent, TANGENT);
DATA(float3, bitangent, BITANGENT);
};

VSOutput VS_MAIN(VSInput In)
Expand All @@ -28,14 +20,7 @@ VSOutput VS_MAIN(VSInput In)
float4x4 modelView = mul(Get(viewMat), Get(uniformObjectBuffer)[Get(objectId)].modelMat);
float4x4 modelViewPrj = mul(Get(projMat), modelView);

Out.uv = mul(Get(uniformObjectBuffer)[Get(objectId)].uvMat, float4(In.TexCoord, 0, 1.0)).xy;
Out.Position = mul(modelViewPrj , float4(In.Position.xyz, 1.0));
Out.pos = mul(modelView, float4(In.Position.xyz, 1.0)).xyz;

float3x3 normalMat = ToNormalMat(Get(uniformObjectBuffer)[Get(objectId)].invModelMat, Get(invViewMat));
Out.normal = normalize(mul(normalMat, In.Normal.xyz));
Out.tangent = normalize(mul(normalMat, In.Tangent.xyz));
Out.bitangent = normalize(mul(normalMat, cross(In.Tangent.xyz, In.Normal.xyz)));

RETURN(Out);
}
30 changes: 30 additions & 0 deletions HPL2/resource/solid_z_cut.vert.fsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#define MATERIAL_SOLID 1
#include "deferred_resources.h.fsl"
#include "deferred_common.h.fsl"

STRUCT(VSInput)
{
DATA(float3, Position, POSITION);
DATA(float2, TexCoord, TEXCOORD0);
};

STRUCT(VSOutput)
{
DATA(float4, Position, SV_Position);
DATA(float3, pos, POSITION);
DATA(float2, uv, TEXCOORD0);
};

VSOutput VS_MAIN(VSInput In)
{
INIT_MAIN;
VSOutput Out;

float4x4 modelView = mul(Get(viewMat), Get(uniformObjectBuffer)[Get(objectId)].modelMat);
float4x4 modelViewPrj = mul(Get(projMat), modelView);

Out.uv = mul(Get(uniformObjectBuffer)[Get(objectId)].uvMat, float4(In.TexCoord, 0, 1.0)).xy;
Out.pos = mul(modelView, float4(In.Position.xyz, 1.0)).xyz;

RETURN(Out);
}
56 changes: 56 additions & 0 deletions HPL2/resource/solid_z_shadow.frag.fsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/// Copyright © 2009-2020 Frictional Games
/// Copyright 2023 Michael Pollind
/// SPDX-License-Identifier: GPL-3.0
#define MATERIAL_SOLID 1
#include "deferred_resources.h.fsl"
#include "deferred_common.h.fsl"

STRUCT(PsIn)
{
DATA(float4, Position, SV_Position);
DATA(float3, pos, POSITION);
DATA(float2, uv, TEXCOORD0);
};

float4 PS_MAIN(PsIn In)
{
INIT_MAIN;
float2 texCoord = In.uv.xy;
uint materialID = Get(uniformObjectBuffer)[Get(objectId)].materialID;
float diffuseAlpha;
if(HasAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
if(IsAlphaSingleChannel(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).r;
} else {
diffuseAlpha = SampleTex2D(Get(alphaMap), Get(materialSampler), texCoord.xy).a;
}
} else {
diffuseAlpha = 1.0;
}

const float dissolveAmount = Get(uniformObjectBuffer)[Get(objectId)].dissolveAmount;

if(dissolveAmount < 1.0 || HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig) || HasDissolveFilter(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
float2 vDissolveCoords = In.Position.xy * (1.0/128.0); //128 = size of dissolve texture.
float fDissolve = SampleTex2D(dissolveMap, Get(dissolveSampler), vDissolveCoords).x;

if(HasDissolveAlpha(Get(uniformMaterialBuffer)[materialID].materialConfig)) {
//Get in 0.75 - 1 range
fDissolve = fDissolve*0.25 + 0.75;

float fDissolveAlpha = SampleTex2D(Get(dissolveAlphaMap), Get(materialSampler), texCoord.xy).r;
fDissolve -= (0.25 - fDissolveAlpha * 0.25);
} else {
//Get in 0.5 - 1 range.
fDissolve = fDissolve*0.5 + 0.5;
}
diffuseAlpha = fDissolve - (1.0 - (dissolveAmount * diffuseAlpha)) * 0.5;
}


if(diffuseAlpha < ALPHA_REJECT) {
discard;
}

RETURN(float4(0,0,0,0));
}
Loading
Loading