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: add missing pbr permutations for pre-compilation #713

Merged
merged 9 commits into from
Nov 4, 2024
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
Loading