SHA256
Add High-Resolution Bloom Correction Option
This commit is contained in:
5 files changed
+90
No files matched your search
@@ -95,6 +95,13 @@ public class AdvancedConfig
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool NonTile { get; set; } = false;
|
public bool NonTile { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true, the game's bloom (<c>VideoBloom</c>) computes its blur size as if the frame were 720 pixels high, so the
|
||||||
|
/// blur passes on the 198-pixel-high bloom buffer are the same as in a 720p frame at any render height
|
||||||
|
/// (VideoBloomPatch). Default false.
|
||||||
|
/// </summary>
|
||||||
|
public bool HighResBloomCorrection { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>File extension of the default output file name, without the dot (e.g. "mkv", "mp4"); selects the container.</summary>
|
/// <summary>File extension of the default output file name, without the dot (e.g. "mkv", "mp4"); selects the container.</summary>
|
||||||
public string FileExtension { get; set; } = "mkv";
|
public string FileExtension { get; set; } = "mkv";
|
||||||
|
|
||||||
@@ -120,6 +127,7 @@ public class AdvancedConfig
|
|||||||
RandomSeed = source.RandomSeed;
|
RandomSeed = source.RandomSeed;
|
||||||
ProcessAudio = source.ProcessAudio;
|
ProcessAudio = source.ProcessAudio;
|
||||||
NonTile = source.NonTile;
|
NonTile = source.NonTile;
|
||||||
|
HighResBloomCorrection = source.HighResBloomCorrection;
|
||||||
FileExtension = source.FileExtension;
|
FileExtension = source.FileExtension;
|
||||||
firePlanetColor = source.firePlanetColor;
|
firePlanetColor = source.firePlanetColor;
|
||||||
icePlanetColor = source.icePlanetColor;
|
icePlanetColor = source.icePlanetColor;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
"ui.render_config.file_extension": "File Extension",
|
"ui.render_config.file_extension": "File Extension",
|
||||||
"ui.render_config.process_audio": "Process Audio",
|
"ui.render_config.process_audio": "Process Audio",
|
||||||
"ui.render_config.non_tile": "Non-Tile Mode",
|
"ui.render_config.non_tile": "Non-Tile Mode",
|
||||||
|
"ui.render_config.high_res_bloom_correction": "High-Resolution Bloom Correction",
|
||||||
"ui.render_config.random_seed": "Random Seed (Optional)",
|
"ui.render_config.random_seed": "Random Seed (Optional)",
|
||||||
"ui.render_config.validation_title": "Invalid Settings",
|
"ui.render_config.validation_title": "Invalid Settings",
|
||||||
"ui.render_config.validation_error": "Please check your input values:\n- Width and Height must be integers > 0\n- Render FPS and Video FPS must be > 0\n- Delay After End must be >= 0",
|
"ui.render_config.validation_error": "Please check your input values:\n- Width and Height must be integers > 0\n- Render FPS and Video FPS must be > 0\n- Delay After End must be >= 0",
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
"ui.render_config.file_extension": "파일 확장자",
|
"ui.render_config.file_extension": "파일 확장자",
|
||||||
"ui.render_config.process_audio": "오디오 처리",
|
"ui.render_config.process_audio": "오디오 처리",
|
||||||
"ui.render_config.non_tile": "논타일 모드",
|
"ui.render_config.non_tile": "논타일 모드",
|
||||||
|
"ui.render_config.high_res_bloom_correction": "고해상도 블룸 보정",
|
||||||
"ui.render_config.random_seed": "랜덤 시드 (선택 사항)",
|
"ui.render_config.random_seed": "랜덤 시드 (선택 사항)",
|
||||||
"ui.render_config.validation_title": "설정 오류",
|
"ui.render_config.validation_title": "설정 오류",
|
||||||
"ui.render_config.validation_error": "입력값을 확인해 주세요:\n- 너비와 높이는 0보다 큰 정수여야 합니다.\n- 렌더 FPS와 영상 FPS는 0보다 커야 합니다.\n- 종료 후 대기 시간은 0 이상이어야 합니다.",
|
"ui.render_config.validation_error": "입력값을 확인해 주세요:\n- 너비와 높이는 0보다 큰 정수여야 합니다.\n- 렌더 FPS와 영상 FPS는 0보다 커야 합니다.\n- 종료 후 대기 시간은 0 이상이어야 합니다.",
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using ADOFAIRenderer.Core;
|
||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ADOFAIRenderer.Patch.Game;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes the game's bloom compute its blur size as if the frame were 720 pixels high
|
||||||
|
/// ("High-Resolution Bloom Correction" option).
|
||||||
|
/// <para>
|
||||||
|
/// Patched member: <c>VideoBloom.OnRenderImage(RenderTexture source, RenderTexture destination)</c>. The game scales the
|
||||||
|
/// frame down to a bloom buffer 198 pixels high (<c>scale = 198 / source.height</c>) and sets the blur radius in bloom
|
||||||
|
/// buffer pixels to <c>KernelSize * MediumKernelScale * scale</c> (and <c>KernelSize * LargeKernelScale * scale</c>).
|
||||||
|
/// <c>BloomBlit</c> turns the radius into the number of 5-tap blur passes and the blend amount of the last pass.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// While the render is active (<see cref="RenderManager.IsActive"/>) and <c>AdvancedConfig.HighResBloomCorrection</c> is
|
||||||
|
/// enabled, the prefix multiplies <c>KernelSize</c> by <c>source.height / 720</c> for the duration of the call, so the
|
||||||
|
/// radius equals <c>KernelSize * MediumKernelScale * 198 / 720</c> and the blur passes on the bloom buffer are the same
|
||||||
|
/// as in a 720p frame. The finalizer restores the original <c>KernelSize</c>. The bloom buffer size and the downscale
|
||||||
|
/// from the source frame keep the game's behavior.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPatch(typeof(VideoBloom))]
|
||||||
|
public class VideoBloomPatch
|
||||||
|
{
|
||||||
|
/// <summary>Frame height in pixels the blur size is computed for.</summary>
|
||||||
|
private const float ReferenceHeight = 720f;
|
||||||
|
|
||||||
|
/// <summary>Prefix of <c>VideoBloom.OnRenderImage</c>.</summary>
|
||||||
|
/// <param name="__instance">The bloom component on the game camera.</param>
|
||||||
|
/// <param name="source">The camera frame; its height selects the multiplier.</param>
|
||||||
|
/// <param name="__state">Original <c>KernelSize</c>, or null when it was not changed.</param>
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch("OnRenderImage")]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public static void ScaleKernelSize(VideoBloom __instance, RenderTexture source, out float? __state)
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
{
|
||||||
|
__state = null;
|
||||||
|
if (!source || !RenderManager.IsActive || !RenderManager.Instance.Configuration.AdvancedConfig.HighResBloomCorrection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
__state = __instance.KernelSize;
|
||||||
|
__instance.KernelSize *= source.height / ReferenceHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Finalizer of <c>VideoBloom.OnRenderImage</c>: restores <c>KernelSize</c> when the prefix changed it.</summary>
|
||||||
|
/// <param name="__instance">The bloom component on the game camera.</param>
|
||||||
|
/// <param name="__state">Original <c>KernelSize</c> stored by the prefix, or null.</param>
|
||||||
|
[HarmonyFinalizer]
|
||||||
|
[HarmonyPatch("OnRenderImage")]
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
public static void RestoreKernelSize(VideoBloom __instance, float? __state)
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
{
|
||||||
|
if (__state.HasValue) __instance.KernelSize = __state.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -139,6 +139,7 @@ internal static class RenderConfigWindow
|
|||||||
private static O5InputField? _randomSeedInput;
|
private static O5InputField? _randomSeedInput;
|
||||||
private static O5Toggle? _processAudioToggle;
|
private static O5Toggle? _processAudioToggle;
|
||||||
private static O5Toggle? _nonTileToggle;
|
private static O5Toggle? _nonTileToggle;
|
||||||
|
private static O5Toggle? _highResBloomCorrectionToggle;
|
||||||
|
|
||||||
// Planet color overrides: the toggle enables the override, the picker holds the color. A disabled toggle stores
|
// Planet color overrides: the toggle enables the override, the picker holds the color. A disabled toggle stores
|
||||||
// null in AdvancedConfig (no override is applied by PersistencePatch) and blocks the picker.
|
// null in AdvancedConfig (no override is applied by PersistencePatch) and blocks the picker.
|
||||||
@@ -698,6 +699,7 @@ internal static class RenderConfigWindow
|
|||||||
// Section 6: Advanced Settings card (RenderConfig.AdvancedConfig)
|
// Section 6: Advanced Settings card (RenderConfig.AdvancedConfig)
|
||||||
// File Extension | Random Seed
|
// File Extension | Random Seed
|
||||||
// Process Audio | Non-Tile Mode
|
// Process Audio | Non-Tile Mode
|
||||||
|
// High-Resolution Bloom Correction |
|
||||||
// "Planet Colors" label, then three columns: Fire | Ice | Wind (toggle + color picker each)
|
// "Planet Colors" label, then three columns: Fire | Ice | Wind (toggle + color picker each)
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// 7. Advanced Settings (Collapsible Card)
|
// 7. Advanced Settings (Collapsible Card)
|
||||||
@@ -739,6 +741,23 @@ internal static class RenderConfigWindow
|
|||||||
generateLabel: false
|
generateLabel: false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// High-Resolution Bloom Correction (AdvancedConfig.HighResBloomCorrection): the game's bloom computes its blur
|
||||||
|
// size as if the frame were 720 pixels high (VideoBloomPatch)
|
||||||
|
_highResBloomCorrectionToggle = CreateToggleField(
|
||||||
|
ctx, CreateFieldSlot(advLeft),
|
||||||
|
labelKey: "",
|
||||||
|
defaultValue: false,
|
||||||
|
value: config.AdvancedConfig.HighResBloomCorrection,
|
||||||
|
toggleTextKey: "ui.render_config.high_res_bloom_correction",
|
||||||
|
id: "toggle_high_res_bloom_correction",
|
||||||
|
onChanged: val =>
|
||||||
|
{
|
||||||
|
config.AdvancedConfig.HighResBloomCorrection = val;
|
||||||
|
MarkConfigModified();
|
||||||
|
},
|
||||||
|
generateLabel: false
|
||||||
|
);
|
||||||
|
|
||||||
// Random Seed (AdvancedConfig.RandomSeed): integer passed to UnityEngine.Random.InitState before the game scene
|
// Random Seed (AdvancedConfig.RandomSeed): integer passed to UnityEngine.Random.InitState before the game scene
|
||||||
// loads; empty text stores null (no seeding). Text that is neither empty nor an integer keeps the previous value.
|
// loads; empty text stores null (no seeding). Text that is neither empty nor an integer keeps the previous value.
|
||||||
_randomSeedInput = CreateInputField(
|
_randomSeedInput = CreateInputField(
|
||||||
@@ -980,6 +999,7 @@ internal static class RenderConfigWindow
|
|||||||
_randomSeedInput?.Set(config.AdvancedConfig.RandomSeed?.ToString() ?? "", false);
|
_randomSeedInput?.Set(config.AdvancedConfig.RandomSeed?.ToString() ?? "", false);
|
||||||
_processAudioToggle?.Set(config.AdvancedConfig.ProcessAudio, false);
|
_processAudioToggle?.Set(config.AdvancedConfig.ProcessAudio, false);
|
||||||
_nonTileToggle?.Set(config.AdvancedConfig.NonTile, false);
|
_nonTileToggle?.Set(config.AdvancedConfig.NonTile, false);
|
||||||
|
_highResBloomCorrectionToggle?.Set(config.AdvancedConfig.HighResBloomCorrection, false);
|
||||||
|
|
||||||
// Planet colors: toggle on when an override is stored; the picker shows the stored color or the default and is
|
// Planet colors: toggle on when an override is stored; the picker shows the stored color or the default and is
|
||||||
// blocked without an override
|
// blocked without an override
|
||||||
@@ -1161,6 +1181,7 @@ internal static class RenderConfigWindow
|
|||||||
}
|
}
|
||||||
if (_processAudioToggle != null) target.AdvancedConfig.ProcessAudio = _processAudioToggle.Value;
|
if (_processAudioToggle != null) target.AdvancedConfig.ProcessAudio = _processAudioToggle.Value;
|
||||||
if (_nonTileToggle != null) target.AdvancedConfig.NonTile = _nonTileToggle.Value;
|
if (_nonTileToggle != null) target.AdvancedConfig.NonTile = _nonTileToggle.Value;
|
||||||
|
if (_highResBloomCorrectionToggle != null) target.AdvancedConfig.HighResBloomCorrection = _highResBloomCorrectionToggle.Value;
|
||||||
|
|
||||||
// Planet Colors
|
// Planet Colors
|
||||||
target.AdvancedConfig.firePlanetColor = (_firePlanetToggle?.Value == true && _firePlanetPicker != null)
|
target.AdvancedConfig.firePlanetColor = (_firePlanetToggle?.Value == true && _firePlanetPicker != null)
|
||||||
|
|||||||
Reference in new issue
Block a user