后处理+FEEL完全改进

This commit is contained in:
SoulliesOfficial
2025-12-22 18:36:29 -05:00
parent c3914da4ac
commit a2052bfe16
1427 changed files with 193092 additions and 374110 deletions

View File

@@ -5,10 +5,6 @@ namespace Echovoid.Runtime.Behavior.Rendering
{
public static class InternalShaderHelpers
{
public const string RGBSplitGlitchShader = "Hidden/Custom/RGBSplitGlitch";
public const string RadialBlurShader = "Hidden/Custom/RadialBlur";
public const string SpeedLinesShader = "Mirza/Anime Speed Lines";
public static Material GenerateTransientMaterial(string shaderName)
{
var shader = Shader.Find(shaderName);
@@ -28,8 +24,6 @@ namespace Echovoid.Runtime.Behavior.Rendering
public static readonly int _RadialCenterY = Shader.PropertyToID("_RadialCenterY");
// Speed Lines
// --- 新增的 Speed Lines ID ---
// 这些名字必须与原 Shader 属性和 HLSL 变量名完全一致
public static readonly int _SpeedLinesColour = Shader.PropertyToID("_Colour");
public static readonly int _SpeedLinesTiling = Shader.PropertyToID("_SpeedLinesTiling");
public static readonly int _SpeedLinesRadialScale = Shader.PropertyToID("_SpeedLinesRadialScale");
@@ -39,6 +33,28 @@ namespace Echovoid.Runtime.Behavior.Rendering
public static readonly int _MaskScale = Shader.PropertyToID("_MaskScale");
public static readonly int _MaskHardness = Shader.PropertyToID("_MaskHardness");
public static readonly int _MaskPower = Shader.PropertyToID("_MaskPower");
// --- Strobe Flash ---
public static readonly int _StrobeColorHigh = Shader.PropertyToID("_StrobeColorHigh");
public static readonly int _StrobeColorLow = Shader.PropertyToID("_StrobeColorLow");
public static readonly int _StrobeParams = Shader.PropertyToID("_StrobeParams");
public static readonly int _StrobeAdvParams = Shader.PropertyToID("_StrobeAdvParams");
public static readonly int _LuminanceWeights = Shader.PropertyToID("_LuminanceWeights");
// --- Sharpen ---
public static readonly int _SharpnessParams = Shader.PropertyToID("_SharpnessParams");
// --- Advanced Chromatic Aberration ---
public static readonly int _ACA_Params1 = Shader.PropertyToID("_ACA_Params1");
public static readonly int _ACA_Params2 = Shader.PropertyToID("_ACA_Params2");
public static readonly int _ACA_Split = Shader.PropertyToID("_ACA_Split");
public static readonly int _DispersionMap = Shader.PropertyToID("_DispersionMap");
// --- Advanced Vignette ---
public static readonly int _ColorInner = Shader.PropertyToID("_ColorInner");
public static readonly int _ColorOuter = Shader.PropertyToID("_ColorOuter");
public static readonly int _VignetteParams1 = Shader.PropertyToID("_VignetteParams1");
public static readonly int _VignetteCenter = Shader.PropertyToID("_VignetteCenter");
}
}
}

View File

@@ -18,10 +18,9 @@ namespace SLSFramework.Rendering.PostProcessing
var stack = VolumeManager.instance.stack;
postProcessorVolumes = VolumeManager.instance.baseComponentTypeArray
.Where(t => t.IsSubclassOf(
typeof(ScriptablePostProcessorVolume)))
.Select(t => stack.GetComponent(t) as ScriptablePostProcessorVolume)
.ToList();
.Where(t => t.IsSubclassOf(typeof(ScriptablePostProcessorVolume)))
.Select(t => stack.GetComponent(t) as ScriptablePostProcessorVolume)
.ToList();
var afterTransparentPostProcessors = postProcessorVolumes
.Where(c => c.InjectionPoint == CustomPostProcessInjectionPoint.AfterTransparent)
@@ -53,24 +52,27 @@ namespace SLSFramework.Rendering.PostProcessing
renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing
};
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
// 只有在相机开启后处理时才执行
if (renderingData.cameraData.postProcessEnabled)
{
if (afterTransparentPass.Setup())
// 关键点:将 renderingData 传递给 Pass 的 Setup 方法
// 这样我们就能把数据缓存下来给 RenderGraph 使用了
if (afterTransparentPass.Setup(ref renderingData))
{
afterTransparentPass.ConfigureInput(ScriptableRenderPassInput.Color);
renderer.EnqueuePass(afterTransparentPass);
}
if (beforePostProcessPass.Setup())
if (beforePostProcessPass.Setup(ref renderingData))
{
beforePostProcessPass.ConfigureInput(ScriptableRenderPassInput.Color);
renderer.EnqueuePass(beforePostProcessPass);
}
if (afterPostProcessPass.Setup())
if (afterPostProcessPass.Setup(ref renderingData))
{
afterPostProcessPass.ConfigureInput(ScriptableRenderPassInput.Color);
renderer.EnqueuePass(afterPostProcessPass);
@@ -90,11 +92,9 @@ namespace SLSFramework.Rendering.PostProcessing
item.Dispose();
}
}
afterTransparentPass.Dispose();
afterTransparentPass = null;
beforePostProcessPass.Dispose();
beforePostProcessPass = null;
afterPostProcessPass.Dispose();
afterPostProcessPass = null;
}
}

View File

