Skip to content

Commit

Permalink
feat: add missing pbr permutations for pre-compilation (#713)
Browse files Browse the repository at this point in the history
* feat: added missing pbr permutations for pre-compilation.

* chore: turned BASE_OBJECT_IS_SNOW into flag.

* style: 🎨 apply clang-format changes

* chore: merged DO_ALPHA_TEST and ADDITIONAL_ALPHA_MASK into single permutation.

* style: 🎨 apply clang-format changes

* chore: true exclusion of pbr vertex permutations.

* style: 🎨 apply clang-format changes

---------

Co-authored-by: Ilya Perapechka <i_perapechka@wargaming.net>
Co-authored-by: Jonahex <Jonahex@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 4, 2024
1 parent 96716e4 commit 06795c5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 101 deletions.
85 changes: 46 additions & 39 deletions package/Shaders/Lighting.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -916,11 +916,10 @@ float3 GetWorldMapBaseColor(float3 originalBaseColor, float3 rawBaseColor, float

float GetSnowParameterY(float texProjTmp, float alpha)
{
# if defined(BASE_OBJECT_IS_SNOW)
return min(1, texProjTmp + alpha);
# else
if (PixelShaderDescriptor & LightingFlags::BaseObjectIsSnow) {
return min(1, texProjTmp + alpha);
}
return texProjTmp;
# endif
}

# if defined(LOD)
Expand Down Expand Up @@ -2568,48 +2567,56 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
}
# endif
# endif
# if !defined(ADDITIONAL_ALPHA_MASK)
alpha *= MaterialData.z;
# else
uint2 alphaMask = input.Position.xy;
alphaMask.x = ((alphaMask.x << 2) & 12);
alphaMask.x = (alphaMask.y & 3) | (alphaMask.x & ~3);
const float maskValues[16] = {
0.003922,
0.533333,
0.133333,
0.666667,
0.800000,
0.266667,
0.933333,
0.400000,
0.200000,
0.733333,
0.066667,
0.600000,
0.996078,
0.466667,
0.866667,
0.333333,
};

float testTmp = 0;
if (MaterialData.z - maskValues[alphaMask.x] < 0) {
discard;
# if defined(DO_ALPHA_TEST)
[branch] if ((PixelShaderDescriptor & LightingFlags::AdditionalAlphaMask) != 0)
{
uint2 alphaMask = input.Position.xy;
alphaMask.x = ((alphaMask.x << 2) & 12);
alphaMask.x = (alphaMask.y & 3) | (alphaMask.x & ~3);
const float maskValues[16] = {
0.003922,
0.533333,
0.133333,
0.666667,
0.800000,
0.266667,
0.933333,
0.400000,
0.200000,
0.733333,
0.066667,
0.600000,
0.996078,
0.466667,
0.866667,
0.333333,
};

float testTmp = 0;
if (MaterialData.z - maskValues[alphaMask.x] < 0) {
discard;
}
}
else
# endif // defined(DO_ALPHA_TEST)
{
alpha *= MaterialData.z;
}
# endif // !defined(ADDITIONAL_ALPHA_MASK)
# if !(defined(TREE_ANIM) || defined(LODOBJECTSHD) || defined(LODOBJECTS))
alpha *= input.Color.w;
# endif // !(defined(TREE_ANIM) || defined(LODOBJECTSHD) || defined(LODOBJECTS))
# if defined(DO_ALPHA_TEST)
[branch] if ((PixelShaderDescriptor & LightingFlags::DoAlphaTest) != 0)
{
# if defined(DEPTH_WRITE_DECALS)
if (alpha - 0.0156862754 < 0) {
discard;
}
alpha = saturate(1.05 * alpha);
if (alpha - 0.0156862754 < 0) {
discard;
}
alpha = saturate(1.05 * alpha);
# endif // DEPTH_WRITE_DECALS
if (alpha - AlphaTestRefRS < 0) {
discard;
if (alpha - AlphaTestRefRS < 0) {
discard;
}
}
# endif // DO_ALPHA_TEST
psout.Diffuse.w = alpha;
Expand Down
4 changes: 2 additions & 2 deletions src/ShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ namespace SIE
{ "PLightColorB", effectPSConstants.PLightColorB },
{ "DLightColor", effectPSConstants.DLightColor },
{ "VPOSOffset", effectPSConstants.VPOSOffset },
{ "CameraData", effectPSConstants.CameraData },
{ "CameraDataEffect", effectPSConstants.CameraData },
{ "FilteringParam", effectPSConstants.FilteringParam },
{ "BaseColor", effectPSConstants.BaseColor },
{ "BaseColorScale", effectPSConstants.BaseColorScale },
Expand Down Expand Up @@ -926,7 +926,7 @@ namespace SIE
{ "BlendRadius", 5 },
{ "PosAdjust", 6 },
{ "ReflectPlane", 7 },
{ "CameraData", 8 },
{ "CameraDataWater", 8 },
{ "ProjData", 9 },
{ "VarAmounts", 10 },
{ "FogParam", 11 },
Expand Down
20 changes: 18 additions & 2 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,18 @@ void State::ModifyShaderLookup(const RE::BSShader& a_shader, uint& a_vertexDescr
(uint32_t)SIE::ShaderCache::LightingShaderFlags::Specular |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::AnisoLighting |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::BaseObjectIsSnow |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::Snow);
(uint32_t)SIE::ShaderCache::LightingShaderFlags::Snow |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::TruePbr);

a_pixelDescriptor &= ~((uint32_t)SIE::ShaderCache::LightingShaderFlags::AmbientSpecular |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::ShadowDir |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::DefShadow |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::CharacterLight);
(uint32_t)SIE::ShaderCache::LightingShaderFlags::CharacterLight |
(uint32_t)SIE::ShaderCache::LightingShaderFlags::BaseObjectIsSnow);
if (a_pixelDescriptor & (uint32_t)SIE::ShaderCache::LightingShaderFlags::AdditionalAlphaMask) {
a_pixelDescriptor |= (uint32_t)SIE::ShaderCache::LightingShaderFlags::DoAlphaTest;
a_pixelDescriptor &= ~(uint32_t)SIE::ShaderCache::LightingShaderFlags::AdditionalAlphaMask;
}

static auto enableImprovedSnow = RE::GetINISetting("bEnableImprovedSnow:Display");
static bool vr = REL::Module::IsVR();
Expand Down Expand Up @@ -579,6 +585,16 @@ void State::ModifyShaderLookup(const RE::BSShader& a_shader, uint& a_vertexDescr
a_pixelDescriptor |= 256;
}
break;
case RE::BSShader::Type::Grass:
{
auto technique = a_vertexDescriptor & 0xF;
auto flags = a_vertexDescriptor & ~0xF;
if (technique == static_cast<uint32_t>(SIE::ShaderCache::GrassShaderTechniques::TruePbr)) {
technique = 0;
}
a_vertexDescriptor = flags | technique;
}
break;
}
}
}
Expand Down
66 changes: 8 additions & 58 deletions src/TruePBR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,40 +489,15 @@ namespace Permutations
}
}

