This commit is contained in:
SoulliesOfficial
2026-03-14 02:30:26 -04:00
parent cf86f0ee51
commit aee62cd637
2041 changed files with 246771 additions and 129128 deletions

View File

@@ -0,0 +1,86 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Advanced Chromatic Aberration")]
public class AdvancedChromaticAberration : ScriptablePostProcessorVolume
{
// 建议放在 PostProcess 之后,作为最终的镜头效果
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
public override int OrderInInjectionPoint => 20;
[Header("Main Settings")]
[Tooltip("色散总强度")]
public ClampedFloatParameter intensity = new(0f, 0f, 1f);
[Tooltip("扩散中心点 (0.5, 0.5 为屏幕中心)")]
public Vector2Parameter center = new(new Vector2(0.5f, 0.5f));
[Tooltip("RGB 分离权重。控制每个通道向外扩散的程度。\n例如 (1, 0, -1) 会让红蓝向相反方向分离,绿色不动。")]
public Vector3Parameter channelSplit = new(new Vector3(1f, 0f, -1f));
[Header("Dispersion Map (Broken Glass/Glitch)")]
[Tooltip("输入的噪波贴图,用于打乱色散的方向")]
public TextureParameter dispersionMap = new(null);
[Tooltip("贴图对色散方向的影响力")]
public ClampedFloatParameter dispersionStrength = new(0f, 0f, 2f);
[Header("Jitter (Temporal Instability)")]
[Tooltip("UV 采样抖动强度")]
public ClampedFloatParameter jitterIntensity = new(0f, 0f, 1f);
[Tooltip("抖动速度")]
public FloatParameter jitterSpeed = new(10f);
[Header("Masking")]
[Tooltip("中心保留清晰的半径 (0-1)")]
public ClampedFloatParameter maskRadius = new(0.2f, 0f, 1f);
[Tooltip("遮罩边缘的软硬度")]
public ClampedFloatParameter maskHardness = new(0.2f, 0.01f, 1f);
public override string GetShaderName() => "SLS/Postprocessing/AdvancedChromaticAberration";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
// Pack Params 1
Vector4 p1 = new Vector4(
intensity.value,
center.value.x,
center.value.y,
maskRadius.value
);
// Pack Params 2
Vector4 p2 = new Vector4(
jitterIntensity.value,
jitterSpeed.value,
dispersionStrength.value,
maskHardness.value
);
material.SetVector(InternalShaderHelpers.ID._ACA_Params1, p1);
material.SetVector(InternalShaderHelpers.ID._ACA_Params2, p2);
material.SetVector(InternalShaderHelpers.ID._ACA_Split, channelSplit.value);
if (dispersionMap.value != null)
{
material.SetTexture(InternalShaderHelpers.ID._DispersionMap, dispersionMap.value);
}
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
public override bool IsActive()
{
// 只要有强度,或者有抖动,就需要渲染
return intensity.value > 0f || jitterIntensity.value > 0f;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d692dfd6cc3001c4993ac48b98cf416c

View File

@@ -0,0 +1,63 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Advanced Vignette")]
public class AdvancedVignette : ScriptablePostProcessorVolume
{
// 放在最最后
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
public override int OrderInInjectionPoint => 100;
[Header("Gradient Colors")]
[Tooltip("外部颜色(边缘)。最暗的地方显示的颜色。")]
public ColorParameter colorOuter = new(Color.black, true, true, true);
[Tooltip("内部颜色(过渡区)。\n当暗角开始出现时显示的颜色。\n设为与外部相同则为单色暗角。\n设为红色可做受伤效果。")]
public ColorParameter colorInner = new(Color.black, true, true, true);
[Header("Shape Settings")]
[Tooltip("中心位置")]
public Vector2Parameter center = new(new Vector2(0.5f, 0.5f));
[Tooltip("强度。0 = 无效果")]
public ClampedFloatParameter intensity = new(0f, 0f, 1f);
[Tooltip("柔和度。控制渐变区域的宽度。")]
public ClampedFloatParameter smoothness = new(0.5f, 0.01f, 1f);
[Tooltip("圆度。1 = 圆形0 = 方形。")]
public ClampedFloatParameter roundness = new(1f, 0f, 1f);
public override string GetShaderName() => "SLS/Postprocessing/AdvancedVignette";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
material.SetColor(InternalShaderHelpers.ID._ColorInner, colorInner.value);
material.SetColor(InternalShaderHelpers.ID._ColorOuter, colorOuter.value);
material.SetVector(InternalShaderHelpers.ID._VignetteCenter, center.value);
// Pack Params
Vector3 p1 = new Vector3(
intensity.value,
smoothness.value,
roundness.value
);
material.SetVector(InternalShaderHelpers.ID._VignetteParams1, p1);
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
public override bool IsActive()
{
return intensity.value > 0f;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4b3eae192e53bb542bb66bee3b8ac936

View File

@@ -0,0 +1,59 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Anime ACES")]
public class AnimeACES : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
public override int OrderInInjectionPoint => 1000;
[Header("Tone Settings")]
[Tooltip("是否开启")]
public BoolParameter enabled = new(false);
[Tooltip("曝光度。如果画面太亮,请降低此值 (0.8 - 1.2)。")]
public FloatParameter exposure = new(1.0f); // 默认降回 1.0
[Tooltip("对比度。基于中灰(0.18)调整。值越高,黑的越黑,亮的越亮。")]
public ClampedFloatParameter contrast = new(1.1f, 0f, 2f);
[Tooltip("饱和度。建议 1.1 - 1.3 以获得鲜艳色彩。")]
public ClampedFloatParameter saturation = new(1.15f, 0f, 2f);
[Tooltip("色彩保留 (Hue Preservation)。\n0 = 标准ACES (皮肤泛白/胶片感)\n1 = 完美保色 (皮肤红润/卡通感)\n二次元建议 0.3 - 0.7。")]
public ClampedFloatParameter huePreservation = new(0.5f, 0f, 1f);
[Tooltip("色彩滤镜")]
public ColorParameter colorFilter = new(Color.white, true, true, true);
[Header("ACES Curve")]
public ClampedFloatParameter coeffA = new(2.51f, 0f, 5f);
public ClampedFloatParameter coeffB = new(0.03f, 0f, 1f);
public ClampedFloatParameter coeffC = new(2.43f, 0f, 5f);
public ClampedFloatParameter coeffD = new(0.59f, 0f, 1f);
public ClampedFloatParameter coeffE = new(0.14f, 0f, 1f);
public override string GetShaderName() => "SLS/Postprocessing/AnimeACES";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
// 传入 w 分量作为 Hue Preservation
material.SetVector(InternalShaderHelpers.ID._TonemapParams, new Vector4(exposure.value, contrast.value, saturation.value, huePreservation.value));
material.SetVector(InternalShaderHelpers.ID._ACESCoeffs, new Vector4(coeffA.value, coeffB.value, coeffC.value, coeffD.value));
material.SetFloat(InternalShaderHelpers.ID._ACES_E, coeffE.value);
material.SetColor(InternalShaderHelpers.ID._ColorFilter, colorFilter.value);
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
public override bool IsActive() => enabled.value;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5a892c0c0e4da4241b39a6d7e8ca14d3

View File

@@ -0,0 +1,140 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
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;
public override int OrderInInjectionPoint => 5; // 放在 Vignette 之前
[Header("Glow Settings")]
[Tooltip("泛光强度。值越大越亮。")]
public ClampedFloatParameter intensity = new(0f, 0f, 10f);
[Tooltip("阈值。亮度超过此值的像素才会发光。\n关键设为 1.1 可以过滤掉白墙(1.0),只让灯光发光。")]
public MinFloatParameter threshold = new(1.1f, 0f); // 默认设为 1.1
[Tooltip("柔膝 (Soft Knee)。让阈值过渡更平滑,避免高光边缘有硬切痕迹。")]
public ClampedFloatParameter softKnee = new(0.5f, 0f, 1f);
[Tooltip("最大亮度钳制。防止极亮像素(如太阳)产生乱跳的噪点。")]
public MinFloatParameter clamp = new(65472f, 1f); // 默认很大,基本不限制
[Header("Anime Style")]
[Tooltip("扩散半径。值越大,光晕越松散、范围越大(二次元感核心)。")]
public ClampedFloatParameter scatter = new(0.7f, 0f, 5f); // 推荐 0.5 - 1.0
[Tooltip("迭代次数。次数越多,光晕越平滑、范围越大,但性能开销越高。")]
public ClampedIntParameter diffusion = new(6, 1, 8); // 6次通常足够高品质
[Tooltip("泛光染色。可以做粉色霓虹、蓝色科技光等效果。")]
public ColorParameter tint = new(Color.white, true, true, true);
// 内部使用的 RT 数组
private RTHandle[] _bloomPyramidUp;
private RTHandle[] _bloomPyramidDown;
private const int k_MaxPyramidSize = 16;
public override string GetShaderName() => "SLS/Postprocessing/AnimeBloom";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
var desc = renderingData.cameraData.cameraTargetDescriptor;
desc.msaaSamples = 1;
desc.depthBufferBits = 0;
// 1. 设置参数
Vector4 bloomParams = new Vector4(intensity.value, threshold.value, softKnee.value, clamp.value);
material.SetVector(InternalShaderHelpers.ID._BloomParams, bloomParams);
material.SetVector(InternalShaderHelpers.ID._BloomTint, tint.value);
material.SetFloat(InternalShaderHelpers.ID._BlurRadius, scatter.value);
// 2. 初始化金字塔数组
int iterations = Mathf.Clamp(diffusion.value, 1, k_MaxPyramidSize);
// 确保 RT 数组大小足够
if (_bloomPyramidUp == null || _bloomPyramidUp.Length != k_MaxPyramidSize)
{
_bloomPyramidUp = new RTHandle[k_MaxPyramidSize];
_bloomPyramidDown = new RTHandle[k_MaxPyramidSize];
}
// 3. Prefilter Pass (提取高亮)
// 先降一半分辨率,节省性能且增加模糊感
desc.width = Mathf.Max(1, desc.width >> 1);
desc.height = Mathf.Max(1, desc.height >> 1);
RenderingUtils.ReAllocateIfNeeded(ref _bloomPyramidDown[0], desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_BloomMipDown0");
RenderingUtils.ReAllocateIfNeeded(ref _bloomPyramidUp[0], desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_BloomMipUp0");
// Source -> Down[0] (Prefilter)
Blitter.BlitCameraTexture(cmd, source, _bloomPyramidDown[0], material, 0);
// 4. Downsample Loop (降采样金字塔)
int lastDown = 0;
for (int i = 1; i < iterations; i++)
{
// 每次分辨率减半
desc.width = Mathf.Max(1, desc.width >> 1);
desc.height = Mathf.Max(1, desc.height >> 1);
RenderingUtils.ReAllocateIfNeeded(ref _bloomPyramidDown[i], desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_BloomMipDown" + i);
RenderingUtils.ReAllocateIfNeeded(ref _bloomPyramidUp[i], desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_BloomMipUp" + i);
// Down[i-1] -> Down[i]
Blitter.BlitCameraTexture(cmd, _bloomPyramidDown[i - 1], _bloomPyramidDown[i], material, 1);
lastDown = i;
}
// 5. Upsample Loop (升采样并混合)
// 从最小的一张开始,往上叠加
// 先把最小的 Down 直接拷给 Up
Blitter.BlitCameraTexture(cmd, _bloomPyramidDown[lastDown], _bloomPyramidUp[lastDown]);
for (int i = lastDown - 1; i >= 0; i--)
{
// 设置上一级 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
Blitter.BlitCameraTexture(cmd, _bloomPyramidUp[i + 1], _bloomPyramidUp[i], material, 2);
}
// 6. Composite (合成)
// 此时 _bloomPyramidUp[0] 包含了最终的泛光纹理
material.SetTexture(InternalShaderHelpers.ID._BloomTex, _bloomPyramidUp[0]);
// Source + BloomTex -> Destination
Blitter.BlitCameraTexture(cmd, source, destination, material, 3);
}
// 清理 RT
public void Dispose()
{
if (_bloomPyramidDown != null)
{
for (int i = 0; i < _bloomPyramidDown.Length; i++)
{
if (_bloomPyramidDown[i] != null) _bloomPyramidDown[i].Release();
if (_bloomPyramidUp[i] != null) _bloomPyramidUp[i].Release();
}
}
}
public override bool IsActive() => intensity.value > 0f;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bb4cc52ae13b01a44ab204c23af5263f

View File

@@ -0,0 +1,42 @@
using System;
using Echovoid.Runtime.Behavior.Rendering;
using SLSUtilities.Rendering.PostProcessing;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[Serializable, VolumeComponentMenu("SLS/Postprocessing/Pixelate")]
public class PixelateVolume : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
public override int OrderInInjectionPoint => 100;
[Tooltip("是否强制开启像素化效果")]
public BoolParameter forceActive = new BoolParameter(false);
public FloatParameter strengthX = new FloatParameter(1920f);
public FloatParameter strengthY = new FloatParameter(1080f);
// 返回我们在 Shader 里定义的名字,保证管家可以据此获取材质
public override string GetShaderName() => "Hidden/Custom/Pixelate";
public override bool IsActive()
{
// 当激活开关开启时才执行后期渲染(节省平时不开时的性能)
return forceActive.value;
}
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
cmd.SetGlobalFloat(InternalShaderHelpers.ID._PixelateStrengthX, strengthX.value);
cmd.SetGlobalFloat(InternalShaderHelpers.ID._PixelateStrengthY, strengthY.value);
// 使用你的统一管家分发的 Blitter 进行优雅渲染
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b25e6f237f6016f4191dd203dbfde0ee

View File

@@ -0,0 +1,36 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/RGBSplitGlitch")]
public class RGBSplitGlitch : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
public override int OrderInInjectionPoint => 0;
public ClampedFloatParameter intensity = new(0f, 0f, 1f);
public ClampedFloatParameter speed = new(10f, 0f, 100f);
public override string GetShaderName() => "SLS/Postprocessing/RGBSplitGlitch";
private float elapsedTime = 1.0f;
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
elapsedTime += Time.unscaledDeltaTime;
if (elapsedTime > 100)
{
elapsedTime = 0;
}
cmd.SetGlobalVector(InternalShaderHelpers.ID._RGBSplitGlitchParams,
new Vector4(intensity.value * 0.01f, Mathf.Floor(elapsedTime * speed.value)));
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
public override bool IsActive() => intensity.value > 0f;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 308c07db68b430d46b6d74d0847371b4

View File

@@ -0,0 +1,39 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
public enum RadialBlurQuality
{
RadialBlur_4Tap_Fatest = 0,
RadialBlur_8Tap_Balance = 1,
RadialBlur_12Tap = 2,
RadialBlur_16Tap_Quality = 3,
}
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Radial Blur")]
public class RadialBlur : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
public override int OrderInInjectionPoint => 10;
public EnumParameter<RadialBlurQuality> qualityLevel = new (RadialBlurQuality.RadialBlur_8Tap_Balance);
public ClampedFloatParameter blurRadius = new(0f, -1f, 1f);
public ClampedFloatParameter radialCenterX = new(0.5f, 0f, 1f);
public ClampedFloatParameter radialCenterY = new(0.5f, 0f, 1f);
public override string GetShaderName() => "SLS/Postprocessing/RadialBlur";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle target)
{
if (material == null) return;
cmd.SetGlobalVector(InternalShaderHelpers.ID._RadialBlurParams,
new Vector4(blurRadius.value * 0.02f, radialCenterX.value, radialCenterY.value));
Blitter.BlitCameraTexture(cmd, source, target, material, (int)qualityLevel.value);
}
public override bool IsActive() => !Mathf.Approximately(blurRadius.value, 0);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1f10b1f364acbb743804f8a970bce230

View File

@@ -0,0 +1,48 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Sharpen")]
public class Sharpen : ScriptablePostProcessorVolume
{
// 放在所有后处理之后,对最终画面进行锐化
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
// 排序靠后,确保是最后几步操作之一
public override int OrderInInjectionPoint => 10;
[Header("General Settings")]
[Tooltip("锐化强度。值越大画面越锋利。建议范围 0.5 - 2.0。过大会导致失真。")]
public ClampedFloatParameter sharpness = new(0f, 0f, 5f);
[Header("Optimizations (Visual Quality)")]
[Tooltip("对比度阈值(降噪)。\n只有当像素差异大于此值时才锐化。\n增加此值可避免平坦区域如天空、皮肤出现噪点。\n建议值0.01 - 0.05。")]
public ClampedFloatParameter threshold = new(0.01f, 0f, 0.2f);
[Tooltip("最大亮度钳制(防光晕)。\n限制像素亮度的最大变化幅度防止边缘出现刺眼的白边或黑边。\n减小此值可让锐化更自然。\n建议值0.1 - 0.3。")]
public ClampedFloatParameter clamp = new(0.2f, 0f, 1f);
public override string GetShaderName() => "SLS/Postprocessing/Sharpen";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
Vector4 paramsVec = new Vector4(
sharpness.value,
threshold.value,
clamp.value,
0 // unused
);
material.SetVector(InternalShaderHelpers.ID._SharpnessParams, paramsVec);
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
// 只有强度大于 0 时才激活
public override bool IsActive() => sharpness.value > 0f;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 148ba37ea406c934ea39cee8e2dd1108

View File

@@ -0,0 +1,49 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Speed Lines")]
public class SpeedLines : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
public override int OrderInInjectionPoint => 20;
[Header("Effect Color & Intensity")]
public ColorParameter color = new(new Color(1f, 1f, 1f, 0.5f), true, true, true);
[Header("Lines")]
public FloatParameter speedLinesTiling = new(200f);
public ClampedFloatParameter speedLinesRadialScale = new(0.1f, 0f, 10f);
public FloatParameter speedLinesPower = new(0f);
public ClampedFloatParameter speedLinesRemap = new(1f, 0f, 1f);
public FloatParameter speedLinesAnimation = new(3f);
[Header("Radial Mask")]
public ClampedFloatParameter maskScale = new(1f, 0f, 2f);
public ClampedFloatParameter maskHardness = new(0f, 0f, 1f);
public FloatParameter maskPower = new(5f);
public override string GetShaderName() => "SLS/Postprocessing/SpeedLines";
public override bool IsActive() => speedLinesRemap.value < 1f && color.value.a > 0f;
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle target)
{
if (material == null) return;
material.SetColor(InternalShaderHelpers.ID._SpeedLinesColour, color.value);
material.SetFloat(InternalShaderHelpers.ID._SpeedLinesTiling, speedLinesTiling.value);
material.SetFloat(InternalShaderHelpers.ID._SpeedLinesRadialScale, speedLinesRadialScale.value);
material.SetFloat(InternalShaderHelpers.ID._SpeedLinesPower, speedLinesPower.value);
material.SetFloat(InternalShaderHelpers.ID._SpeedLinesRemap, speedLinesRemap.value);
material.SetFloat(InternalShaderHelpers.ID._SpeedLinesAnimation, speedLinesAnimation.value);
material.SetFloat(InternalShaderHelpers.ID._MaskScale, maskScale.value);
material.SetFloat(InternalShaderHelpers.ID._MaskHardness, maskHardness.value);
material.SetFloat(InternalShaderHelpers.ID._MaskPower, maskPower.value);
Blitter.BlitCameraTexture(cmd, source, target, material, 0);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b67ae72a3d84887438324358c0932509

View File

@@ -0,0 +1,76 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSUtilities.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Strobe Flash")]
public class StrobeFlash : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
public override int OrderInInjectionPoint => 5;
[Header("Master Switch")]
public BoolParameter enableEffect = new(false);
[Header("Binary Colors")]
public ColorParameter colorHigh = new(Color.white);
public ColorParameter colorLow = new(Color.black);
[Header("Threshold & Flash")]
public ClampedFloatParameter grading = new(0.5f, 0f, 1f);
public BoolParameter autoFlash = new(false);
public FloatParameter frequency = new(15f);
public BoolParameter manualInvert = new(false);
[Header("Optimizations (Art Style)")]
[Tooltip("预模糊:消除地面的细碎噪点。")]
public ClampedFloatParameter noiseReduction = new(1.5f, 0f, 5f);
[Tooltip("柔化边缘:让黑白交界处不那么生硬。")]
public ClampedFloatParameter softness = new(0.05f, 0f, 0.5f);
[Header("Outline Settings")]
[Tooltip("描边粗细:建议值 1.0 - 2.0。如果太小可能看不见。")]
public ClampedFloatParameter outlineThickness = new(1f, 0f, 5f);
[Tooltip("描边敏感度阈值 (米):深度差超过此值才画线。\n解决地面全黑的关键参数\n建议值0.5 - 2.0。")]
public MinFloatParameter outlineThreshold = new(1.0f, 0f); // 默认设为 1米
[Tooltip("感光权重")]
public Vector3Parameter luminanceWeights = new(new Vector3(0.2126f, 0.7152f, 0.0722f));
public override string GetShaderName() => "SLS/Postprocessing/StrobeFlash";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle destination)
{
if (material == null) return;
material.SetColor(InternalShaderHelpers.ID._StrobeColorHigh, colorHigh.value);
material.SetColor(InternalShaderHelpers.ID._StrobeColorLow, colorLow.value);
material.SetVector(InternalShaderHelpers.ID._LuminanceWeights, new Vector4(luminanceWeights.value.x, luminanceWeights.value.y, luminanceWeights.value.z, 0));
Vector4 paramsVec = new Vector4(
frequency.value,
grading.value,
autoFlash.value ? 1f : 0f,
manualInvert.value ? 1f : 0f
);
material.SetVector(InternalShaderHelpers.ID._StrobeParams, paramsVec);
// 更新:传入 outlineThreshold (w分量)
Vector4 advParamsVec = new Vector4(
noiseReduction.value,
softness.value,
outlineThickness.value,
outlineThreshold.value
);
material.SetVector(InternalShaderHelpers.ID._StrobeAdvParams, advParamsVec);
Blitter.BlitCameraTexture(cmd, source, destination, material, 0);
}
public override bool IsActive() => enableEffect.value;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6a1f971f558014244b688b0d0a91e039