源战役客户端
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 

277 řádky
6.8 KiB

Shader "Hidden/FXAA" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
half4 _MainTex_TexelSize;
half _ContrastThreshold, _RelativeThreshold;
half _SubpixelBlending;
struct VertexData {
half4 vertex : POSITION;
half2 uv : TEXCOORD0;
};
struct Interpolators {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
Interpolators VertexProgram (VertexData v) {
Interpolators i;
i.pos = UnityObjectToClipPos(v.vertex);
i.uv = v.uv;
return i;
}
half4 Sample (half2 uv) {
return tex2Dlod(_MainTex, half4(uv, 0, 0));
}
half SampleLuminance (half2 uv) {
return Sample(uv).g;
// #if defined(LUMINANCE_GREEN)
// return Sample(uv).g;
// #else
// return Sample(uv).a;
// #endif
}
half SampleLuminance (half2 uv, half uOffset, half vOffset) {
uv += _MainTex_TexelSize * half2(uOffset, vOffset);
return SampleLuminance(uv);
}
struct LuminanceData {
half m, n, e, s, w;
half ne, nw, se, sw;
half highest, lowest, contrast;
};
LuminanceData SampleLuminanceNeighborhood (half2 uv) {
LuminanceData l;
l.m = SampleLuminance(uv);
l.n = SampleLuminance(uv, 0, 1);
l.e = SampleLuminance(uv, 1, 0);
l.s = SampleLuminance(uv, 0, -1);
l.w = SampleLuminance(uv, -1, 0);
l.ne = SampleLuminance(uv, 1, 1);
l.nw = SampleLuminance(uv, -1, 1);
l.se = SampleLuminance(uv, 1, -1);
l.sw = SampleLuminance(uv, -1, -1);
l.highest = max(max(max(max(l.n, l.e), l.s), l.w), l.m);
l.lowest = min(min(min(min(l.n, l.e), l.s), l.w), l.m);
l.contrast = l.highest - l.lowest;
return l;
}
bool ShouldSkipPixel (LuminanceData l) {
half threshold =
max(_ContrastThreshold, _RelativeThreshold * l.highest);
return l.contrast < threshold;
}
half DeterminePixelBlendFactor (LuminanceData l) {
half filter = 2 * (l.n + l.e + l.s + l.w);
filter += l.ne + l.nw + l.se + l.sw;
filter *= 1.0 / 12.0;
filter = abs(filter - l.m);
filter = saturate(filter / l.contrast);
half blendFactor = smoothstep(0, 1, filter);
return blendFactor * blendFactor * _SubpixelBlending;
}
struct EdgeData {
bool isHorizontal;
half pixelStep;
half oppositeLuminance, gradient;
};
EdgeData DetermineEdge (LuminanceData l) {
EdgeData e;
half horizontal =
abs(l.n + l.s - 2 * l.m) * 2 +
abs(l.ne + l.se - 2 * l.e) +
abs(l.nw + l.sw - 2 * l.w);
half vertical =
abs(l.e + l.w - 2 * l.m) * 2 +
abs(l.ne + l.nw - 2 * l.n) +
abs(l.se + l.sw - 2 * l.s);
e.isHorizontal = horizontal >= vertical;
half pLuminance = e.isHorizontal ? l.n : l.e;
half nLuminance = e.isHorizontal ? l.s : l.w;
half pGradient = abs(pLuminance - l.m);
half nGradient = abs(nLuminance - l.m);
e.pixelStep =
e.isHorizontal ? _MainTex_TexelSize.y : _MainTex_TexelSize.x;
if (pGradient < nGradient) {
e.pixelStep = -e.pixelStep;
e.oppositeLuminance = nLuminance;
e.gradient = nGradient;
}
else {
e.oppositeLuminance = pLuminance;
e.gradient = pGradient;
}
return e;
}
#if defined(LOW_QUALITY)
#define EDGE_STEP_COUNT 4
#define EDGE_STEPS 1, 1.5, 2, 4
#define EDGE_GUESS 12
#else
#define EDGE_STEP_COUNT 10
#define EDGE_STEPS 1, 1.5, 2, 2, 2, 2, 2, 2, 2, 4
#define EDGE_GUESS 8
#endif
static const half edgeSteps[EDGE_STEP_COUNT] = { EDGE_STEPS };
half DetermineEdgeBlendFactor (LuminanceData l, EdgeData e, half2 uv) {
half2 uvEdge = uv;
half2 edgeStep;
if (e.isHorizontal) {
uvEdge.y += e.pixelStep * 0.5;
edgeStep = half2(_MainTex_TexelSize.x, 0);
}
else {
uvEdge.x += e.pixelStep * 0.5;
edgeStep = half2(0, _MainTex_TexelSize.y);
}
half edgeLuminance = (l.m + e.oppositeLuminance) * 0.5;
half gradientThreshold = e.gradient * 0.25;
half2 puv = uvEdge + edgeStep * edgeSteps[0];
half pLuminanceDelta = SampleLuminance(puv) - edgeLuminance;
bool pAtEnd = abs(pLuminanceDelta) >= gradientThreshold;
UNITY_UNROLL
for (int i = 1; i < EDGE_STEP_COUNT && !pAtEnd; i++) {
puv += edgeStep * edgeSteps[i];
pLuminanceDelta = SampleLuminance(puv) - edgeLuminance;
pAtEnd = abs(pLuminanceDelta) >= gradientThreshold;
}
if (!pAtEnd) {
puv += edgeStep * EDGE_GUESS;
}
half2 nuv = uvEdge - edgeStep * edgeSteps[0];
half nLuminanceDelta = SampleLuminance(nuv) - edgeLuminance;
bool nAtEnd = abs(nLuminanceDelta) >= gradientThreshold;
UNITY_UNROLL
for (int i = 1; i < EDGE_STEP_COUNT && !nAtEnd; i++) {
nuv -= edgeStep * edgeSteps[i];
nLuminanceDelta = SampleLuminance(nuv) - edgeLuminance;
nAtEnd = abs(nLuminanceDelta) >= gradientThreshold;
}
if (!nAtEnd) {
nuv -= edgeStep * EDGE_GUESS;
}
half pDistance, nDistance;
if (e.isHorizontal) {
pDistance = puv.x - uv.x;
nDistance = uv.x - nuv.x;
}
else {
pDistance = puv.y - uv.y;
nDistance = uv.y - nuv.y;
}
half shortestDistance;
bool deltaSign;
if (pDistance <= nDistance) {
shortestDistance = pDistance;
deltaSign = pLuminanceDelta >= 0;
}
else {
shortestDistance = nDistance;
deltaSign = nLuminanceDelta >= 0;
}
if (deltaSign == (l.m - edgeLuminance >= 0)) {
return 0;
}
return 0.5 - shortestDistance / (pDistance + nDistance);
}
half4 ApplyFXAA (half2 uv) {
LuminanceData l = SampleLuminanceNeighborhood(uv);
if (ShouldSkipPixel(l)) {
return Sample(uv);
}
half pixelBlend = DeterminePixelBlendFactor(l);
EdgeData e = DetermineEdge(l);
half edgeBlend = DetermineEdgeBlendFactor(l, e, uv);
half finalBlend = max(pixelBlend, edgeBlend);
if (e.isHorizontal) {
uv.y += e.pixelStep * finalBlend;
}
else {
uv.x += e.pixelStep * finalBlend;
}
return half4(Sample(uv).rgb, l.m);
}
ENDCG
SubShader {
Cull Off
ZTest Always
ZWrite Off
Pass { // 0 luminancePass
CGPROGRAM
#pragma vertex VertexProgram
#pragma fragment FragmentProgram
// #pragma enable_d3d11_debug_symbols
#pragma multi_compile _ GAMMA_BLENDING
half4 FragmentProgram (Interpolators i) : SV_Target {
half4 sample = tex2D(_MainTex, i.uv);
sample.rgb = saturate(sample.rgb);
sample.a = LinearRgbToLuminance(sample.rgb);
#if defined(GAMMA_BLENDING)
sample.rgb = LinearToGammaSpace(sample.rgb);
#endif
return sample;
}
ENDCG
}
Pass { // 1 fxaaPass
CGPROGRAM
#pragma vertex VertexProgram
#pragma fragment FragmentProgram
// #pragma enable_d3d11_debug_symbols
// #pragma multi_compile _ LUMINANCE_GREEN
#pragma multi_compile _ LOW_QUALITY
#pragma multi_compile _ GAMMA_BLENDING
half4 FragmentProgram (Interpolators i) : SV_Target {
half4 sample = ApplyFXAA(i.uv);
#if defined(GAMMA_BLENDING)
sample.rgb = GammaToLinearSpace(sample.rgb);
#endif
return sample;
}
ENDCG
}
}
}