@@ -0,0 +1,146 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.Universal;
namespace SLSFramework.Rendering.PostProcessing
{
public class ScriptablePostProcessorPass : ScriptableRenderPass
{
private List<ScriptablePostProcessorVolume> postProcessors;
private List<int> activePostProcessorIndex;
private string profilerTag;
private List<ProfilingSampler> profilingSamplers;
public ScriptablePostProcessorPass(string profilerTag, List<ScriptablePostProcessorVolume> postProcessors)
{
this.profilerTag = profilerTag;
this.postProcessors = postProcessors;
activePostProcessorIndex = new List<int>(postProcessors.Count);
profilingSamplers = postProcessors.Select(c => new ProfilingSampler(c.ToString())).ToList();
}
private RenderingData m_RenderingData;
private class PassData
{
public TextureHandle SourceTexture;
public TextureHandle TargetTexture;
public TextureHandle TempTextureA;
public TextureHandle TempTextureB;
public List<int> ActiveIndices;
public List<ScriptablePostProcessorVolume> Volumes;
public List<ProfilingSampler> Profilers;
public RenderingData RenderingData; // 数据结构保持不变
}
// 修改 Setup接收 RenderingData 并保存
// 注意:这里的 Setup 需要在 AddRenderPasses 中调用
public bool Setup(ref RenderingData renderingData)
{
this.m_RenderingData = renderingData; // 捕获数据
activePostProcessorIndex.Clear();
for (int i = 0; i < postProcessors.Count; i++)
{
postProcessors[i].Setup();
if (postProcessors[i].IsActive())
{
activePostProcessorIndex.Add(i);
}
}
return activePostProcessorIndex.Count != 0;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
var resourceData = frameData.Get<UniversalResourceData>();
var cameraData = frameData.Get<UniversalCameraData>();
// 如果没有激活的后处理,直接跳过
if (activePostProcessorIndex.Count == 0) return;
// 1. 获取相机的基础描述符 (这是旧的 RenderTextureDescriptor)
var cameraDesc = cameraData.cameraTargetDescriptor;
// 2. 【核心修正】创建一个新的 RenderGraph 专用描述符 (TextureDesc)
// 只有 TextureDesc 才能设置 name也不能直接把 cameraDesc 强转过去,必须手动赋值
var rgDesc = new TextureDesc(cameraDesc.width, cameraDesc.height);
rgDesc.colorFormat = cameraDesc.graphicsFormat;
rgDesc.depthBufferBits = DepthBits.None; // 后处理不需要深度
rgDesc.msaaSamples = MSAASamples.None; // 后处理通常不需要 MSAA
using (var builder = renderGraph.AddUnsafePass<PassData>(profilerTag, out var passData))
{
// 填充数据
passData.SourceTexture = resourceData.activeColorTexture;
passData.TargetTexture = resourceData.activeColorTexture;
passData.ActiveIndices = activePostProcessorIndex;
passData.Volumes = postProcessors;
passData.Profilers = profilingSamplers;
// 使用我们在 Setup 中缓存的旧版数据 (解决 UniversalRenderingData 找不到的问题)
passData.RenderingData = m_RenderingData;
// 3. 【核心修正】设置名字并创建纹理
// 这里使用的是 rgDesc (TextureDesc 类型),它有 name 属性
rgDesc.name = "_TemporaryRenderTextureA";
passData.TempTextureA = renderGraph.CreateTexture(rgDesc);
rgDesc.name = "_TemporaryRenderTextureB";
passData.TempTextureB = renderGraph.CreateTexture(rgDesc);
// 声明依赖关系 (保持不变)
builder.UseTexture(passData.SourceTexture, AccessFlags.Read);
builder.UseTexture(passData.TempTextureA, AccessFlags.ReadWrite);
builder.UseTexture(passData.TempTextureB, AccessFlags.ReadWrite);
builder.UseTexture(passData.TargetTexture, AccessFlags.ReadWrite);
// 设置执行逻辑 (保持不变)
builder.SetRenderFunc((PassData data, UnsafeGraphContext context) =>
{
var cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd);
var source = data.SourceTexture;
var target = data.TargetTexture;
var tempA = data.TempTextureA;
var tempB = data.TempTextureB;
if (data.ActiveIndices.Count == 1)
{
int index = data.ActiveIndices[0];
using (new ProfilingScope(cmd, data.Profilers[index]))
{
data.Volumes[index].Render(cmd, ref data.RenderingData, source, tempA);
}
Blitter.BlitCameraTexture(cmd, tempA, target);
}
else
{
Blitter.BlitCameraTexture(cmd, source, tempA);
var currSource = tempA;
var currDest = tempB;
foreach (int index in data.ActiveIndices)
{
var postProcessor = data.Volumes[index];
using (new ProfilingScope(cmd, data.Profilers[index]))
{
postProcessor.Render(cmd, ref data.RenderingData, currSource, currDest);
}
CoreUtils.Swap(ref currSource, ref currDest);
}
Blitter.BlitCameraTexture(cmd, currSource, target);
}
});
}
}
}
}

View File

