与编辑器同步,增加sync优化bloom,添加打包时自动打包主题包的特性
(怎么这么多meta文件啊) Signed-off-by: TRADER_FOER <lhf190@outlook.com>
This commit is contained in:
@@ -6,6 +6,22 @@ using UnityEngine.Experimental.Rendering;
|
||||
|
||||
namespace SLSUtilities.Rendering.PostProcessing
|
||||
{
|
||||
public enum AnimeBloomBlurMode
|
||||
{
|
||||
DualKawaseFast,
|
||||
DualKawaseQuality,
|
||||
Box
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public sealed class AnimeBloomBlurModeParameter : VolumeParameter<AnimeBloomBlurMode>
|
||||
{
|
||||
public AnimeBloomBlurModeParameter(AnimeBloomBlurMode value, bool overrideState = false)
|
||||
: base(value, overrideState)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Anime Bloom")]
|
||||
public class AnimeBloom : ScriptablePostProcessorVolume
|
||||
{
|
||||
@@ -31,14 +47,53 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
|
||||
[Header("Iterations")]
|
||||
// 迭代次数:Dual Kawase 每层只需 1 Pass,性能远低于原生双趟高斯。
|
||||
// 4 次迭代 Dual Kawase ≈ 原生 6 次双趟高斯的扩散范围,但 Pass 数只有其 1/3。
|
||||
// 现在主要作为质量 / pass budget 控制,视觉扩散范围由 bloomRadius 统一塑形。
|
||||
public ClampedIntParameter diffusion = new(4, 1, 8);
|
||||
|
||||
[Header("Optimization (Mobile)")]
|
||||
[Header("Radius")]
|
||||
[Tooltip("Bloom 视觉扩散半径。\n1.0=旧默认半径;调大可扩大光晕范围,调小可让光晕更贴近高亮区域。")]
|
||||
public ClampedFloatParameter bloomRadius = new(1.0f, 0.1f, 8.0f);
|
||||
|
||||
[Tooltip("当 diffusion 改变时,自动补偿采样跨度,尽量保持 Bloom Radius 的视觉范围稳定。\n关闭后 diffusion 会像传统 mip 金字塔一样明显改变光晕大小。")]
|
||||
public BoolParameter preserveRadiusAcrossDiffusion = new(true);
|
||||
|
||||
[Tooltip("半径补偿的参考 diffusion。\n默认 4 表示 bloomRadius=1 时以 4 层金字塔的旧效果作为基准。")]
|
||||
public ClampedIntParameter radiusReferenceDiffusion = new(4, 1, 8);
|
||||
|
||||
[Tooltip("自动半径补偿的最大倍率。\n低 diffusion 为了维持大半径会拉大采样跨度;该上限用于限制色块感、十字感和采样离散感。")]
|
||||
public ClampedFloatParameter maxRadiusCompensation = new(2.5f, 1.0f, 8.0f);
|
||||
|
||||
[Header("Blur Mode")]
|
||||
[Tooltip("模糊方式。\nDualKawaseFast=当前默认移动端低采样方案;DualKawaseQuality=更多采样、更平滑;Box=更便宜但质感更硬。")]
|
||||
public AnimeBloomBlurModeParameter blurMode = new(AnimeBloomBlurMode.DualKawaseFast);
|
||||
|
||||
[Header("Downsample Steps")]
|
||||
[Tooltip("初始降采样倍率(首趟大幅压缩分辨率)。\n1=原生半分辨率(1/2);2=1/4分辨率;3=1/8分辨率。\n调大此值可用极低的迭代次数跑出巨大且柔和的光晕,大幅节省 GPU 带宽。")]
|
||||
public ClampedIntParameter initialDownscaleShift = new(1, 1, 3);
|
||||
|
||||
[Tooltip("第 2 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep1 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 3 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep2 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 4 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep3 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 5 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep4 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 6 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep5 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 7 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep6 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("第 8 层相对上一层的降采样倍率。\n0=保持上一层分辨率只做模糊;1=1/2;2=1/4;3=1/8。")]
|
||||
public ClampedIntParameter downscaleStep7 = new(1, 0, 3);
|
||||
|
||||
[Tooltip("采样偏移跨度放大(Kernel Scale)。\n1.0=原生标准跨度。适度放大(如1.2-1.5)可拉扯光晕扩散范围,但过大会产生轻微十字星/方格马赛克。")]
|
||||
[Header("Kernel")]
|
||||
[Tooltip("采样偏移微调倍率。\n最终采样跨度 = bloomRadius * diffusion 自动补偿 * kernelScale。\n一般保持 1.0,用于针对具体画面做细调。")]
|
||||
public ClampedFloatParameter kernelScale = new(1.0f, 0.5f, 3.0f);
|
||||
|
||||
[Header("Tint")]
|
||||
@@ -64,7 +119,8 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
|
||||
// 【移动端极限优化】:强制降级到 32位 HDR 格式 (B10G11R11),
|
||||
// 相比主相机默认的 64位 R16G16B16A16,带宽消耗直接砍半,且肉眼几乎无损!
|
||||
if (SystemInfo.IsFormatSupported(GraphicsFormat.B10G11R11_UFloatPack32, GraphicsFormatUsage.Linear | GraphicsFormatUsage.Render))
|
||||
if (SystemInfo.IsFormatSupported(GraphicsFormat.B10G11R11_UFloatPack32,
|
||||
GraphicsFormatUsage.Linear | GraphicsFormatUsage.Render))
|
||||
{
|
||||
desc.graphicsFormat = GraphicsFormat.B10G11R11_UFloatPack32;
|
||||
}
|
||||
@@ -83,8 +139,6 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
material.SetVector(InternalShaderHelpers.ID._BloomScatterParams,
|
||||
new Vector4(scatterMapped, clamp.value, thresholdLinear, thresholdKnee));
|
||||
|
||||
material.SetFloat(InternalShaderHelpers.ID._AnimeBloom_KernelScale, kernelScale.value);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 2. Tint 归一化(原生做法:亮度归一为 1,只携带色相/饱和度)
|
||||
// 这样 tint 调整颜色时不会改变 bloom 总亮度。
|
||||
@@ -101,6 +155,7 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
// 3. RT 数组初始化
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
int mipCount = Mathf.Clamp(diffusion.value, 1, k_MaxMips);
|
||||
material.SetFloat(InternalShaderHelpers.ID._AnimeBloom_KernelScale, GetEffectiveKernelScale(mipCount));
|
||||
|
||||
if (_bloomMipDown == null || _bloomMipDown.Length != k_MaxMips)
|
||||
{
|
||||
@@ -112,7 +167,7 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
// 4. Prefilter(提取高亮像素 + 初始激进降采样)
|
||||
// 根据用户选择,起始分辨率可能是 1/2, 1/4 或 1/8。
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
int shift = initialDownscaleShift.value;
|
||||
int shift = GetDownscaleShiftForMip(0);
|
||||
desc.width = Mathf.Max(1, desc.width >> shift);
|
||||
desc.height = Mathf.Max(1, desc.height >> shift);
|
||||
|
||||
@@ -124,18 +179,20 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 5. Downsample Loop:Dual Kawase 降采样金字塔(Pass 1)
|
||||
// 每次分辨率减半,产生多层不同尺度的模糊纹理
|
||||
// 每层可单独设置相对上一层的降采样倍率,产生可手动塑形的模糊纹理
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
int downsamplePass = GetDownsamplePass();
|
||||
for (int i = 1; i < mipCount; i++)
|
||||
{
|
||||
desc.width = Mathf.Max(1, desc.width >> 1);
|
||||
desc.height = Mathf.Max(1, desc.height >> 1);
|
||||
shift = GetDownscaleShiftForMip(i);
|
||||
desc.width = Mathf.Max(1, desc.width >> shift);
|
||||
desc.height = Mathf.Max(1, desc.height >> shift);
|
||||
|
||||
RenderingUtils.ReAllocateHandleIfNeeded(ref _bloomMipDown[i], desc, FilterMode.Bilinear,
|
||||
TextureWrapMode.Clamp, name: "_BloomDown" + i);
|
||||
|
||||
// Down[i-1] → Down[i] via Pass 1 (Dual Kawase Downsample)
|
||||
Blitter.BlitCameraTexture(cmd, _bloomMipDown[i - 1], _bloomMipDown[i], material, 1);
|
||||
// Down[i-1] → Down[i] via selected downsample pass
|
||||
Blitter.BlitCameraTexture(cmd, _bloomMipDown[i - 1], _bloomMipDown[i], material, downsamplePass);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
@@ -163,12 +220,13 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
Blitter.BlitCameraTexture(cmd, _bloomMipDown[mipCount - 1], _bloomMipUp[mipCount - 1]);
|
||||
|
||||
// 从第二底层开始向上 upsample
|
||||
int upsamplePass = GetUpsamplePass();
|
||||
for (int i = mipCount - 2; i >= 0; i--)
|
||||
{
|
||||
// highMip:当前层降采样纹理 Down[i],作为 Blit 的 source(_BlitTexture)
|
||||
// lowMip: 上一级升采样结果 Up[i+1],通过 SetTexture 传入
|
||||
cmd.SetGlobalTexture(InternalShaderHelpers.ID._SourceTexLowMip, _bloomMipUp[i + 1]);
|
||||
Blitter.BlitCameraTexture(cmd, _bloomMipDown[i], _bloomMipUp[i], material, 2);
|
||||
Blitter.BlitCameraTexture(cmd, _bloomMipDown[i], _bloomMipUp[i], material, upsamplePass);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
@@ -178,6 +236,74 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
Blitter.BlitCameraTexture(cmd, source, destination, material, 3);
|
||||
}
|
||||
|
||||
private int GetDownscaleShiftForMip(int mipIndex)
|
||||
{
|
||||
return mipIndex switch
|
||||
{
|
||||
0 => initialDownscaleShift.value,
|
||||
1 => downscaleStep1.value,
|
||||
2 => downscaleStep2.value,
|
||||
3 => downscaleStep3.value,
|
||||
4 => downscaleStep4.value,
|
||||
5 => downscaleStep5.value,
|
||||
6 => downscaleStep6.value,
|
||||
7 => downscaleStep7.value,
|
||||
_ => 1
|
||||
};
|
||||
}
|
||||
|
||||
private float GetEffectiveKernelScale(int mipCount)
|
||||
{
|
||||
float compensation = preserveRadiusAcrossDiffusion.value
|
||||
? GetRadiusCompensation(mipCount)
|
||||
: 1f;
|
||||
|
||||
return Mathf.Max(0.01f, bloomRadius.value * kernelScale.value * compensation);
|
||||
}
|
||||
|
||||
private float GetRadiusCompensation(int mipCount)
|
||||
{
|
||||
float referenceSpread = GetPyramidSpread(Mathf.Clamp(radiusReferenceDiffusion.value, 1, k_MaxMips));
|
||||
float currentSpread = GetPyramidSpread(mipCount);
|
||||
float compensation = referenceSpread / Mathf.Max(1f, currentSpread);
|
||||
|
||||
return Mathf.Clamp(compensation, 1f / maxRadiusCompensation.value, maxRadiusCompensation.value);
|
||||
}
|
||||
|
||||
private float GetPyramidSpread(int mipCount)
|
||||
{
|
||||
int cumulativeShift = 0;
|
||||
float spread = 0f;
|
||||
|
||||
for (int i = 0; i < mipCount; i++)
|
||||
{
|
||||
cumulativeShift += GetDownscaleShiftForMip(i);
|
||||
spread += 1 << Mathf.Clamp(cumulativeShift, 0, 16);
|
||||
}
|
||||
|
||||
return Mathf.Max(1f, spread);
|
||||
}
|
||||
|
||||
private int GetDownsamplePass()
|
||||
{
|
||||
return blurMode.value switch
|
||||
{
|
||||
AnimeBloomBlurMode.DualKawaseQuality => 4,
|
||||
AnimeBloomBlurMode.Box => 5,
|
||||
_ => 1
|
||||
};
|
||||
}
|
||||
|
||||
private int GetUpsamplePass()
|
||||
{
|
||||
return blurMode.value switch
|
||||
{
|
||||
AnimeBloomBlurMode.DualKawaseQuality => 6,
|
||||
AnimeBloomBlurMode.Box => 7,
|
||||
_ => 2
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_bloomMipDown == null) return;
|
||||
|
||||
Reference in New Issue
Block a user