-
Notifications
You must be signed in to change notification settings - Fork 133
feat: add Extended Translucency #678
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
features/Extended Translucency/Shaders/ExtendedTranslucency/ExtendedTranslucency.hlsli
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| namespace ExtendedTranslucency | ||
| { | ||
| namespace MaterialModel | ||
| { | ||
| static const uint Default = 0; // Use ExtendedTranslucencySettings | ||
| static const uint RimLight = 1; | ||
| static const uint IsotropicFabric = 2; | ||
| static const uint AnisotropicFabric = 3; | ||
| static const uint Disabled = 4; // Any value >= 4 | ||
| } | ||
|
|
||
| bool IsValidMaterial(uint Material) | ||
| { | ||
| return Material > 0 && Material < MaterialModel::Disabled; | ||
| } | ||
|
|
||
| uint GetMaterialModelFromDescriptor(uint Descriptor) | ||
| { | ||
| // TerrainHelper : 6 | ||
| // ExtraFeatureDescriptor : 3 | ||
| return (Descriptor >> 6) & 7; | ||
| } | ||
|
|
||
| float GetViewDependentAlphaNaive(float alpha, float3 view, float3 normal) | ||
| { | ||
| return 1.0 - (1.0 - alpha) * dot(view, normal); | ||
| } | ||
|
|
||
| float GetViewDependentAlphaFabric1D(float alpha, float3 view, float3 normal) | ||
| { | ||
| return alpha / min(1.0, (abs(dot(view, normal)) + 0.001)); | ||
| } | ||
|
|
||
| float GetViewDependentAlphaFabric2D(float alpha, float3 view, float3x3 tbnTr) | ||
| { | ||
| float3 t = tbnTr[0]; | ||
| float3 b = tbnTr[1]; | ||
| float3 n = tbnTr[2]; | ||
| float3 v = view; | ||
| float a0 = 1 - sqrt(1.0 - alpha); | ||
| return a0 * (length(cross(v, t)) + length(cross(v, b))) / (abs(dot(v, n)) + 0.001) - a0 * a0; | ||
| } | ||
|
|
||
| float SoftClamp(float alpha, float limit) | ||
| { | ||
| // soft clamp [alpha,1] and remap the transparency | ||
| alpha = min(alpha, limit / (1 + exp(-4 * (alpha - limit * 0.5) / limit))); | ||
| return saturate(alpha); | ||
| } | ||
| } |
2 changes: 2 additions & 0 deletions
2
features/Extended Translucency/Shaders/Features/ExtendedTranslucency.ini
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| [Info] | ||
| Version = 1-0-0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| #include "ExtendedTranslucency.h" | ||
|
|
||
| #include "../ShaderCache.h" | ||
| #include "../State.h" | ||
| #include "../Util.h" | ||
|
|
||
| NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT( | ||
| ExtendedTranslucency::MaterialParams, | ||
| AlphaMode, | ||
| AlphaReduction, | ||
| AlphaSoftness, | ||
| AlphaStrength); | ||
|
|
||
| const RE::BSFixedString ExtendedTranslucency::NiExtraDataName_AnisotropicAlphaMaterial = "AnisotropicAlphaMaterial"; | ||
|
|
||
| ExtendedTranslucency* ExtendedTranslucency::GetSingleton() | ||
| { | ||
| static ExtendedTranslucency singleton; | ||
| return &singleton; | ||
| } | ||
|
|
||
| void ExtendedTranslucency::BSLightingShader_SetupGeometry(RE::BSRenderPass* pass) | ||
| { | ||
| globals::state->currentExtraFeatureDescriptor &= ~(ExtraFeatureDescriptorMask << ExtraFeatureDescriptorShift); | ||
| // TODO: PERFORMANCE: Caching the feature descriptor in map<RE::BSGeometry*, uint> if this get more complex | ||
| if (auto* data = pass->geometry->GetExtraData(NiExtraDataName_AnisotropicAlphaMaterial)) { | ||
| static const REL::Relocation<const RE::NiRTTI*> NiIntegerExtraDataRTTI{ RE::NiIntegerExtraData::Ni_RTTI }; | ||
| // netimmerse_cast<RE::NiIntegerExtraData*>(data) seems not working here | ||
| if (data->GetRTTI() == NiIntegerExtraDataRTTI.get()) { | ||
|
ArcEarth marked this conversation as resolved.
|
||
| uint32_t material = static_cast<uint32_t>(static_cast<RE::NiIntegerExtraData*>(data)->value) & ExtraFeatureDescriptorMask; | ||
| if (material == MaterialModel::Disabled) { | ||
| // MaterialModel::Disabled (0) is the flag when this extra does not exist | ||
| // And it will let the effect use default settings instead of force disable it | ||
| // Ensure this is disabled by using the ForceDisabled flag | ||
| material = MaterialModel::ForceDisabled; | ||
| } | ||
| globals::state->currentExtraFeatureDescriptor |= (material << ExtraFeatureDescriptorShift); | ||
|
|
||
| // TODO: Per-material settings from Nif | ||
| // Mods supporting this feature should adjust their alpha value in texture already | ||
| // And the texture should be adjusted based on full strength param | ||
| } | ||
| } | ||
| } | ||
|
|
||
| struct ExtendedTranslucency::Hooks | ||
| { | ||
| struct BSLightingShader_SetupGeometry | ||
| { | ||
| static void thunk(RE::BSShader* This, RE::BSRenderPass* Pass, uint32_t RenderFlags) | ||
| { | ||
| ExtendedTranslucency::BSLightingShader_SetupGeometry(Pass); | ||
| func(This, Pass, RenderFlags); | ||
| } | ||
| static inline REL::Relocation<decltype(thunk)> func; | ||
| }; | ||
|
|
||
| static void Install() | ||
| { | ||
| stl::write_vfunc<0x6, BSLightingShader_SetupGeometry>(RE::VTABLE_BSLightingShader[0]); | ||
| logger::info("[ExtendedTranslucency] Installed hooks - BSLightingShader_SetupGeometry"); | ||
| } | ||
| }; | ||
|
|
||
| void ExtendedTranslucency::PostPostLoad() | ||
| { | ||
| Hooks::Install(); | ||
| } | ||
|
|
||
| void ExtendedTranslucency::DrawSettings() | ||
| { | ||
| if (ImGui::TreeNodeEx("Translucent Material", ImGuiTreeNodeFlags_DefaultOpen)) { | ||
| static const char* AlphaModeNames[4] = { | ||
| "Disabled", | ||
| "Rim Light", | ||
| "Isotropic Fabric", | ||
| "Anisotropic Fabric" | ||
| }; | ||
|
|
||
| bool changed = false; | ||
| if (ImGui::Combo("Default Material Model", (int*)&settings.AlphaMode, AlphaModeNames, 4)) { | ||
| changed = true; | ||
| } | ||
| if (auto _tt = Util::HoverTooltipWrapper()) { | ||
| ImGui::Text( | ||
| "Anisotropic transluency will make the surface more opaque when you view it parallel to the surface.\n" | ||
| " - Disabled: No anisotropic transluency\n" | ||
| " - Rim Light: Naive rim light effect\n" | ||
| " - Isotropic Fabric: Imaginary fabric weaved from threads in one direction, respect normal map.\n" | ||
| " - Anisotropic Fabric: Common fabric weaved from tangent and birnormal direction, ignores normal map.\n"); | ||
| } | ||
|
|
||
| if (ImGui::SliderFloat("Transparency Increase", &settings.AlphaReduction, 0.f, 1.f)) { | ||
| changed = true; | ||
| } | ||
| if (auto _tt = Util::HoverTooltipWrapper()) { | ||
| ImGui::Text("Transluent material will make the material more opaque on average, which could be different from the intent, reduce the alpha to counter this effect and increase the dynamic range of the output."); | ||
| } | ||
|
|
||
| if (ImGui::SliderFloat("Softness", &settings.AlphaSoftness, 0.0f, 1.0f)) { | ||
| changed = true; | ||
| } | ||
| if (auto _tt = Util::HoverTooltipWrapper()) { | ||
| ImGui::Text("Control the softness of the alpha increase, increase the softness reduce the increased amount of alpha."); | ||
| } | ||
|
|
||
| if (ImGui::SliderFloat("Blend Weight", &settings.AlphaStrength, 0.0f, 1.0f)) { | ||
| changed = true; | ||
| } | ||
| if (auto _tt = Util::HoverTooltipWrapper()) { | ||
| ImGui::Text("Control the blend weight of the effect applied to the final result."); | ||
| } | ||
|
|
||
| ImGui::Spacing(); | ||
| ImGui::Spacing(); | ||
| ImGui::TreePop(); | ||
| } | ||
| } | ||
|
|
||
| void ExtendedTranslucency::LoadSettings(json& o_json) | ||
| { | ||
| settings = o_json; | ||
| } | ||
|
|
||
| void ExtendedTranslucency::SaveSettings(json& o_json) | ||
| { | ||
| o_json = settings; | ||
| } | ||
|
|
||
| void ExtendedTranslucency::RestoreDefaultSettings() | ||
| { | ||
| settings = {}; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| #pragma once | ||
|
|
||
| #include "../Buffer.h" | ||
| #include "../Feature.h" | ||
|
|
||
| struct ExtendedTranslucency final : Feature | ||
| { | ||
| static ExtendedTranslucency* GetSingleton(); | ||
|
|
||
| virtual inline std::string GetName() override { return "Extended Translucency"; } | ||
| virtual inline std::string GetShortName() override { return "ExtendedTranslucency"; } | ||
| virtual inline std::string_view GetShaderDefineName() override { return "EXTENDED_TRANSLUCENCY"; } | ||
| virtual bool HasShaderDefine(RE::BSShader::Type shaderType) override { return RE::BSShader::Type::Lighting == shaderType; }; | ||
| virtual void PostPostLoad() override; | ||
| virtual void DrawSettings() override; | ||
| virtual void LoadSettings(json& o_json) override; | ||
| virtual void SaveSettings(json& o_json) override; | ||
| virtual void RestoreDefaultSettings() override; | ||
| virtual bool SupportsVR() override { return true; }; | ||
|
|
||
| // Future proof function for UI refactoring | ||
| std::string GetFeatureDescription() { return "Realistic rendering of thin fabric and other translucent materials"; } // Feature description for settings page | ||
| std::string GetFeatureModLink() { return "https://www.nexusmods.com/skyrimspecialedition/mods/150755"; } | ||
|
|
||
| static void BSLightingShader_SetupGeometry(RE::BSRenderPass* pass); | ||
|
|
||
| struct Hooks; | ||
|
|
||
| // TODO: Support more material model like glasses or arcylic | ||
| enum MaterialModel : uint32_t | ||
| { | ||
| Disabled = 0, // In ExtraFeatureDescriptor, this value means 'Default' instead of 'Disabled' | ||
| RimLight = 1, // Similar effect like rim light | ||
| IsotropicFabric = 2, // 1D fabric model, respect normal map | ||
| AnisotropicFabric = 3, // 2D fabric model alone tangent and binormal, ignores normal map | ||
| ForceDisabled = 7, // In ExtraFeatureDescriptor, value >= 4 means 'Disabled' | ||
| }; | ||
|
|
||
| static constexpr uint32_t ExtraFeatureDescriptorShift = 6; | ||
| static constexpr uint32_t ExtraFeatureDescriptorMask = 7; | ||
|
|
||
| struct alignas(16) MaterialParams | ||
| { | ||
| uint32_t AlphaMode = MaterialModel::AnisotropicFabric; | ||
| float AlphaReduction = 0.15f; | ||
| float AlphaSoftness = 0.f; | ||
| float AlphaStrength = 0.f; | ||
| }; | ||
|
|
||
| MaterialParams settings; | ||
|
|
||
| static const RE::BSFixedString NiExtraDataName_AnisotropicAlphaMaterial; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.