@@ -1,101 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSFramework.Rendering.PostProcessing
{
public class ScriptablePostProcessorPass : ScriptableRenderPass
{
private List<ScriptablePostProcessorVolume> postProcessors;
private List<int> activePostProcessorIndex;
private string profilerTag;
private List<ProfilingSampler> profilingSamplers;
private RTHandle sourceRT;
private RTHandle targetRT;
private RTHandle tempRTA;
private RTHandle tempRTB;
private const string tempRTAName = "_TemporaryRenderTextureA";
private const string tempRTBName = "_TemporaryRenderTextureB";
public ScriptablePostProcessorPass(string profilerTag, List<ScriptablePostProcessorVolume> postProcessors)
{
this.profilerTag = profilerTag;
this.postProcessors = postProcessors;
activePostProcessorIndex = new List<int>(postProcessors.Count);
profilingSamplers = postProcessors.Select(c => new ProfilingSampler(c.ToString())).ToList();
tempRTA = RTHandles.Alloc(tempRTAName, name: tempRTAName);
tempRTB = RTHandles.Alloc(tempRTBName, name: tempRTBName);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
var cmd = CommandBufferPool.Get(profilerTag);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
var descriptor = renderingData.cameraData.cameraTargetDescriptor;
descriptor.msaaSamples = 1;
descriptor.depthBufferBits = 0;
targetRT = renderingData.cameraData.renderer.cameraColorTargetHandle;
sourceRT = renderingData.cameraData.renderer.cameraColorTargetHandle;
RenderingUtils.ReAllocateIfNeeded(ref tempRTA, descriptor, name: tempRTAName);
if (activePostProcessorIndex.Count == 1)
{
int index = activePostProcessorIndex[0];
using (new ProfilingScope(cmd, profilingSamplers[index]))
{
postProcessors[index].Render(cmd, ref renderingData, sourceRT, tempRTA);
}
}
else
{
RenderingUtils.ReAllocateIfNeeded(ref tempRTB, descriptor, name: tempRTBName);
Blitter.BlitCameraTexture(cmd, sourceRT, tempRTA);
foreach (int index in activePostProcessorIndex)
{
var postProcessor = postProcessors[index];
using (new ProfilingScope(cmd, profilingSamplers[index]))
{
postProcessor.Render(cmd, ref renderingData, tempRTA, tempRTB);
}
CoreUtils.Swap(ref tempRTA, ref tempRTB);
}
}
Blitter.BlitCameraTexture(cmd, tempRTA, targetRT);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public void Dispose()
{
if (tempRTA != null) RTHandles.Release(tempRTA);
if (tempRTB != null) RTHandles.Release(tempRTB);
}
public bool Setup()
{
activePostProcessorIndex.Clear();
for (int i = 0; i < postProcessors.Count; i++)
{
postProcessors[i].Setup();
if (postProcessors[i].IsActive())
{
activePostProcessorIndex.Add(i);
}
}
return activePostProcessorIndex.Count != 0;
}
}
}

View File

@@ -1,404 +0,0 @@
#ifndef ECHOVOID_POSTPROCESSING_PASS
#define ECHOVOID_POSTPROCESSING_PASS
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
TEXTURE2D_X(_CameraOpaqueTexture);
SAMPLER(sampler_CameraOpaqueTexture);
// PostProcessor - RGB Split Glitch Pass || BEGIN ------
float4 _RGBSplitGlitchParams;
#define _RGBSplitGlitchIntensity _RGBSplitGlitchParams.x
#define _TimeX _RGBSplitGlitchParams.y
float randomNoise(float x, float y)
{
return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
}
float4 RGBSplitGlitchPassFragment(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float splitAmount = _RGBSplitGlitchIntensity * randomNoise(_TimeX, 2);
half4 colorR = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, input.texcoord);
half4 colorG = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp,
float2(input.texcoord.x + splitAmount, input.texcoord.y + splitAmount));
half4 colorB = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp,
float2(input.texcoord.x - splitAmount, input.texcoord.y - splitAmount));
return half4(colorR.r, colorG.g, colorB.b, 1);
}
// PostProcessor - RGB Split Glitch Pass || END ------
// PostProcessor - RGB Split Glitch Pass || BEGIN ------
float4 _RadialBlurParams;
#define _BlurRadius _RadialBlurParams.x
#define _RadialCenter _RadialBlurParams.yz
half4 RadialBlurPassFragment_4Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 2 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 3 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
color *= 0.25f; // 1/4
return color;
}
half4 RadialBlurPassFragment_8Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 2 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 3 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 4 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 5 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 6 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 7 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
color *= 0.125f; // 1/8
return color;
}
half4 RadialBlurPassFragment_12Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 2 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 3 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 4 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 5 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 6 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 7 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 8 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 9 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 10 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 11 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
color *= 0.0833f; // 1/12
return color;
}
half4 RadialBlurPassFragment_20Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 2 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 3 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 4 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 5 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 6 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 7 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 8 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 9 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 10 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 11 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 12 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 13 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 14 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 15 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 16 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 17 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 18 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 19 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
color *= 0.05f; // 1/20
return color;
}
half4 RadialBlurPassFragment_30Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 2 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 3 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 4 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 5 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 6 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 7 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 8 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 9 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 10 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 11 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 12 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 13 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 14 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 15 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 16 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 17 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 18 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 19 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 20 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 21 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 22 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 23 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 24 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 25 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 26 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 27 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 28 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
scale = 29 * _BlurRadius + 1; //1 MAD
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter); //1 MAD
color *= 0.0333f; // 1/30
return color;
}
// PostProcessor - RGB Split Glitch Pass || END ------
// PostProcessor - Anime Speed Lines || BEGIN ------
float4 _Colour;
float _SpeedLinesTiling;
float _SpeedLinesRadialScale;
float _SpeedLinesPower;
float _SpeedLinesRemap;
float _SpeedLinesAnimation;
float _MaskScale;
float _MaskHardness;
float _MaskPower;
// 2. 移植原 Shader 中的 snoise (Simplex Noise) 函数
// (这段代码从原 shader 中原封不动地复制过来)
float3 mod2D289( float3 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }
float2 mod2D289( float2 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }
float3 permute( float3 x ) { return mod2D289( ( ( x * 34.0 ) + 1.0 ) * x ); }
float snoise( float2 v )
{
const float4 C = float4( 0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439 );
float2 i = floor( v + dot( v, C.yy ) );
float2 x0 = v - i + dot( i, C.xx );
float2 i1 = ( x0.x > x0.y ) ? float2( 1.0, 0.0 ) : float2( 0.0, 1.0 );
float4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod2D289( i );
float3 p = permute( permute( i.y + float3( 0.0, i1.y, 1.0 ) ) + i.x + float3( 0.0, i1.x, 1.0 ) );
float3 m = max( 0.5 - float3( dot( x0, x0 ), dot( x12.xy, x12.xy ), dot( x12.zw, x12.zw ) ), 0.0 );
m = m * m; m = m * m;
float3 x = 2.0 * frac( p * C.www ) - 1.0; float3 h = abs( x ) - 0.5;
float3 ox = floor( x + 0.5 ); float3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * ( a0 * a0 + h * h );
float3 g;
g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot( m, g );
}
// 3. 移植原 Shader 的 frag 函数逻辑
half4 SpeedLinesPassFragment(Varyings input) : SV_Target
{
// input.texcoord 是 URP 框架提供的正确 UV 坐标
half2 uv = input.texcoord;
// [cite: 26] 用 URP 的方式采样屏幕纹理(原图)
half4 SceneColour7 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
// --- 下面是原 frag 函数 [cite: 27-34] 的核心逻辑,几乎是 1:1 复制 ---
// [cite: 27] 计算中心 UV
float2 CenteredUV15_g1 = ( uv - float2( 0.5,0.5 ) );
float2 break17_g1 = CenteredUV15_g1;
// [cite: 27] 转换为极坐标(长度和角度)并应用 Tiling
float2 appendResult23_g1 = (float2(( length( CenteredUV15_g1 ) * _SpeedLinesRadialScale * 2.0 ) , ( atan2( break17_g1.x , break17_g1.y ) * ( 1.0 / 6.28318548202515 ) * _SpeedLinesTiling )));
// [cite: 28] 应用时间动画
// _Time.y 是 Unity 内置的 Shader 变量,可以直接使用
float2 appendResult58 = (float2(( -_SpeedLinesAnimation * _Time.y ) , 0.0));
// [cite: 28, 29] 采样 Simplex Noise
float simplePerlin2D10 = snoise( ( appendResult23_g1 + appendResult58 ) );
simplePerlin2D10 = simplePerlin2D10*0.5 + 0.5; // 重新映射到 0-1
// [cite: 29] 应用 Power 和 Remap生成线条
float temp_output_1_0_g6 = _SpeedLinesRemap;
float SpeedLines21 = saturate( ( ( pow( simplePerlin2D10 , _SpeedLinesPower ) - temp_output_1_0_g6 ) / ( 1.0 - temp_output_1_0_g6 ) ) );
// [cite: 30, 31] 计算中心径向遮罩
float2 texCoord60 = uv * float2( 2,2 ) + float2( -1,-1 );
float temp_output_1_0_g5 = _MaskScale;
float lerpResult71 = lerp( 0.0 , _MaskScale , _MaskHardness);
float Mask24 = pow( ( 1.0 - saturate( ( ( length( texCoord60 ) - temp_output_1_0_g5 ) / ( ( lerpResult71 - 0.001 ) - temp_output_1_0_g5 ) ) ) ) , _MaskPower );
// [cite: 32] 组合线条和遮罩
float MaskedSpeedLines29 = ( SpeedLines21 * Mask24 );
// [cite: 33] 获取颜色
float3 ColourRGB38 = (_Colour).rgb;
float ColourA40 = _Colour.a; // Alpha 用作混合强度
// [cite: 33] 创建速度线颜色
float4 speedLineColor = float4( ( MaskedSpeedLines29 * ColourRGB38 ) , SceneColour7.a );
// [cite: 34] 最终混合:(原图, 速度线, 混合量)
// 混合量 = 线条 * 遮罩 * 颜色Alpha
float4 lerpResult2 = lerp( SceneColour7 , speedLineColor , ( MaskedSpeedLines29 * ColourA40 ));
return lerpResult2;
}
// PostProcessor - Anime Speed Lines || END ------
#endif // ECHOVOID_POSTPROCESSING_PASS (确保这是你文件的最后一行)