std::unordered_set<uint32_t> GeneratePBRLightingVertexPermutations()
{
using enum SIE::ShaderCache::LightingShaderFlags;

constexpr std::array defaultFlags{ VC, Skinned, WorldMap };
constexpr std::array projectedUvFlags{ VC, WorldMap };
constexpr std::array treeFlags{ VC, Skinned };
constexpr std::array landFlags{ VC };

constexpr uint32_t defaultConstantFlags = static_cast<uint32_t>(TruePbr);
constexpr uint32_t projectedUvConstantFlags = static_cast<uint32_t>(TruePbr) | static_cast<uint32_t>(ProjectedUV);

const std::unordered_set<uint32_t> defaultFlagValues = GenerateFlagPermutations(defaultFlags, defaultConstantFlags);
const std::unordered_set<uint32_t> projectedUvFlagValues = GenerateFlagPermutations(projectedUvFlags, projectedUvConstantFlags);
const std::unordered_set<uint32_t> treeFlagValues = GenerateFlagPermutations(treeFlags, defaultConstantFlags);
const std::unordered_set<uint32_t> landFlagValues = GenerateFlagPermutations(landFlags, defaultConstantFlags);

std::unordered_set<uint32_t> result;
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::None, defaultFlagValues, result);
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::None, projectedUvFlagValues, result);
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::TreeAnim, treeFlagValues, result);
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::MTLand, landFlagValues, result);
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::MTLandLODBlend, landFlagValues, result);
return result;
}

