GPU优化
This commit is contained in:
@@ -59,8 +59,10 @@ Shader "SLS/Postprocessing/AnimeBloom"
|
||||
float2 uv = input.texcoord;
|
||||
float4 texelSize = _BlitTexture_TexelSize;
|
||||
|
||||
// 扩散偏移量,随 BlurRadius 调整
|
||||
float2 offset = texelSize.xy * _BlurRadius;
|
||||
// 原生的 Kawase Offset 是 1.0(即 0.5 个对角像素距离),
|
||||
// 这里加入 _BlurRadius 按比例扩大步幅,能够使用 3 次迭代跑出原版 6 次的扩散面积
|
||||
float spreadOffset = 1.0 + _BlurRadius * 0.5;
|
||||
float2 offset = texelSize.xy * spreadOffset;
|
||||
|
||||
half3 c0 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv - offset).rgb;
|
||||
half3 c1 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(offset.x, -offset.y)).rgb;
|
||||
@@ -71,26 +73,36 @@ Shader "SLS/Postprocessing/AnimeBloom"
|
||||
return half4(color, 1.0);
|
||||
}
|
||||
|
||||
// --- Pass 2: Upsample (Kawase 4-Tap + Blend) ---
|
||||
// 升采样:高质量混合。
|
||||
// 这里采用 Dual Kawase 的升采样逻辑,混合上一级纹理
|
||||
TEXTURE2D(_BloomMipDown);
|
||||
SAMPLER(sampler_BloomMipDown);
|
||||
|
||||
// --- Pass 2: Upsample (Kawase 4-Tap + Scatter) ---
|
||||
half4 FragUpsample(Varyings input) : SV_Target
|
||||
{
|
||||
float2 uv = input.texcoord;
|
||||
float4 texelSize = _BlitTexture_TexelSize;
|
||||
float2 offset = texelSize.xy * _BlurRadius * 0.5; // 升采样时半径减半,为了更平滑
|
||||
|
||||
// 原生的 Kawase 升采样偏移是 0.5。
|
||||
// 配合宽幅降采样,这里稍微放大一点点就可以获得非常柔顺的大面积泛光
|
||||
float spreadOffset = 0.5 + _BlurRadius * 0.2;
|
||||
float2 offset = texelSize.xy * spreadOffset;
|
||||
|
||||
// 4-Tap 采样高一级的纹理
|
||||
// 4-Tap 从更低分辨率纹理 (Up[i+1]) 采样外围光晕
|
||||
half3 c0 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv - offset * float2(1, 1)).rgb;
|
||||
half3 c1 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset * float2(1, -1)).rgb;
|
||||
half3 c2 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv - offset * float2(1, -1)).rgb;
|
||||
half3 c3 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset * float2(1, 1)).rgb;
|
||||
|
||||
half3 blur = (c0 + c1 + c2 + c3) * 0.25;
|
||||
half3 lowRes = (c0 + c1 + c2 + c3) * 0.25;
|
||||
|
||||
// 这一步在 C# 中是通过 Blit 叠加到上一级 RT 上的
|
||||
// 所以这里直接输出 blur 结果,混合模式设为 Add 即可
|
||||
return half4(blur, 1.0);
|
||||
// 采样当前层级的高清纹理 (Down[i])
|
||||
half3 highRes = SAMPLE_TEXTURE2D_X(_BloomMipDown, sampler_LinearClamp, uv).rgb;
|
||||
|
||||
// 【完全复刻 Unity 原生逻辑】: highRes + lowRes * scatter
|
||||
// 这既保证了光晕向外漫射(低迭代扩散广),又保证了核心亮区的能量守恒!
|
||||
float scatter = saturate(_BlurRadius);
|
||||
half3 bloom = highRes + lowRes * scatter;
|
||||
|
||||
return half4(bloom, 1.0);
|
||||
}
|
||||
|
||||
// --- Pass 3: Composite (最终合成) ---
|
||||
@@ -143,7 +155,7 @@ Shader "SLS/Postprocessing/AnimeBloom"
|
||||
Pass
|
||||
{
|
||||
Name "Bloom Upsample"
|
||||
Blend One One // Additive Blend for upsampling accumulation
|
||||
// 已在内部 Lerp,无需外部 Additive Blend
|
||||
HLSLPROGRAM
|
||||
#pragma vertex Vert
|
||||
#pragma fragment FragUpsample
|
||||
|
||||
@@ -8,9 +8,8 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Anime Bloom")]
|
||||
public class AnimeBloom : ScriptablePostProcessorVolume
|
||||
{
|
||||
// 放在 ToneMapping 之前效果最强,但放在 AfterPostProcess 最安全(不易过曝)
|
||||
// 这里建议 AfterPostProcess,配合 HDR 使用
|
||||
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
|
||||
// 【核心修改】:放在 ToneMapping 之前执行(BeforePostProcess),配合 ACES 才能彻底解决“高光泛白”问题
|
||||
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
|
||||
public override int OrderInInjectionPoint => 5; // 放在 Vignette 之前
|
||||
|
||||
[Header("Glow Settings")]
|
||||
@@ -27,11 +26,11 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
public MinFloatParameter clamp = new(65472f, 1f); // 默认很大,基本不限制
|
||||
|
||||
[Header("Anime Style")]
|
||||
[Tooltip("扩散半径。值越大,光晕越松散、范围越大(二次元感核心)。")]
|
||||
public ClampedFloatParameter scatter = new(0.7f, 0f, 5f); // 推荐 0.5 - 1.0
|
||||
[Tooltip("扩散半径。稍微增加扩展范围来弥补低迭代带来的发光不足。")]
|
||||
public ClampedFloatParameter scatter = new(0.85f, 0f, 5f); // 推荐增量以适应低迭代
|
||||
|
||||
[Tooltip("迭代次数。次数越多,光晕越平滑、范围越大,但性能开销越高。")]
|
||||
public ClampedIntParameter diffusion = new(6, 1, 8); // 6次通常足够高品质
|
||||
[Tooltip("迭代次数。针对移动端带宽优化,建议控制在 2~3 次。")]
|
||||
public ClampedIntParameter diffusion = new(3, 1, 4); // 移动端性能优化,最高4次
|
||||
|
||||
[Tooltip("泛光染色。可以做粉色霓虹、蓝色科技光等效果。")]
|
||||
public ColorParameter tint = new(Color.white, true, true, true);
|
||||
@@ -39,7 +38,7 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
// 内部使用的 RT 数组
|
||||
private RTHandle[] _bloomPyramidUp;
|
||||
private RTHandle[] _bloomPyramidDown;
|
||||
private const int k_MaxPyramidSize = 16;
|
||||
private const int k_MaxPyramidSize = 6; // 减少不必要的最大数组长度
|
||||
|
||||
public override string GetShaderName() => "SLS/Postprocessing/AnimeBloom";
|
||||
|
||||
@@ -104,13 +103,9 @@ namespace SLSUtilities.Rendering.PostProcessing
|
||||
// 设置上一级 Up 为输入
|
||||
// Upsample Pass 会混合:Up[i+1] (Blur) + Down[i] (High Res Detail)
|
||||
// 这里我们稍微简化逻辑:直接把 Up[i+1] 升采样并叠加到 Up[i] 上
|
||||
// 为了保留细节,Dual Kawase 通常是将 Up[i+1] 叠加回 Down[i] 存入 Up[i]
|
||||
|
||||
// 第一步:先把 Down[i] 拷进 Up[i] 作为底图
|
||||
Blitter.BlitCameraTexture(cmd, _bloomPyramidDown[i], _bloomPyramidUp[i]);
|
||||
|
||||
// 第二步:把 Up[i+1] 升采样并 Additive 混合进 Up[i]
|
||||
// Shader Pass 2 开启了 Blend One One
|
||||
// 第二步:把 Up[i+1] (LowRes) 和 Down[i] (HighRes) 一起传给 Shader
|
||||
// 在 Shader 内部执行 Lerp 能量守恒融合,彻底替代会导致死白的 Additive 叠加模式
|
||||
material.SetTexture("_BloomMipDown", _bloomPyramidDown[i]);
|
||||
Blitter.BlitCameraTexture(cmd, _bloomPyramidUp[i + 1], _bloomPyramidUp[i], material, 2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user