View File

@@ -1,26 +0,0 @@
Shader "Hidden/Custom/RGBSplitGlitch"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "PostProcessingPass.hlsl"
ENDHLSL
Pass
{
Name " RGB Split Glitch"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RGBSplitGlitchPassFragment
ENDHLSL
}
}
}

View File

@@ -1,62 +0,0 @@
Shader "Hidden/Custom/RadialBlur"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "PostProcessingPass.hlsl"
ENDHLSL
Pass
{
Name " Radial Blur 4 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_4Tap
ENDHLSL
}
Pass
{
Name " Radial Blur 8 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_8Tap
ENDHLSL
}
Pass
{
Name " Radial Blur 12 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_12Tap
ENDHLSL
}
Pass
{
Name " Radial Blur 20 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_20Tap
ENDHLSL
}
Pass
{
Name " Radial Blur 30 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_30Tap
ENDHLSL
}
}
}

View File

@@ -1,6 +1,7 @@
fileFormatVersion: 2
guid: e88f673b667316245b29b8ee5ae80ae9
ShaderIncludeImporter:
guid: f9d89e0aea11e6947bb9f9c65db23e43
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@@ -0,0 +1,122 @@
Shader "SLS/Postprocessing/AdvancedChromaticAberration"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// --- 参数定义 ---
float4 _ACA_Params1;
// x: Intensity (总强度)
// y: Center X
// z: Center Y
// w: Mask Radius (中心保留半径)
float4 _ACA_Params2;
// x: Jitter Intensity
// y: Jitter Speed
// z: Dispersion Map Strength (贴图影响力度)
// w: Mask Hardness (边缘硬度)
float4 _ACA_Split; // x: R权重, y: G权重, z: B权重
// 纹理
TEXTURE2D(_DispersionMap);
SAMPLER(sampler_DispersionMap); // 建议设置为 Repeat 模式
// --- 辅助函数 ---
// 简单的伪随机函数 (0-1)
float random(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453123);
}
half4 Frag(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
// 1. 参数解包
float intensity = _ACA_Params1.x;
float2 center = _ACA_Params1.yz;
float maskRadius = _ACA_Params1.w;
float jitterAmount = _ACA_Params2.x;
float jitterSpeed = _ACA_Params2.y;
float mapStrength = _ACA_Params2.z;
float maskHardness = _ACA_Params2.w;
float3 splitWeights = _ACA_Split.rgb;
// 2. 计算基础方向向量 (径向)
float2 dir = uv - center;
float dist = length(dir);
// 3. 计算中心遮罩 (Vignette Mask)
// 距离小于 Radius 的地方强度为 0向外渐变
float mask = smoothstep(maskRadius, maskRadius + maskHardness, dist);
// 如果在遮罩内,直接返回原图,节省性能
// (为了 Jitter 的连贯性,这里我们只把 mask 乘到 offset 上,不直接 return)
// 4. 计算 Jitter (采样抖动)
// 利用 Time 和 UV 做随机,模拟不稳定的信号
float timeVal = _Time.y * jitterSpeed;
// 这里的 floor 模拟“跳动”的帧率感,如果想要平滑 jitter 可以去掉 floor
float2 jitterUV = uv + float2(random(uv + timeVal), random(uv - timeVal)) * 0.1;
float2 jitterOffset = (float2(random(jitterUV), random(jitterUV * 1.5)) - 0.5) * 2.0; // -1 ~ 1
jitterOffset *= jitterAmount * 0.05; // 缩放幅度
// 5. 采样 Dispersion Map (破碎感)
// 让贴图随时间缓慢流动一点点,或者固定
float4 noiseTex = SAMPLE_TEXTURE2D(_DispersionMap, sampler_DispersionMap, uv * 3.0 + jitterOffset); // 缩放 UV
float noiseFactor = noiseTex.r * 2.0 - 1.0; // -1 ~ 1
// 混合 Map 影响
// 如果 mapStrength 为 0则 noiseFactor 为 0 (不影响),我们希望默认为 1
float finalNoise = lerp(1.0, noiseFactor, mapStrength);
// 6. 组合最终偏移量
// 基础方向 * (1 + 噪声) + 抖动
float2 finalOffset = dir * finalNoise;
// 加上纯粹的位置抖动 (不依赖方向)
finalOffset += jitterOffset;
// 应用遮罩和总强度
finalOffset *= mask * intensity;
// 7. 分离通道采样
// 注意URP 的 _BlitTexture 采样时最好 Clamp防止边缘溢出
float2 uvR = uv - finalOffset * splitWeights.r;
float2 uvG = uv - finalOffset * splitWeights.g;
float2 uvB = uv - finalOffset * splitWeights.b;
half r = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvR).r;
half g = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvG).g;
half b = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uvB).b;
// 8. 重新组合
return half4(r, g, b, 1.0);
}
ENDHLSL
Pass
{
Name "Advanced Chromatic Aberration"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c195927c5e8d7b54482f7cc52dc314df
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
Shader "SLS/Postprocessing/AdvancedVignette"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// --- 参数定义 ---
float4 _VignetteColors; // xy: Unused, z: Unused, w: Unused (颜色单独传)
float4 _ColorInner; // 内部颜色 (过渡色)
float4 _ColorOuter; // 外部颜色 (边缘色)
float3 _VignetteParams1;
// x: Intensity (强度)
// y: Smoothness (柔和度)
// z: Roundness (圆度)
float4 _VignetteCenter; // xy: Center
// 简单的伪随机噪声函数 (用于 Dithering)
float Random(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
half4 Frag(Varyings input) : SV_Target
{
float2 uv = input.texcoord;
// 1. 参数解包
float intensity = _VignetteParams1.x;
float smoothness = max(0.001, _VignetteParams1.y);
float roundness = _VignetteParams1.z;
float2 center = _VignetteCenter.xy;
half3 colInner = _ColorInner.rgb;
half3 colOuter = _ColorOuter.rgb;
// 2. 计算距离场 (SDF)
float2 d = uv - center;
// 圆度计算
d = d * lerp(1.0, 0.5, roundness);
float vdist = length(d);
float boxDist = max(abs(d.x), abs(d.y));
vdist = lerp(boxDist, vdist, roundness);
// 3. 计算遮罩 (Mask)
// 归一化距离,使其适配 Intensity
float maxDist = 0.8;
float threshold = 1.0 - intensity;
// 计算平滑的 0-1 遮罩值
// mask = 0 (中心区域,显示原图) -> 1 (边缘区域,显示暗角)
float mask = smoothstep(threshold - smoothness * 0.5, threshold + smoothness * 0.5, vdist * 2.0);
// 5. 计算最终暗角颜色 (Gradient)
// 随着 mask 从 0 变到 1颜色从 Inner 变到 Outer
// 我们可以用 mask 本身作为插值系数,或者用 vdist
// 这里用 mask 保证颜色变化与透明度变化同步
half3 finalVignetteColor = lerp(colInner, colOuter, mask);
// 6. 混合原图
half4 sceneColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
// sceneColor * (1 - mask) + vignetteColor * mask
// 即Lerp(sceneColor, finalVignetteColor, mask)
return lerp(sceneColor, half4(finalVignetteColor, 1), mask);
}
ENDHLSL
Pass
{
Name "Advanced Vignette"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e9424f71b68fc594b82da3259df1d2c5
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
Shader "SLS/Postprocessing/RGBSplitGlitch"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
// 1. 引入 Unity 核心库 (替代原本的 #include "PostProcessingPass.hlsl")
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// 引入 Blit 库以获得 Vert 顶点函数和 _BlitTexture
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// 2. 定义该效果专用的变量
float4 _RGBSplitGlitchParams;
#define _RGBSplitGlitchIntensity _RGBSplitGlitchParams.x
#define _TimeX _RGBSplitGlitchParams.y
// 3. 辅助函数 (仅在此 Shader 内部使用)
float randomNoise(float x, float y)
{
return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
}
// 4. 片段着色器逻辑
float4 RGBSplitGlitchPassFragment(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float splitAmount = _RGBSplitGlitchIntensity * randomNoise(_TimeX, 2);
// 使用 _BlitTexture 采样当前画面
half4 colorR = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, input.texcoord);
half4 colorG = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp,
float2(input.texcoord.x + splitAmount, input.texcoord.y + splitAmount));
half4 colorB = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp,
float2(input.texcoord.x - splitAmount, input.texcoord.y - splitAmount));
return half4(colorR.r, colorG.g, colorB.b, 1);
}
ENDHLSL
Pass
{
Name "RGB Split Glitch"
HLSLPROGRAM
#pragma vertex Vert // 使用 Blit.hlsl 中的 Vert
#pragma fragment RGBSplitGlitchPassFragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,117 @@
Shader "SLS/Postprocessing/RadialBlur"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// 变量定义
float4 _RadialBlurParams;
#define _BlurRadius _RadialBlurParams.x
#define _RadialCenter _RadialBlurParams.yz
// --- 具体实现函数 ---
half4 RadialBlurPassFragment_4Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half scale = 1;
half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
scale = _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
scale = 2 * _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
scale = 3 * _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
color *= 0.25f; // 1/4
return color;
}
half4 RadialBlurPassFragment_8Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half4 color = 0;
// 为了代码简洁,这里可以使用循环,但在 Shader 中手动展开(Unroll)通常性能更好或便于控制
// 这里保留你原本的展开逻辑
[unroll]
for(int i=0; i<8; i++)
{
half scale = i * _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
}
return color * 0.125f;
}
half4 RadialBlurPassFragment_12Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half4 color = 0;
for(int i=0; i<12; i++) {
half scale = i * _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
}
return color * 0.0833f;
}
half4 RadialBlurPassFragment_16Tap(Varyings input): SV_Target
{
float2 uv = input.texcoord - _RadialCenter;
half4 color = 0;
for(int i=0; i<16; i++) {
half scale = i * _BlurRadius + 1;
color += SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv * scale + _RadialCenter);
}
return color * 0.0625f;
}
ENDHLSL
Pass
{
Name "Radial Blur 4 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_4Tap
ENDHLSL
}
Pass
{
Name "Radial Blur 8 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_8Tap
ENDHLSL
}
Pass
{
Name "Radial Blur 12 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_12Tap
ENDHLSL
}
Pass
{
Name "Radial Blur 16 Tap"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment RadialBlurPassFragment_16Tap
ENDHLSL
}
}
}