std::unordered_set<uint32_t> GeneratePBRLightingPixelPermutations()
{
using enum SIE::ShaderCache::LightingShaderFlags;

constexpr std::array defaultFlags{ Skinned, DoAlphaTest, AdditionalAlphaMask };
constexpr std::array projectedUvFlags{ DoAlphaTest, AdditionalAlphaMask, Snow, BaseObjectIsSnow };
constexpr std::array lodObjectsFlags{ WorldMap, DoAlphaTest, AdditionalAlphaMask, ProjectedUV };
constexpr std::array treeFlags{ Skinned, DoAlphaTest, AdditionalAlphaMask };
constexpr std::array defaultFlags{ Deferred, AnisoLighting, Skinned, DoAlphaTest };
constexpr std::array projectedUvFlags{ Deferred, AnisoLighting, DoAlphaTest, Snow };
constexpr std::array lodObjectsFlags{ Deferred, WorldMap, DoAlphaTest, ProjectedUV };
constexpr std::array treeFlags{ Deferred, AnisoLighting, Skinned, DoAlphaTest };
constexpr std::array landFlags{ Deferred, AnisoLighting };

constexpr uint32_t defaultConstantFlags = static_cast<uint32_t>(TruePbr) | static_cast<uint32_t>(VC);
constexpr uint32_t projectedUvConstantFlags = static_cast<uint32_t>(TruePbr) | static_cast<uint32_t>(VC) | static_cast<uint32_t>(ProjectedUV);
Expand All @@ -531,7 +506,7 @@ namespace Permutations
const std::unordered_set<uint32_t> projectedUvFlagValues = GenerateFlagPermutations(projectedUvFlags, projectedUvConstantFlags);
const std::unordered_set<uint32_t> lodObjectsFlagValues = GenerateFlagPermutations(lodObjectsFlags, defaultConstantFlags);
const std::unordered_set<uint32_t> treeFlagValues = GenerateFlagPermutations(treeFlags, defaultConstantFlags);
const std::unordered_set<uint32_t> landFlagValues = { defaultConstantFlags };
const std::unordered_set<uint32_t> landFlagValues = GenerateFlagPermutations(landFlags, defaultConstantFlags);

std::unordered_set<uint32_t> result;
AddLightingShaderDescriptors(SIE::ShaderCache::LightingShaderTechniques::None, defaultFlagValues, result);
Expand All @@ -544,38 +519,20 @@ namespace Permutations
return result;
}

std::unordered_set<uint32_t> GeneratePBRGrassPermutations()
std::unordered_set<uint32_t> GeneratePBRGrassPixelPermutations()
{
using enum SIE::ShaderCache::GrassShaderTechniques;
using enum SIE::ShaderCache::GrassShaderFlags;

return { static_cast<uint32_t>(TruePbr),
static_cast<uint32_t>(TruePbr) | static_cast<uint32_t>(AlphaTest) };
}

std::unordered_set<uint32_t> GeneratePBRGrassVertexPermutations()
{
return GeneratePBRGrassPermutations();
}

std::unordered_set<uint32_t> GeneratePBRGrassPixelPermutations()
{
return GeneratePBRGrassPermutations();
}
}

void TruePBR::GenerateShaderPermutations(RE::BSShader* shader)
{
auto& shaderCache = SIE::ShaderCache::Instance();
if (shader->shaderType == RE::BSShader::Type::Lighting) {
const auto vertexPermutations = Permutations::GeneratePBRLightingVertexPermutations();
for (auto descriptor : vertexPermutations) {
auto vertexShaderDesriptor = descriptor;
auto pixelShaderDescriptor = descriptor;
State::GetSingleton()->ModifyShaderLookup(*shader, vertexShaderDesriptor, pixelShaderDescriptor);
std::ignore = shaderCache.GetVertexShader(*shader, vertexShaderDesriptor);
}

const auto pixelPermutations = Permutations::GeneratePBRLightingPixelPermutations();
for (auto descriptor : pixelPermutations) {
auto vertexShaderDesriptor = descriptor;
Expand All @@ -584,14 +541,6 @@ void TruePBR::GenerateShaderPermutations(RE::BSShader* shader)
std::ignore = shaderCache.GetPixelShader(*shader, pixelShaderDescriptor);
}
} else if (shader->shaderType == RE::BSShader::Type::Grass) {
const auto vertexPermutations = Permutations::GeneratePBRGrassVertexPermutations();
for (auto descriptor : vertexPermutations) {
auto vertexShaderDesriptor = descriptor;
auto pixelShaderDescriptor = descriptor;
State::GetSingleton()->ModifyShaderLookup(*shader, vertexShaderDesriptor, pixelShaderDescriptor);
std::ignore = shaderCache.GetVertexShader(*shader, vertexShaderDesriptor);
}

const auto pixelPermutations = Permutations::GeneratePBRGrassPixelPermutations();
for (auto descriptor : pixelPermutations) {
auto vertexShaderDesriptor = descriptor;
Expand Down Expand Up @@ -750,6 +699,7 @@ struct BSLightingShaderProperty_GetRenderPasses
lightingFlags &= ~0b111000u;
if (isPbr) {
lightingFlags |= static_cast<uint32_t>(SIE::ShaderCache::LightingShaderFlags::TruePbr);
lightingFlags &= ~static_cast<uint32_t>(SIE::ShaderCache::LightingShaderFlags::Specular);
if (property->flags.any(RE::BSShaderProperty::EShaderPropertyFlag::kMultiTextureLandscape)) {
auto* material = static_cast<BSLightingShaderMaterialPBRLandscape*>(property->material);
if (material->HasGlint()) {
Expand Down

0 comments on commit 06795c5

Please sign in to comment.