尝试进一步优化

This commit is contained in:
SoulliesOfficial
2026-06-30 05:43:26 -04:00
parent 8e4690c964
commit afa8a56e1d
21 changed files with 351 additions and 315 deletions

View File

@@ -38,25 +38,9 @@ Shader "SLS/Postprocessing/AnimeBloom"
SAMPLER(sampler_BloomTex);
// =====================================================
// HDR 编解码(与 Unity 原生 Bloom.shader 完全一致)
// 在线性工作流下 encode/decode 是 no-op但写清楚以防 gamma 空间项目
// 我们去除了 EncodeHDR / DecodeHDR因为我们在 BeforePostProcess 运行
// 且面向移动端,节省 ALU 开销,直接进行线性空间计算。
// =====================================================
half4 EncodeHDR(half3 color)
{
#if UNITY_COLORSPACE_GAMMA
color = sqrt(color);
#endif
return half4(color, 1.0);
}
half3 DecodeHDR(half4 data)
{
half3 color = data.xyz;
#if UNITY_COLORSPACE_GAMMA
color *= color;
#endif
return color;
}
// =====================================================
// Pass 0: Prefilter — 提取超过阈值的高亮像素
@@ -65,7 +49,7 @@ Shader "SLS/Postprocessing/AnimeBloom"
half4 FragPrefilter(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
half3 color = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv));
half3 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb;
// 1. 亮度钳制(防止极亮萤火虫像素跳变)
color = min(color, ClampMax);
@@ -77,10 +61,10 @@ Shader "SLS/Postprocessing/AnimeBloom"
half multiplier = max(brightness - Threshold, softness) / max(brightness, 1e-4);
color *= multiplier;
// 3. 防止 NaN 传播(负值在 EncodeHDR sqrt 时会产生 NaN
// 3. 防止 NaN 传播
color = max(color, 0);
return EncodeHDR(color);
return half4(color, 1.0);
}
// =====================================================
@@ -96,17 +80,17 @@ Shader "SLS/Postprocessing/AnimeBloom"
float2 ts = _BlitTexture_TexelSize.xy * _KernelScale;
// 中心点(权重 4
half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv));
half3 c0 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb;
// 4 个对角偏移各 0.5 像素(恰好落在 4 像素的双线性插值中心)
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, 0.5) * ts));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, 0.5) * ts));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, -0.5) * ts));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, -0.5) * ts));
// 4 个对角偏移
half3 c1 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, 0.5) * ts).rgb;
half3 c2 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, 0.5) * ts).rgb;
half3 c3 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, -0.5) * ts).rgb;
half3 c4 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, -0.5) * ts).rgb;
// 加权平均(c0*4 + c1+c2+c3+c4) / 8
// 加权平均
half3 color = (1.0 / 8.0) * (c0 * 4.0 + c1 + c2 + c3 + c4);
return EncodeHDR(color);
return half4(color, 1.0);
}
// =====================================================
@@ -124,32 +108,20 @@ Shader "SLS/Postprocessing/AnimeBloom"
half4 FragDualUpsample(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
// 同样乘以 _KernelScale
float2 ts = _BlitTexture_TexelSize.xy * _KernelScale;
// Dual Kawase 8-tap 升采样4 对角 + 4 正交
// 正交距离 = 1.0 texel对角距离 = 0.5 texel与原生完全一致
half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, 0.5) * ts));
half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, 0.5) * ts));
half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-0.5, -0.5) * ts));
half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.5, -0.5) * ts));
// 【移动端终极杀器】:剥离所有冗余采样!
// 从 9 采样(原生高端/老版)降低为 2 采样(原生移动端级别
// 凭借前面巨大的 Spread 范围,仅使用最基础的双线性过滤合并即可。
// 1. highMip = 当前层级的高清纹理
half3 highMip = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb;
half3 c5 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(-1.0, 0.0) * ts));
half3 c6 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 1.0, 0.0) * ts));
half3 c7 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.0, 1.0) * ts));
half3 c8 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2( 0.0, -1.0) * ts));
// 2. lowMip = 上一级的极致模糊光晕
half3 lowMip = SAMPLE_TEXTURE2D(_SourceTexLowMip, sampler_LinearClamp, uv).rgb;
// 加权平均 (4角×2 + 4正交×1) / 12产生柔和的钟形分布
half3 highMip = (1.0 / 12.0) * ((c1 + c2 + c3 + c4) * 2.0 + c5 + c6 + c7 + c8);
// lowMip = 来自更低分辨率层Up[i+1])的扩散光晕,双线性采样
half3 lowMip = DecodeHDR(SAMPLE_TEXTURE2D(_SourceTexLowMip, sampler_LinearClamp, uv));
// 【核心公式,与原生完全一致】
// Scatter 控制光晕扩散程度0=只有当前层细节1=完全使用模糊层
// 始终能量守恒,绝对不会产生死白
// 物理守恒 Lerp 合并
half3 result = lerp(highMip, lowMip, Scatter);
return EncodeHDR(result);
return half4(result, 1.0);
}
// =====================================================
@@ -164,8 +136,8 @@ Shader "SLS/Postprocessing/AnimeBloom"
// 原始 HDR 画面
half4 baseColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
// Bloom 纹理(已经过多轮 Dual Kawase 升降采样)
half3 bloom = DecodeHDR(SAMPLE_TEXTURE2D(_BloomTex, sampler_BloomTex, uv));
// Bloom 纹理
half3 bloom = SAMPLE_TEXTURE2D(_BloomTex, sampler_BloomTex, uv).rgb;
// 应用强度和染色_BloomParams.yzw 是亮度归一化的 tint
float intensity = _BloomParams.x;

View File

@@ -2,6 +2,7 @@ using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Experimental.Rendering;
namespace SLSUtilities.Rendering.PostProcessing
{
@@ -60,6 +61,13 @@ namespace SLSUtilities.Rendering.PostProcessing
var desc = renderingData.cameraData.cameraTargetDescriptor;
desc.msaaSamples = 1;
desc.depthBufferBits = 0;
// 【移动端极限优化】:强制降级到 32位 HDR 格式 (B10G11R11)
// 相比主相机默认的 64位 R16G16B16A16带宽消耗直接砍半且肉眼几乎无损
if (SystemInfo.IsFormatSupported(GraphicsFormat.B10G11R11_UFloatPack32, FormatUsage.Linear | FormatUsage.Render))
{
desc.graphicsFormat = GraphicsFormat.B10G11R11_UFloatPack32;
}
// ─────────────────────────────────────────────────────────────
// 1. 参数打包(完全对齐 Unity SetupBloom 的计算逻辑)