View File

@@ -0,0 +1,77 @@
Shader "SLS/Postprocessing/Sharpen"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// 变量定义
float4 _SharpnessParams;
// x: Strength (锐化强度)
// y: Threshold (对比度阈值,用于降噪)
// z: Clamp (最大亮度变化限制,防光晕)
// w: Unused
half4 SharpenPassFragment(Varyings input) : SV_Target
{
half2 uv = input.texcoord;
// _BlitTexture_TexelSize 包含了纹理像素的大小 (1/width, 1/height)
float4 texelSize = _BlitTexture_TexelSize;
// 1. 5-Tap 采样 (中心 + 上下左右)
half4 center = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
half3 up = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(0, texelSize.y)).rgb;
half3 down = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv - float2(0, texelSize.y)).rgb;
half3 left = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv - float2(texelSize.x, 0)).rgb;
half3 right = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + float2(texelSize.x, 0)).rgb;
// 2. 计算周围像素的平均值
half3 neighborsAvg = (up + down + left + right) * 0.25;
// 3. 计算差异 (边缘信号)
// 如果 center 比周围亮diff 为正;反之为负。
half3 diff = center.rgb - neighborsAvg;
// 参数解包
float strength = _SharpnessParams.x;
float threshold = _SharpnessParams.y;
float clampVal = _SharpnessParams.z;
// 4. 【优化一】对比度阈值 (Threshold) - 降噪用
// 计算差异的亮度值
float lumaDiff = dot(abs(diff), float3(0.2126, 0.7152, 0.0722));
// 如果差异小于阈值,则不进行锐化 (factor = 0)
// 使用 smoothstep 让过渡更平滑
float factor = smoothstep(threshold, threshold + 0.001, lumaDiff);
// 5. 应用锐化
half3 sharpened = center.rgb + diff * strength * factor;
// 6. 【优化二】钳制 (Clamp) - 防光晕用
// 限制锐化后的值与原始值的偏差不能超过 clampVal
sharpened = max(sharpened, center.rgb - clampVal); // 不能太暗
sharpened = min(sharpened, center.rgb + clampVal); // 不能太亮
return half4(sharpened, center.a);
}
ENDHLSL
Pass
{
Name "Sharpen Pass"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment SharpenPassFragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ca578cdeed02a0e4185a591e727a1a6f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
Shader "SLS/Postprocessing/SpeedLines"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
// 变量
float4 _Colour;
float _SpeedLinesTiling;
float _SpeedLinesRadialScale;
float _SpeedLinesPower;
float _SpeedLinesRemap;
float _SpeedLinesAnimation;
float _MaskScale;
float _MaskHardness;
float _MaskPower;
// --- 噪声算法库 (Simplex Noise) ---
float3 mod2D289( float3 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }
float2 mod2D289( float2 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }
float3 permute( float3 x ) { return mod2D289( ( ( x * 34.0 ) + 1.0 ) * x ); }
float snoise( float2 v )
{
const float4 C = float4( 0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439 );
float2 i = floor( v + dot( v, C.yy ) );
float2 x0 = v - i + dot( i, C.xx );
float2 i1 = ( x0.x > x0.y ) ? float2( 1.0, 0.0 ) : float2( 0.0, 1.0 );
float4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1;
i = mod2D289( i );
float3 p = permute( permute( i.y + float3( 0.0, i1.y, 1.0 ) ) + i.x + float3( 0.0, i1.x, 1.0 ) );
float3 m = max( 0.5 - float3( dot( x0, x0 ), dot( x12.xy, x12.xy ), dot( x12.zw, x12.zw ) ), 0.0 );
m = m * m; m = m * m;
float3 x = 2.0 * frac( p * C.www ) - 1.0; float3 h = abs( x ) - 0.5;
float3 ox = floor( x + 0.5 ); float3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * ( a0 * a0 + h * h );
float3 g;
g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot( m, g );
}
// --- 主逻辑 ---
half4 SpeedLinesPassFragment(Varyings input) : SV_Target
{
half2 uv = input.texcoord;
half4 SceneColour7 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv);
float2 CenteredUV15_g1 = ( uv - float2( 0.5,0.5 ) );
float2 break17_g1 = CenteredUV15_g1;
float2 appendResult23_g1 = (float2(( length( CenteredUV15_g1 ) * _SpeedLinesRadialScale * 2.0 ) , ( atan2( break17_g1.x , break17_g1.y ) * ( 1.0 / 6.28318548202515 ) * _SpeedLinesTiling )));
float2 appendResult58 = (float2(( -_SpeedLinesAnimation * _Time.y ) , 0.0));
float simplePerlin2D10 = snoise( ( appendResult23_g1 + appendResult58 ) );
simplePerlin2D10 = simplePerlin2D10*0.5 + 0.5;
float temp_output_1_0_g6 = _SpeedLinesRemap;
float SpeedLines21 = saturate( ( ( pow( simplePerlin2D10 , _SpeedLinesPower ) - temp_output_1_0_g6 ) / ( 1.0 - temp_output_1_0_g6 ) ) );
float2 texCoord60 = uv * float2( 2,2 ) + float2( -1,-1 );
float temp_output_1_0_g5 = _MaskScale;
float lerpResult71 = lerp( 0.0 , _MaskScale , _MaskHardness);
float Mask24 = pow( ( 1.0 - saturate( ( ( length( texCoord60 ) - temp_output_1_0_g5 ) / ( ( lerpResult71 - 0.001 ) - temp_output_1_0_g5 ) ) ) ) , _MaskPower );
float MaskedSpeedLines29 = ( SpeedLines21 * Mask24 );
float3 ColourRGB38 = (_Colour).rgb;
float ColourA40 = _Colour.a;
float4 speedLineColor = float4( ( MaskedSpeedLines29 * ColourRGB38 ) , SceneColour7.a );
float4 lerpResult2 = lerp( SceneColour7 , speedLineColor , ( MaskedSpeedLines29 * ColourA40 ));
return lerpResult2;
}
ENDHLSL
Pass
{
Name "Speed Lines Pass"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment SpeedLinesPassFragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,135 @@
Shader "SLS/Postprocessing/StrobeFlash"
{
SubShader
{
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
HLSLINCLUDE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
// --- 参数定义 ---
float4 _StrobeColorHigh;
float4 _StrobeColorLow;
float4 _StrobeParams;
float4 _StrobeAdvParams;
// x: Noise Reduction
// y: Softness
// z: Outline Thickness
// w: Outline Threshold (新增:深度差异阈值)
float4 _LuminanceWeights;
// --- 辅助函数 ---
half3 BoxBlur(float2 uv, float radius)
{
float4 offset = _BlitTexture_TexelSize.xyxy * radius * float4(-1, -1, 1, 1);
half3 c1 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.xy).rgb;
half3 c2 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.zy).rgb;
half3 c3 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.xw).rgb;
half3 c4 = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + offset.zw).rgb;
return (c1 + c2 + c3 + c4) * 0.25;
}
// 修改:增加 threshold 参数
float GetEdge(float2 uv, float thickness, float threshold)
{
if(thickness <= 0) return 0;
float2 size = _BlitTexture_TexelSize.xy * thickness;
float d1 = SampleSceneDepth(uv + size);
float d2 = SampleSceneDepth(uv - size);
float d3 = SampleSceneDepth(uv + float2(size.x, -size.y));
float d4 = SampleSceneDepth(uv + float2(-size.x, size.y));
d1 = LinearEyeDepth(d1, _ZBufferParams);
d2 = LinearEyeDepth(d2, _ZBufferParams);
d3 = LinearEyeDepth(d3, _ZBufferParams);
d4 = LinearEyeDepth(d4, _ZBufferParams);
float diff1 = abs(d1 - d2);
float diff2 = abs(d3 - d4);
// 使用传入的阈值,而不是写死的 0.1
// 只有当深度差 > threshold 时,才认为是边缘
return step(threshold, diff1 + diff2);
}
half4 StrobeFlashPassFragment(Varyings input) : SV_Target
{
half2 uv = input.texcoord;
float frequency = _StrobeParams.x;
float threshold = _StrobeParams.y;
float noiseReduction = _StrobeAdvParams.x;
float softness = _StrobeAdvParams.y;
// 新增参数获取
float outlineThickness = _StrobeAdvParams.z;
float outlineThreshold = max(0.001, _StrobeAdvParams.w); // 防止除0或负数
float3 lumWeights = _LuminanceWeights.rgb;
// 采样颜色 (带降噪)
half3 sceneColor;
if (noiseReduction > 0.01)
{
sceneColor = BoxBlur(uv, noiseReduction);
}
else
{
sceneColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).rgb;
}
float luminance = dot(sceneColor, lumWeights);
float softRange = max(0.001, softness);
float t = smoothstep(threshold - softRange, threshold + softRange, luminance);
float isAuto = _StrobeParams.z;
float isManualInvert = _StrobeParams.w;
float invertSignal = 0;
if (isAuto > 0.5)
{
invertSignal = step(0, sin(_Time.y * frequency * PI));
}
invertSignal = max(invertSignal, isManualInvert);
// 边缘检测:传入 Thickness 和 Threshold
float edge = GetEdge(uv, outlineThickness, outlineThreshold);
t = abs(t - edge);
float3 finalColor;
if (invertSignal > 0.5)
{
finalColor = lerp(_StrobeColorHigh.rgb, _StrobeColorLow.rgb, t);
}
else
{
finalColor = lerp(_StrobeColorLow.rgb, _StrobeColorHigh.rgb, t);
}
return half4(finalColor, 1);
}
ENDHLSL
Pass
{
Name "Strobe Flash Pass"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment StrobeFlashPassFragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: aa12587766ec16842a16c1965e43da43
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,32 +0,0 @@
Shader "Hidden/Custom/SpeedLines"
{
SubShader
{
// URP 标签
Tags
{
"RenderType" = "Opaque"
"RenderPipeline" = "UniversalPipeline"
}
ZWrite Off
Cull Off
// 包含所有效果的 HLSL 逻辑
HLSLINCLUDE
#include "PostProcessingPass.hlsl"
ENDHLSL
// 定义一个 Pass。我们只需要这一个
Pass
{
Name "Speed Lines Pass"
HLSLPROGRAM
// Vert顶点函数来自 PostProcessingPass.hlsl 包含的 Blit.hlsl
#pragma vertex Vert
// Frag片元函数是我们即将在下面 HLSL 文件中创建的新函数
#pragma fragment SpeedLinesPassFragment
ENDHLSL
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ca35e3cf743bc4240a318ee3bde84ece
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSFramework.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);
protected 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 SLSFramework.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);
protected 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

@@ -5,7 +5,7 @@ using UnityEngine.Rendering.Universal;
namespace SLSFramework.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("Custom/RGBSplitGlitch")]
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/RGBSplitGlitch")]
public class RGBSplitGlitch : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
@@ -13,7 +13,7 @@ namespace SLSFramework.Rendering.PostProcessing
public ClampedFloatParameter intensity = new(0f, 0f, 1f);
public ClampedFloatParameter speed = new(10f, 0f, 100f);
protected override string GetShaderName() => "Hidden/Custom/RGBSplitGlitch";
protected override string GetShaderName() => "SLS/Postprocessing/RGBSplitGlitch";
private float elapsedTime = 1.0f;

View File

@@ -10,11 +10,10 @@ namespace SLSFramework.Rendering.PostProcessing
RadialBlur_4Tap_Fatest = 0,
RadialBlur_8Tap_Balance = 1,
RadialBlur_12Tap = 2,
RadialBlur_20Tap_Quality = 3,
RadialBlur_30Tap_Extreme = 4,
RadialBlur_16Tap_Quality = 3,
}
[System.Serializable, VolumeComponentMenu("Custom/Radial Blur")]
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Radial Blur")]
public class RadialBlur : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.BeforePostProcess;
@@ -25,7 +24,7 @@ namespace SLSFramework.Rendering.PostProcessing
public ClampedFloatParameter radialCenterX = new(0.5f, 0f, 1f);
public ClampedFloatParameter radialCenterY = new(0.5f, 0f, 1f);
protected override string GetShaderName() => "Hidden/Custom/RadialBlur";
protected override string GetShaderName() => "SLS/Postprocessing/RadialBlur";
public override void Render(CommandBuffer cmd, ref RenderingData renderingData, RTHandle source, RTHandle target)
{

View File

@@ -0,0 +1,48 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSFramework.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);
protected 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

@@ -5,7 +5,7 @@ using UnityEngine.Rendering.Universal;
namespace SLSFramework.Rendering.PostProcessing
{
[System.Serializable, VolumeComponentMenu("Custom/Speed Lines")]
[System.Serializable, VolumeComponentMenu("SLS/Postprocessing/Speed Lines")]
public class SpeedLines : ScriptablePostProcessorVolume
{
public override CustomPostProcessInjectionPoint InjectionPoint => CustomPostProcessInjectionPoint.AfterPostProcess;
@@ -26,7 +26,7 @@ namespace SLSFramework.Rendering.PostProcessing
public ClampedFloatParameter maskHardness = new(0f, 0f, 1f);
public FloatParameter maskPower = new(5f);
protected override string GetShaderName() => "Hidden/Custom/SpeedLines";
protected 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)

View File

@@ -0,0 +1,76 @@
using Echovoid.Runtime.Behavior.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace SLSFramework.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));
protected 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