modified maps
modified maps
This commit is contained in:
@ -0,0 +1,135 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/BlendModesOverlay" {
|
||||
Properties {
|
||||
_MainTex ("Screen Blended", 2D) = "" {}
|
||||
_Overlay ("Color", 2D) = "grey" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _Overlay;
|
||||
sampler2D _MainTex;
|
||||
|
||||
half _Intensity;
|
||||
half4 _MainTex_TexelSize;
|
||||
half4 _UV_Transform = half4(1, 0, 0, 1);
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
|
||||
o.uv[0] = float2(
|
||||
dot(v.texcoord.xy, _UV_Transform.xy),
|
||||
dot(v.texcoord.xy, _UV_Transform.zw)
|
||||
);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if(_MainTex_TexelSize.y<0.0)
|
||||
o.uv[0].y = 1.0-o.uv[0].y;
|
||||
#endif
|
||||
|
||||
o.uv[1] = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragAddSub (v2f i) : SV_Target {
|
||||
half4 toAdd = tex2D(_Overlay, i.uv[0]) * _Intensity;
|
||||
return tex2D(_MainTex, i.uv[1]) + toAdd;
|
||||
}
|
||||
|
||||
half4 fragMultiply (v2f i) : SV_Target {
|
||||
half4 toBlend = tex2D(_Overlay, i.uv[0]) * _Intensity;
|
||||
return tex2D(_MainTex, i.uv[1]) * toBlend;
|
||||
}
|
||||
|
||||
half4 fragScreen (v2f i) : SV_Target {
|
||||
half4 toBlend = (tex2D(_Overlay, i.uv[0]) * _Intensity);
|
||||
return 1-(1-toBlend)*(1-(tex2D(_MainTex, i.uv[1])));
|
||||
}
|
||||
|
||||
half4 fragOverlay (v2f i) : SV_Target {
|
||||
half4 m = (tex2D(_Overlay, i.uv[0]));// * 255.0;
|
||||
half4 color = (tex2D(_MainTex, i.uv[1]));//* 255.0;
|
||||
|
||||
// overlay blend mode
|
||||
//color.rgb = (color.rgb/255.0) * (color.rgb + ((2*m.rgb)/( 255.0 )) * (255.0-color.rgb));
|
||||
//color.rgb /= 255.0;
|
||||
|
||||
/*
|
||||
if (Target > ½) R = 1 - (1-2x(Target-½)) x (1-Blend)
|
||||
if (Target <= ½) R = (2xTarget) x Blend
|
||||
*/
|
||||
|
||||
float3 check = step(0.5, color.rgb);
|
||||
float3 result = 0;
|
||||
|
||||
result = check * (half3(1,1,1) - ( (half3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
|
||||
result += (1-check) * (2*color.rgb) * m.rgb;
|
||||
|
||||
return half4(lerp(color.rgb, result.rgb, (_Intensity)), color.a);
|
||||
}
|
||||
|
||||
half4 fragAlphaBlend (v2f i) : SV_Target {
|
||||
half4 toAdd = tex2D(_Overlay, i.uv[0]) ;
|
||||
return lerp(tex2D(_MainTex, i.uv[1]), toAdd, toAdd.a * _Intensity);
|
||||
}
|
||||
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
ColorMask RGB
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAddSub
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragScreen
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragMultiply
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragOverlay
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAlphaBlend
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c81db0e527d24acc9bcec04e87781bd
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,44 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/BlurEffectConeTap" {
|
||||
Properties { _MainTex ("", any) = "" {} }
|
||||
CGINCLUDE
|
||||
#include "UnityCG.cginc"
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
half2 uv : TEXCOORD0;
|
||||
half2 taps[4] : TEXCOORD1;
|
||||
};
|
||||
sampler2D _MainTex;
|
||||
half4 _MainTex_TexelSize;
|
||||
half4 _BlurOffsets;
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord - _BlurOffsets.xy * _MainTex_TexelSize.xy; // hack, see BlurEffect.cs for the reason for this. let's make a new blur effect soon
|
||||
o.taps[0] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy;
|
||||
o.taps[1] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy;
|
||||
o.taps[2] = o.uv + _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
|
||||
o.taps[3] = o.uv - _MainTex_TexelSize * _BlurOffsets.xy * half2(1,-1);
|
||||
return o;
|
||||
}
|
||||
half4 frag(v2f i) : SV_Target {
|
||||
half4 color = tex2D(_MainTex, i.taps[0]);
|
||||
color += tex2D(_MainTex, i.taps[1]);
|
||||
color += tex2D(_MainTex, i.taps[2]);
|
||||
color += tex2D(_MainTex, i.taps[3]);
|
||||
return color * 0.25;
|
||||
}
|
||||
ENDCG
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57e6deea7c2924e22a5138e2b70bb4dc
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,518 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
/*
|
||||
CAMERA MOTION BLUR IMAGE EFFECTS
|
||||
|
||||
Reconstruction Filter:
|
||||
Based on "Plausible Motion Blur"
|
||||
http://graphics.cs.williams.edu/papers/MotionBlurI3D12/
|
||||
|
||||
CameraMotion:
|
||||
Based on Alex Vlacho's technique in
|
||||
http://www.valvesoftware.com/publications/2008/GDC2008_PostProcessingInTheOrangeBox.pdf
|
||||
|
||||
SimpleBlur:
|
||||
Straightforward sampling along velocities
|
||||
|
||||
ScatterFromGather:
|
||||
Combines Reconstruction with depth of field type defocus
|
||||
*/
|
||||
|
||||
Shader "Hidden/CameraMotionBlur" {
|
||||
Properties {
|
||||
_MainTex ("-", 2D) = "" {}
|
||||
_NoiseTex ("-", 2D) = "grey" {}
|
||||
_VelTex ("-", 2D) = "black" {}
|
||||
_NeighbourMaxTex ("-", 2D) = "black" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
// 's' in paper (# of samples for reconstruction)
|
||||
#define NUM_SAMPLES (11)
|
||||
// # samples for valve style blur
|
||||
#define MOTION_SAMPLES (16)
|
||||
// 'k' in paper
|
||||
float _MaxRadiusOrKInPaper;
|
||||
|
||||
static const int SmallDiscKernelSamples = 12;
|
||||
static const float2 SmallDiscKernel[SmallDiscKernelSamples] =
|
||||
{
|
||||
float2(-0.326212,-0.40581),
|
||||
float2(-0.840144,-0.07358),
|
||||
float2(-0.695914,0.457137),
|
||||
float2(-0.203345,0.620716),
|
||||
float2(0.96234,-0.194983),
|
||||
float2(0.473434,-0.480026),
|
||||
float2(0.519456,0.767022),
|
||||
float2(0.185461,-0.893124),
|
||||
float2(0.507431,0.064425),
|
||||
float2(0.89642,0.412458),
|
||||
float2(-0.32194,-0.932615),
|
||||
float2(-0.791559,-0.59771)
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
sampler2D _VelTex;
|
||||
sampler2D _NeighbourMaxTex;
|
||||
sampler2D _NoiseTex;
|
||||
sampler2D _TileTexDebug;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
float4 _CameraDepthTexture_TexelSize;
|
||||
float4 _VelTex_TexelSize;
|
||||
|
||||
float4x4 _InvViewProj; // inverse view-projection matrix
|
||||
float4x4 _PrevViewProj; // previous view-projection matrix
|
||||
float4x4 _ToPrevViewProjCombined; // combined
|
||||
|
||||
float _Jitter;
|
||||
|
||||
float _VelocityScale;
|
||||
float _DisplayVelocityScale;
|
||||
|
||||
float _MaxVelocity;
|
||||
float _MinVelocity;
|
||||
|
||||
float4 _BlurDirectionPacked;
|
||||
|
||||
float _SoftZDistance;
|
||||
|
||||
v2f vert(appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 CameraVelocity(v2f i) : SV_Target
|
||||
{
|
||||
float2 depth_uv = i.uv;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
depth_uv.y = 1 - depth_uv.y;
|
||||
#endif
|
||||
|
||||
// read depth
|
||||
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, depth_uv);
|
||||
|
||||
// calculate position from pixel from depth
|
||||
float3 clipPos = float3(i.uv.x*2.0-1.0, (i.uv.y)*2.0-1.0, d);
|
||||
|
||||
// only 1 matrix mul:
|
||||
float4 prevClipPos = mul(_ToPrevViewProjCombined, float4(clipPos, 1.0));
|
||||
prevClipPos.xyz /= prevClipPos.w;
|
||||
|
||||
/*
|
||||
float4 ws = mul(_InvViewProj, float4(clipPos, 1.0));
|
||||
ws /= ws.w;
|
||||
prevClipPos = mul(_PrevViewProj,ws);
|
||||
prevClipPos.xyz /= prevClipPos.w;
|
||||
*/
|
||||
|
||||
/*
|
||||
float2 vel = _VelocityScale *(clipPos.xy - prevClipPos.xy) / 2.f;
|
||||
// clamp to maximum velocity (in pixels)
|
||||
float maxVel = length(_MainTex_TexelSize.xy*_MaxVelocity);
|
||||
if (length(vel) > maxVel) {
|
||||
vel = normalize(vel) * maxVel;
|
||||
}
|
||||
return float4(vel, 0.0, 0.0);
|
||||
*/
|
||||
|
||||
float2 vel = _MainTex_TexelSize.zw * _VelocityScale * (clipPos.xy - prevClipPos.xy) / 2.f;
|
||||
float vellen = length(vel);
|
||||
float maxVel = _MaxVelocity;
|
||||
float2 velOut = vel * max(0.5, min(vellen, maxVel)) / (vellen + 1e-2f);
|
||||
velOut *= _MainTex_TexelSize.xy;
|
||||
return float4(velOut, 0.0, 0.0);
|
||||
|
||||
}
|
||||
|
||||
// vector with largest magnitude
|
||||
float2 vmax(float2 a, float2 b)
|
||||
{
|
||||
float ma = dot(a, a);
|
||||
float mb = dot(b, b);
|
||||
return (ma > mb) ? a : b;
|
||||
}
|
||||
|
||||
// find dominant velocity for each tile
|
||||
float4 TileMax(v2f i) : SV_Target
|
||||
{
|
||||
float2 uvCorner = i.uv - _MainTex_TexelSize.xy * (_MaxRadiusOrKInPaper * 0.5);
|
||||
float2 maxvel = float2(0,0);
|
||||
float4 baseUv = float4(uvCorner,0,0);
|
||||
float4 uvScale = float4(_MainTex_TexelSize.xy, 0, 0);
|
||||
|
||||
for(int l=0; l<(int)_MaxRadiusOrKInPaper; l++)
|
||||
{
|
||||
for(int k=0; k<(int)_MaxRadiusOrKInPaper; k++)
|
||||
{
|
||||
maxvel = vmax(maxvel, tex2Dlod(_MainTex, baseUv + float4(l,k,0,0) * uvScale).xy);
|
||||
}
|
||||
}
|
||||
return float4(maxvel, 0, 1);
|
||||
}
|
||||
|
||||
// find maximum velocity in any adjacent tile
|
||||
float4 NeighbourMax(v2f i) : SV_Target
|
||||
{
|
||||
float2 x_ = i.uv;
|
||||
|
||||
// to fetch all neighbours, we need 3x3 point filtered samples
|
||||
|
||||
float2 nx = tex2D(_MainTex, x_+float2(1.0, 1.0)*_MainTex_TexelSize.xy).xy;
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(1.0, 0.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(1.0,-1.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0, 1.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0, 0.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(0.0,-1.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0, 1.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0, 0.0)*_MainTex_TexelSize.xy).xy);
|
||||
nx = vmax(nx, tex2D(_MainTex, x_+float2(-1.0,-1.0)*_MainTex_TexelSize.xy).xy);
|
||||
|
||||
return float4(nx, 0, 0);
|
||||
}
|
||||
|
||||
float4 Debug(v2f i) : SV_Target
|
||||
{
|
||||
return saturate( float4(tex2D(_MainTex, i.uv).x,abs(tex2D(_MainTex, i.uv).y),-tex2D(_MainTex, i.uv).xy) * _DisplayVelocityScale);
|
||||
}
|
||||
|
||||
// classification filters
|
||||
float cone(float2 px, float2 py, float2 v)
|
||||
{
|
||||
return clamp(1.0 - (length(px - py) / length(v)), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float cylinder(float2 x, float2 y, float2 v)
|
||||
{
|
||||
float lv = length(v);
|
||||
return 1.0 - smoothstep(0.95*lv, 1.05*lv, length(x - y));
|
||||
}
|
||||
|
||||
// is zb closer than za?
|
||||
float softDepthCompare(float za, float zb)
|
||||
{
|
||||
return clamp(1.0 - (za - zb) / _SoftZDistance, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 SimpleBlur (v2f i) : SV_Target
|
||||
{
|
||||
float2 x = i.uv;
|
||||
float2 xf = x;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
xf.y = 1 - xf.y;
|
||||
#endif
|
||||
|
||||
float2 vx = tex2D(_VelTex, xf).xy; // vel at x
|
||||
|
||||
float4 sum = float4(0, 0, 0, 0);
|
||||
for(int l=0; l<NUM_SAMPLES; l++) {
|
||||
float t = l / (float) (NUM_SAMPLES - 1);
|
||||
t = t-0.5;
|
||||
float2 y = x - vx*t;
|
||||
float4 cy = tex2D(_MainTex, y);
|
||||
sum += cy;
|
||||
}
|
||||
sum /= NUM_SAMPLES;
|
||||
return sum;
|
||||
}
|
||||
|
||||
float4 ReconstructFilterBlur(v2f i) : SV_Target
|
||||
{
|
||||
// uv's
|
||||
|
||||
float2 x = i.uv;
|
||||
float2 xf = x;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
xf.y = 1-xf.y;
|
||||
#endif
|
||||
|
||||
float2 x2 = xf;
|
||||
|
||||
float2 vn = tex2Dlod(_NeighbourMaxTex, float4(x2,0,0)).xy; // largest velocity in neighbourhood
|
||||
float4 cx = tex2Dlod(_MainTex, float4(x,0,0)); // color at x
|
||||
float2 vx = tex2Dlod(_VelTex, float4(xf,0,0)).xy; // vel at x
|
||||
|
||||
float zx = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(x,0,0));
|
||||
zx = -Linear01Depth(zx);
|
||||
|
||||
// random offset [-0.5, 0.5]
|
||||
float j = (tex2Dlod(_NoiseTex, float4(i.uv,0,0) * 11.0f).r*2-1) * _Jitter;
|
||||
|
||||
// sample current pixel
|
||||
float weight = 0.75; // <= good start weight choice??
|
||||
float4 sum = cx * weight;
|
||||
|
||||
int centerSample = (int)(NUM_SAMPLES-1)/2;
|
||||
|
||||
for(int l=0; l<NUM_SAMPLES; l++)
|
||||
{
|
||||
float contrib = 1.0f;
|
||||
#if SHADER_API_D3D11
|
||||
if (l==centerSample) continue; // skip center sample
|
||||
#else
|
||||
if (l==centerSample) contrib = 0.0f; // skip center sample
|
||||
#endif
|
||||
|
||||
float t = lerp(-1.0, 1.0, (l + j) / (-1 + _Jitter + (float)NUM_SAMPLES));
|
||||
//float t = lerp(-1.0, 1.0, l / (float)(NUM_SAMPLES - 1));
|
||||
|
||||
float2 y = x + vn * t;
|
||||
|
||||
float2 yf = y;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
yf.y = 1-yf.y;
|
||||
#endif
|
||||
|
||||
// velocity at y
|
||||
float2 vy = tex2Dlod(_VelTex, float4(yf,0,0)).xy;
|
||||
|
||||
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y,0,0));
|
||||
zy = -Linear01Depth(zy);
|
||||
float f = softDepthCompare(zx, zy);
|
||||
float b = softDepthCompare(zy, zx);
|
||||
float alphay = b * cone(x, y, vx) + f * cone(y, x, vy) + cylinder(y, x, vy) * cylinder(x, y, vx) * 2.0;
|
||||
|
||||
float4 cy = tex2Dlod(_MainTex, float4(y,0,0));
|
||||
sum += cy * alphay * contrib;
|
||||
weight += alphay * contrib;
|
||||
}
|
||||
sum /= weight;
|
||||
return sum;
|
||||
}
|
||||
|
||||
float4 ReconstructionDiscBlur (v2f i) : SV_Target
|
||||
{
|
||||
float2 xf = i.uv;
|
||||
float2 x = i.uv;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
xf.y = 1 - xf.y;
|
||||
#endif
|
||||
|
||||
float2 x2 = xf;
|
||||
|
||||
float2 vn = tex2Dlod(_NeighbourMaxTex, float4(x2,0,0)).xy; // largest velocity in neighbourhood
|
||||
float4 cx = tex2Dlod(_MainTex, float4(x,0,0)); // color at x
|
||||
float2 vx = tex2Dlod(_VelTex, float4(xf,0,0)).xy; // vel at x
|
||||
|
||||
float4 noise = tex2Dlod(_NoiseTex, float4(i.uv,0,0)*11.0f)*2-1;
|
||||
float zx = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(x,0,0));
|
||||
|
||||
zx = -Linear01Depth(zx);
|
||||
|
||||
noise *= _MainTex_TexelSize.xyxy * _Jitter;
|
||||
|
||||
//return abs(blurDir.xyxy)*10 + centerTap;
|
||||
|
||||
float weight = 1.0; // <- maybe tweak this: bluriness amount ...
|
||||
float4 sum = cx * weight;
|
||||
|
||||
float4 jitteredDir = vn.xyxy + noise.xyyz;
|
||||
#ifdef SHADER_API_D3D11
|
||||
jitteredDir = max(abs(jitteredDir.xyxy), _MainTex_TexelSize.xyxy * _MaxVelocity * 0.5) * sign(jitteredDir.xyxy) * float4(1,1,-1,-1);
|
||||
#else
|
||||
jitteredDir = max(abs(jitteredDir.xyxy), _MainTex_TexelSize.xyxy * _MaxVelocity * 0.15) * sign(jitteredDir.xyxy) * float4(1,1,-1,-1);
|
||||
#endif
|
||||
|
||||
for(int l=0; l<SmallDiscKernelSamples; l++)
|
||||
{
|
||||
float4 y = i.uv.xyxy + jitteredDir.xyxy * SmallDiscKernel[l].xyxy * float4(1,1,-1,-1);
|
||||
|
||||
float4 yf = y;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
yf.yw = 1-yf.yw;
|
||||
#endif
|
||||
|
||||
// velocity at y
|
||||
float2 vy = tex2Dlod(_VelTex, float4(yf.xy,0,0)).xy;
|
||||
|
||||
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y.xy,0,0) );
|
||||
zy = -Linear01Depth(zy);
|
||||
|
||||
float f = softDepthCompare(zx, zy);
|
||||
float b = softDepthCompare(zy, zx);
|
||||
float alphay = b * cone(x, y.xy, vx) + f * cone(y.xy, x, vy) + cylinder(y.xy, x, vy) * cylinder(x, y.xy, vx) * 2.0;
|
||||
|
||||
float4 cy = tex2Dlod(_MainTex, float4(y.xy,0,0));
|
||||
sum += cy * alphay;
|
||||
weight += alphay;
|
||||
|
||||
#ifdef SHADER_API_D3D11
|
||||
|
||||
vy = tex2Dlod(_VelTex, float4(yf.zw,0,0)).xy;
|
||||
|
||||
zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y.zw,0,0) );
|
||||
zy = -Linear01Depth(zy);
|
||||
|
||||
f = softDepthCompare(zx, zy);
|
||||
b = softDepthCompare(zy, zx);
|
||||
alphay = b * cone(x, y.zw, vx) + f * cone(y.zw, x, vy) + cylinder(y.zw, x, vy) * cylinder(x, y.zw, vx) * 2.0;
|
||||
|
||||
cy = tex2Dlod(_MainTex, float4(y.zw,0,0));
|
||||
sum += cy * alphay;
|
||||
weight += alphay;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return sum / weight;
|
||||
}
|
||||
|
||||
float4 MotionVectorBlur (v2f i) : SV_Target
|
||||
{
|
||||
float2 x = i.uv;
|
||||
|
||||
float2 insideVector = (x*2-1) * float2(1,_MainTex_TexelSize.w/_MainTex_TexelSize.z);
|
||||
float2 rollVector = float2(insideVector.y, -insideVector.x);
|
||||
|
||||
float2 blurDir = _BlurDirectionPacked.x * float2(0,1);
|
||||
blurDir += _BlurDirectionPacked.y * float2(1,0);
|
||||
blurDir += _BlurDirectionPacked.z * rollVector;
|
||||
blurDir += _BlurDirectionPacked.w * insideVector;
|
||||
blurDir *= _VelocityScale;
|
||||
|
||||
// clamp to maximum velocity (in pixels)
|
||||
float velMag = length(blurDir);
|
||||
if (velMag > _MaxVelocity) {
|
||||
blurDir *= (_MaxVelocity / velMag);
|
||||
velMag = _MaxVelocity;
|
||||
}
|
||||
|
||||
float4 centerTap = tex2D(_MainTex, x);
|
||||
float4 sum = centerTap;
|
||||
|
||||
blurDir *= smoothstep(_MinVelocity * 0.25f, _MinVelocity * 2.5, velMag);
|
||||
|
||||
blurDir *= _MainTex_TexelSize.xy;
|
||||
blurDir /= MOTION_SAMPLES;
|
||||
|
||||
for(int i=0; i<MOTION_SAMPLES; i++) {
|
||||
float4 tap = tex2D(_MainTex, x+i*blurDir);
|
||||
sum += tap;
|
||||
}
|
||||
|
||||
return sum/(1+MOTION_SAMPLES);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
// pass 0
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite On Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment CameraVelocity
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 1
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment Debug
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 2
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment TileMax
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 3
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment NeighbourMax
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 4
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment ReconstructFilterBlur
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 5
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment SimpleBlur
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 6
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment MotionVectorBlur
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 7
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment ReconstructionDiscBlur
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85a88efa8c871af4a9d17c64791b6f4f
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,223 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
/*
|
||||
NOTES: see CameraMotionBlur.shader
|
||||
*/
|
||||
|
||||
Shader "Hidden/CameraMotionBlurDX11" {
|
||||
Properties {
|
||||
_MainTex ("-", 2D) = "" {}
|
||||
_NoiseTex ("-", 2D) = "grey" {}
|
||||
_VelTex ("-", 2D) = "black" {}
|
||||
_NeighbourMaxTex ("-", 2D) = "black" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
// 'k' in paper
|
||||
float _MaxRadiusOrKInPaper;
|
||||
// 's' in paper
|
||||
#define NUM_SAMPLES (19)
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
sampler2D _VelTex;
|
||||
sampler2D _NeighbourMaxTex;
|
||||
sampler2D _NoiseTex;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
float4 _CameraDepthTexture_TexelSize;
|
||||
float4 _VelTex_TexelSize;
|
||||
|
||||
float4x4 _InvViewProj; // inverse view-projection matrix
|
||||
float4x4 _PrevViewProj; // previous view-projection matrix
|
||||
float4x4 _ToPrevViewProjCombined; // combined
|
||||
|
||||
float _Jitter;
|
||||
|
||||
float _VelocityScale;
|
||||
float _DisplayVelocityScale;
|
||||
|
||||
float _MinVelocity;
|
||||
|
||||
float _SoftZDistance;
|
||||
|
||||
v2f vert(appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
// returns vector with largest magnitude
|
||||
float2 vmax(float2 a, float2 b)
|
||||
{
|
||||
float ma = dot(a, a);
|
||||
float mb = dot(b, b);
|
||||
return (ma > mb) ? a : b;
|
||||
}
|
||||
|
||||
// find dominant velocity in each tile
|
||||
float4 TileMax(v2f i) : SV_Target
|
||||
{
|
||||
float2 tilemax = float2(0.0, 0.0);
|
||||
float2 srcPos = i.uv - _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper * 0.5;
|
||||
|
||||
for(int y=0; y<(int)_MaxRadiusOrKInPaper; y++) {
|
||||
for(int x=0; x<(int)_MaxRadiusOrKInPaper; x++) {
|
||||
float2 v = tex2D(_MainTex, srcPos + float2(x,y) * _MainTex_TexelSize.xy).xy;
|
||||
tilemax = vmax(tilemax, v);
|
||||
}
|
||||
}
|
||||
return float4(tilemax, 0, 1);
|
||||
}
|
||||
|
||||
// find maximum velocity in any adjacent tile
|
||||
float4 NeighbourMax(v2f i) : SV_Target
|
||||
{
|
||||
float2 maxvel = float2(0.0, 0.0);
|
||||
for(int y=-1; y<=1; y++) {
|
||||
for(int x=-1; x<=1; x++) {
|
||||
float2 v = tex2D(_MainTex, i.uv + float2(x,y) * _MainTex_TexelSize.xy).xy;
|
||||
maxvel = vmax(maxvel, v);
|
||||
}
|
||||
}
|
||||
return float4(maxvel, 0, 1);
|
||||
}
|
||||
|
||||
float cone(float2 px, float2 py, float2 v)
|
||||
{
|
||||
return clamp(1.0 - (length(px - py) / length(v)), 0.0, 1.0);
|
||||
}
|
||||
|
||||
float cylinder(float2 x, float2 y, float2 v)
|
||||
{
|
||||
float lv = length(v);
|
||||
return 1.0 - smoothstep(0.95*lv, 1.05*lv, length(x - y));
|
||||
}
|
||||
|
||||
float softDepthCompare(float za, float zb)
|
||||
{
|
||||
return clamp(1.0 - (za - zb) / _SoftZDistance, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float4 ReconstructFilterBlur(v2f i) : SV_Target
|
||||
{
|
||||
float2 x = i.uv;
|
||||
float2 xf = x;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
xf.y = 1-xf.y;
|
||||
#endif
|
||||
|
||||
float2 x2 = xf;
|
||||
|
||||
float2 vn = tex2D(_NeighbourMaxTex, x2).xy; // largest velocity in neighbourhood
|
||||
float4 cx = tex2D(_MainTex, x); // color at x
|
||||
|
||||
float zx = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, x);
|
||||
zx = -Linear01Depth(zx); // depth at x
|
||||
float2 vx = tex2D(_VelTex, xf).xy; // vel at x
|
||||
|
||||
// random offset [-0.5, 0.5]
|
||||
float j = (tex2D(_NoiseTex, i.uv * 11.0f ).r*2-1) * _Jitter;
|
||||
|
||||
// sample current pixel
|
||||
float weight = 1.0;
|
||||
float4 sum = cx * weight;
|
||||
|
||||
int centerSample = (int)(NUM_SAMPLES-1) / 2;
|
||||
|
||||
// in DX11 county we take more samples and interleave with sampling along vx direction to break up "patternized" look
|
||||
|
||||
for(int l=0; l<NUM_SAMPLES; l++)
|
||||
{
|
||||
if (l==centerSample) continue; // skip center sample
|
||||
|
||||
// Choose evenly placed filter taps along +-vN,
|
||||
// but jitter the whole filter to prevent ghosting
|
||||
|
||||
float t = lerp(-1.0, 1.0, (l + j) / (-1 + _Jitter + (float)NUM_SAMPLES));
|
||||
//float t = lerp(-1.0, 1.0, l / (float)(NUM_SAMPLES - 1));
|
||||
|
||||
float2 velInterlaved = lerp(vn, min(vx, normalize(vx) * _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper), l%2==0);
|
||||
float2 y = x + velInterlaved * t;
|
||||
|
||||
float2 yf = y;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
yf.y = 1-yf.y;
|
||||
#endif
|
||||
|
||||
// velocity at y
|
||||
float2 vy = tex2Dlod(_VelTex, float4(yf,0,0)).xy;
|
||||
|
||||
float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y,0,0));
|
||||
zy = -Linear01Depth(zy);
|
||||
float f = softDepthCompare(zx, zy);
|
||||
float b = softDepthCompare(zy, zx);
|
||||
float alphay = f * cone(y, x, vy) + // blurry y in front of any x
|
||||
b * cone(x, y, vx) + // any y behing blurry x; estimate background
|
||||
cylinder(y, x, vy) * cylinder(x, y, vx) * 2.0; // simultaneous blurry x and y
|
||||
|
||||
float4 cy = tex2Dlod(_MainTex, float4(y,0,0));
|
||||
sum += cy * alphay;
|
||||
weight += alphay;
|
||||
}
|
||||
sum /= weight;
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
// pass 0
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment TileMax
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 1
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment NeighbourMax
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// pass 2
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment ReconstructFilterBlur
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1b13d7a80660504a858ea24cfa418c6
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,161 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ChromaticAberration" {
|
||||
Properties {
|
||||
_MainTex ("Base", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
half _ChromaticAberration;
|
||||
half _AxialAberration;
|
||||
half _Luminance;
|
||||
half2 _BlurDistance;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragDs(v2f i) : SV_Target
|
||||
{
|
||||
half4 c = tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * 0.5);
|
||||
c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * 0.5);
|
||||
c += tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * float2(0.5,-0.5));
|
||||
c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * float2(0.5,-0.5));
|
||||
return c/4.0;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
half2 coords = i.uv;
|
||||
half2 uv = i.uv;
|
||||
|
||||
coords = (coords - 0.5) * 2.0;
|
||||
half coordDot = dot (coords,coords);
|
||||
|
||||
half2 uvG = uv - _MainTex_TexelSize.xy * _ChromaticAberration * coords * coordDot;
|
||||
half4 color = tex2D (_MainTex, uv);
|
||||
#if SHADER_API_D3D9
|
||||
// Work around Cg's code generation bug for D3D9 pixel shaders :(
|
||||
color.g = color.g * 0.0001 + tex2D (_MainTex, uvG).g;
|
||||
#else
|
||||
color.g = tex2D (_MainTex, uvG).g;
|
||||
#endif
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// squeezing into SM2.0 with 9 samples:
|
||||
static const int SmallDiscKernelSamples = 9;
|
||||
static const half2 SmallDiscKernel[SmallDiscKernelSamples] =
|
||||
{
|
||||
half2(-0.926212,-0.40581),
|
||||
half2(-0.695914,0.457137),
|
||||
half2(-0.203345,0.820716),
|
||||
half2(0.96234,-0.194983),
|
||||
half2(0.473434,-0.480026),
|
||||
half2(0.519456,0.767022),
|
||||
half2(0.185461,-0.893124),
|
||||
half2(0.89642,0.412458),
|
||||
half2(-0.32194,-0.932615),
|
||||
};
|
||||
|
||||
half4 fragComplex(v2f i) : SV_Target
|
||||
{
|
||||
half2 coords = i.uv;
|
||||
half2 uv = i.uv;
|
||||
|
||||
// corner heuristic
|
||||
coords = (coords - 0.5h) * 2.0h;
|
||||
half coordDot = dot (coords,coords);
|
||||
|
||||
half4 color = tex2D (_MainTex, uv);
|
||||
half tangentialStrength = _ChromaticAberration * coordDot * coordDot;
|
||||
half maxOfs = clamp(max(_AxialAberration, tangentialStrength), _BlurDistance.x, _BlurDistance.y);
|
||||
|
||||
// we need a blurred sample tap for advanced aberration
|
||||
|
||||
// NOTE: it's relatively important that input is HDR
|
||||
// and if you do have a proper HDR setup, lerping .rb might yield better results than .g
|
||||
// (see below)
|
||||
|
||||
half4 blurredTap = color * 0.1h;
|
||||
for(int l=0; l < SmallDiscKernelSamples; l++)
|
||||
{
|
||||
half2 sampleUV = uv + SmallDiscKernel[l].xy * _MainTex_TexelSize.xy * maxOfs;
|
||||
half3 tap = tex2D(_MainTex, sampleUV).rgb;
|
||||
blurredTap.rgb += tap;
|
||||
}
|
||||
blurredTap.rgb /= (float)SmallDiscKernelSamples + 0.2h;
|
||||
|
||||
// debug:
|
||||
//return blurredTap;
|
||||
|
||||
half lumDiff = Luminance(abs(blurredTap.rgb-color.rgb));
|
||||
half isEdge = saturate(_Luminance * lumDiff);
|
||||
|
||||
// debug #2:
|
||||
//return isEdge;
|
||||
|
||||
color.rb = lerp(color.rb, blurredTap.rb, isEdge);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
// 0: box downsample
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDs
|
||||
|
||||
ENDCG
|
||||
}
|
||||
// 1: simple chrom aberration
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
ENDCG
|
||||
}
|
||||
// 2: simulates more chromatic aberration effects
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragComplex
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b4f29398d9484ccfa9fd220449f5eee
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,76 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ColorCorrection3DLut" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler3D _ClutTex;
|
||||
|
||||
float _Scale;
|
||||
float _Offset;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float4 c = tex2D(_MainTex, i.uv);
|
||||
c.rgb = tex3D(_ClutTex, c.rgb * _Scale + _Offset).rgb;
|
||||
return c;
|
||||
}
|
||||
|
||||
float4 fragLinear(v2f i) : SV_Target
|
||||
{
|
||||
float4 c = tex2D(_MainTex, i.uv);
|
||||
c.rgb= sqrt(c.rgb);
|
||||
c.rgb = tex3D(_ClutTex, c.rgb * _Scale + _Offset).rgb;
|
||||
c.rgb = c.rgb*c.rgb;
|
||||
return c;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
|
||||
Subshader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass
|
||||
{
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragLinear
|
||||
#pragma target 3.0
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b61f0d8d8244b4b28aa66b0c8cb46a8d
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,95 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ColorCorrectionCurves" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
|
||||
_RgbTex ("_RgbTex (RGB)", 2D) = "" {}
|
||||
|
||||
_ZCurve ("_ZCurve (RGB)", 2D) = "" {}
|
||||
|
||||
_RgbDepthTex ("_RgbDepthTex (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// note: also have a look at ColorCorrectionCurvesSimple
|
||||
// for a much simpler color correction without use of
|
||||
// depth texture lookups
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv2 : TEXCOORD1;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
float4 _CameraDepthTexture_ST;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
sampler2D _RgbTex;
|
||||
sampler2D _ZCurve;
|
||||
sampler2D _RgbDepthTex;
|
||||
|
||||
fixed _Saturation;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
o.uv2 = TRANSFORM_TEX(v.texcoord, _CameraDepthTexture);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv2.y = 1-o.uv2.y;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
half4 color = tex2D(_MainTex, i.uv);
|
||||
|
||||
half3 ycoords = half3(0.5,1.5,2.5) * 0.25;
|
||||
|
||||
half3 red = tex2D(_RgbTex, half2(color.r, ycoords.x)).rgb * half3(1,0,0);
|
||||
half3 green = tex2D(_RgbTex, half2(color.g, ycoords.y)).rgb * half3(0,1,0);
|
||||
half3 blue = tex2D(_RgbTex, half2(color.b, ycoords.z)).rgb * half3(0,0,1);
|
||||
|
||||
half theDepth = SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, i.uv2) ;
|
||||
half zval = tex2D(_ZCurve, half2( Linear01Depth (theDepth), 0.5));
|
||||
|
||||
half3 depthRed = tex2D(_RgbDepthTex, half2(color.r, ycoords.x)).rgb * half3(1,0,0);
|
||||
half3 depthGreen = tex2D(_RgbDepthTex, half2(color.g, ycoords.y)).rgb * half3(0,1,0);
|
||||
half3 depthBlue = tex2D(_RgbDepthTex, half2(color.b, ycoords.z)).rgb * half3(0,0,1);
|
||||
|
||||
color = half4( lerp(red+green+blue, depthRed+depthBlue+depthGreen, zval), color.a);
|
||||
|
||||
half lum = Luminance(color.rgb);
|
||||
color.rgb = lerp(half3(lum,lum,lum), color.rgb, _Saturation);
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62bcade1028c24ca1a39760ed84b9487
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,61 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ColorCorrectionCurvesSimple" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
_RgbTex ("_RgbTex (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
half2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _RgbTex;
|
||||
fixed _Saturation;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target
|
||||
{
|
||||
fixed4 color = tex2D(_MainTex, i.uv);
|
||||
|
||||
fixed3 red = tex2D(_RgbTex, half2(color.r, 0.5/4.0)).rgb * fixed3(1,0,0);
|
||||
fixed3 green = tex2D(_RgbTex, half2(color.g, 1.5/4.0)).rgb * fixed3(0,1,0);
|
||||
fixed3 blue = tex2D(_RgbTex, half2(color.b, 2.5/4.0)).rgb * fixed3(0,0,1);
|
||||
|
||||
color = fixed4(red+green+blue, color.a);
|
||||
|
||||
fixed lum = Luminance(color.rgb);
|
||||
color.rgb = lerp(fixed3(lum,lum,lum), color.rgb, _Saturation);
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 438ddd58d82c84d9eb1fdc56111702e1
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,38 @@
|
||||
Shader "Hidden/Color Correction Effect" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_RampTex ("Base (RGB)", 2D) = "grayscaleRamp" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_img
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _RampTex;
|
||||
|
||||
fixed4 frag (v2f_img i) : SV_Target
|
||||
{
|
||||
fixed4 orig = tex2D(_MainTex, i.uv);
|
||||
|
||||
fixed rr = tex2D(_RampTex, orig.rr).r;
|
||||
fixed gg = tex2D(_RampTex, orig.gg).g;
|
||||
fixed bb = tex2D(_RampTex, orig.bb).b;
|
||||
|
||||
fixed4 color = fixed4(rr, gg, bb, orig.a);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67f8781cad112c75d0008dfa8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,54 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ColorCorrectionSelective" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 selColor;
|
||||
float4 targetColor;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target {
|
||||
fixed4 color = tex2D (_MainTex, i.uv);
|
||||
|
||||
fixed diff = saturate (2.0 * length (color.rgb - selColor.rgb));
|
||||
color = lerp (targetColor, color, diff);
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e515e0f94cefc4c0db54b45cba621544
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a40c1b84cf7fe418bae97a29041b85a4
|
@ -0,0 +1,68 @@
|
||||
// Calculates adaptation to minimum/maximum luminance values,
|
||||
// based on "currently adapted" and "new values to adapt to"
|
||||
// textures (both 1x1).
|
||||
|
||||
Shader "Hidden/Contrast Stretch Adaptation" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_CurTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_img
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex; // currently adapted to
|
||||
uniform sampler2D _CurTex; // new value to adapt to
|
||||
uniform float4 _AdaptParams; // x=adaptLerp, y=limitMinimum, z=limitMaximum
|
||||
|
||||
float4 frag (v2f_img i) : SV_Target {
|
||||
// value is: max, min
|
||||
float2 valAdapted = tex2D(_MainTex, i.uv).xy;
|
||||
float2 valCur = tex2D(_CurTex, i.uv).xy;
|
||||
|
||||
// Calculate new adapted values: interpolate
|
||||
// from valAdapted to valCur by script-supplied amount.
|
||||
//
|
||||
// Because we store adaptation levels in a simple 8 bit/channel
|
||||
// texture, we might not have enough precision - the interpolation
|
||||
// amount might be too small to change anything, and we'll never
|
||||
// arrive at the needed values.
|
||||
//
|
||||
// So we make sure the change we do is at least 1/255th of the
|
||||
// color range - this way we'll always change the value.
|
||||
const float kMinChange = 1.0/255.0;
|
||||
float2 delta = (valCur-valAdapted) * _AdaptParams.x;
|
||||
delta.x = sign(delta.x) * max( kMinChange, abs(delta.x) );
|
||||
delta.y = sign(delta.y) * max( kMinChange, abs(delta.y) );
|
||||
|
||||
float4 valNew;
|
||||
valNew.xy = valAdapted + delta;
|
||||
|
||||
// Impose user limits on maximum/minimum values
|
||||
valNew.x = max( valNew.x, _AdaptParams.z );
|
||||
valNew.y = min( valNew.y, _AdaptParams.y );
|
||||
|
||||
// Optimization so that our final apply pass is faster:
|
||||
// z = max-min (plus a small amount to prevent division by zero)
|
||||
valNew.z = valNew.x - valNew.y + 0.01;
|
||||
// w = min/(max-min)
|
||||
valNew.w = valNew.y / valNew.z;
|
||||
|
||||
return valNew;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 257bc83cbeb544540bd0e558aa9b1383
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,57 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
// Final pass in the contrast stretch effect: apply
|
||||
// color stretch to the original image, based on currently
|
||||
// adapted to minimum/maximum luminances.
|
||||
|
||||
Shader "Hidden/Contrast Stretch Apply" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_AdaptTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _AdaptTex;
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv[0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
|
||||
o.uv[1] = float2(0.5,0.5);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv[0]);
|
||||
float4 adapted = tex2D(_AdaptTex, i.uv[1]);
|
||||
float vmul = 1.0 / adapted.z;
|
||||
float vadd = -adapted.w;
|
||||
col.rgb = col.rgb * vmul + vadd;
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4901f25d4e1542589348bbb89563d8e
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,35 @@
|
||||
// Outputs luminance (grayscale) of the input image _MainTex
|
||||
|
||||
Shader "Hidden/Contrast Stretch Luminance" {
|
||||
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_img
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
|
||||
float4 frag (v2f_img i) : SV_Target
|
||||
{
|
||||
float4 col = tex2D(_MainTex, i.uv);
|
||||
col.rgb = Luminance(col.rgb) * (1+col.a*2);
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: befbb4b9c320b4b18a08ef7afb93b6c9
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,67 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
// Reduces input image (_MainTex) by 2x2.
|
||||
// Outputs maximum value in R, minimum in G.
|
||||
Shader "Hidden/Contrast Stretch Reduction" {
|
||||
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
Category {
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 position : SV_POSITION;
|
||||
float2 uv[4] : TEXCOORD0;
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
|
||||
v2f vert (appdata_img v) {
|
||||
v2f o;
|
||||
o.position = UnityObjectToClipPos (v.vertex);
|
||||
float2 uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
|
||||
|
||||
// Compute UVs to sample 2x2 pixel block.
|
||||
o.uv[0] = uv + float2(0,0);
|
||||
o.uv[1] = uv + float2(0,1);
|
||||
o.uv[2] = uv + float2(1,0);
|
||||
o.uv[3] = uv + float2(1,1);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
// Sample pixel block
|
||||
float4 v00 = tex2D(_MainTex, i.uv[0]);
|
||||
float2 v01 = tex2D(_MainTex, i.uv[1]).xy;
|
||||
float2 v10 = tex2D(_MainTex, i.uv[2]).xy;
|
||||
float2 v11 = tex2D(_MainTex, i.uv[3]).xy;
|
||||
|
||||
float4 res;
|
||||
// output x: maximum of the four values
|
||||
res.x = max( max(v00.x,v01.x), max(v10.x,v11.x) );
|
||||
// output y: minimum of the four values
|
||||
res.y = min( min(v00.y,v01.y), min(v10.y,v11.y) );
|
||||
// output zw unchanged from the first pixel
|
||||
res.zw = v00.zw;
|
||||
|
||||
return res;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57b33a14b6d5347c5a85c36f6cb3b280
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,69 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ContrastComposite" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
_MainTexBlurred ("Base Blurred (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _MainTexBlurred;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
float intensity;
|
||||
float threshold;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
|
||||
o.uv[0] = v.texcoord.xy;
|
||||
o.uv[1] = v.texcoord.xy;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv[0].y = 1-o.uv[0].y;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
half4 color = tex2D (_MainTex, i.uv[1]);
|
||||
half4 blurred = tex2D (_MainTexBlurred, (i.uv[0]));
|
||||
|
||||
half4 difference = color - blurred;
|
||||
half4 signs = sign (difference);
|
||||
|
||||
half4 enhancement = saturate (abs(difference) - threshold) * signs * 1.0/(1.0-threshold);
|
||||
color += enhancement * intensity;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 273404942eede4ea1883ca1fb2942507
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,56 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/ConvertDepth" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
float d = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
|
||||
d = Linear01Depth(d);
|
||||
|
||||
if(d>0.99999)
|
||||
return half4(1,1,1,1);
|
||||
else
|
||||
return EncodeFloatRGBA(d);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14768d3865b1342e3a861fbe19ba2db2
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,63 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
|
||||
Shader "Hidden/CreaseApply" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_HrDepthTex ("Base (RGB)", 2D) = "white" {}
|
||||
_LrDepthTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _HrDepthTex;
|
||||
sampler2D _LrDepthTex;
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
uniform float intensity;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv.xy = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 hrDepth = tex2D(_HrDepthTex, i.uv);
|
||||
float4 lrDepth = tex2D(_LrDepthTex, i.uv);
|
||||
|
||||
hrDepth.a = DecodeFloatRGBA(hrDepth);
|
||||
lrDepth.a = DecodeFloatRGBA(lrDepth);
|
||||
|
||||
float4 color = tex2D(_MainTex, i.uv);
|
||||
|
||||
return color * (1.0-abs(hrDepth.a-lrDepth.a)*intensity);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b59984d82af624bd3b0c777f038276f2
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,327 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
Shader "Hidden/EdgeDetect" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[5] : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2fd {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
sampler2D _CameraDepthNormalsTexture;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
uniform half4 _Sensitivity;
|
||||
uniform half4 _BgColor;
|
||||
uniform half _BgFade;
|
||||
uniform half _SampleDistance;
|
||||
uniform float _Exponent;
|
||||
|
||||
uniform float _Threshold;
|
||||
|
||||
struct v2flum {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[3] : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2flum vertLum (appdata_img v)
|
||||
{
|
||||
v2flum o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
|
||||
o.uv[0] = uv;
|
||||
o.uv[1] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
|
||||
o.uv[2] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
fixed4 fragLum (v2flum i) : SV_Target
|
||||
{
|
||||
fixed4 original = tex2D(_MainTex, i.uv[0]);
|
||||
|
||||
// a very simple cross gradient filter
|
||||
|
||||
half3 p1 = original.rgb;
|
||||
half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
|
||||
half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;
|
||||
|
||||
half3 diff = p1 * 2 - p2 - p3;
|
||||
half len = dot(diff, diff);
|
||||
len = step(len, _Threshold);
|
||||
//if(len >= _Threshold)
|
||||
// original.rgb = 0;
|
||||
|
||||
return len * lerp(original, _BgColor, _BgFade);
|
||||
}
|
||||
|
||||
inline half CheckSame (half2 centerNormal, float centerDepth, half4 theSample)
|
||||
{
|
||||
// difference in normals
|
||||
// do not bother decoding normals - there's no need here
|
||||
half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
|
||||
int isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
|
||||
// difference in depth
|
||||
float sampleDepth = DecodeFloatRG (theSample.zw);
|
||||
float zdiff = abs(centerDepth-sampleDepth);
|
||||
// scale the required threshold by the distance
|
||||
int isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;
|
||||
|
||||
// return:
|
||||
// 1 - if normals and depth are similar enough
|
||||
// 0 - otherwise
|
||||
|
||||
return isSameNormal * isSameDepth ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
v2f vertRobert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
o.uv[0] = uv;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
uv.y = 1-uv.y;
|
||||
#endif
|
||||
|
||||
// calc coord for the X pattern
|
||||
// maybe nicer TODO for the future: 'rotated triangles'
|
||||
|
||||
o.uv[1] = uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance;
|
||||
o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance;
|
||||
o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance;
|
||||
o.uv[4] = uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
v2f vertThin( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
o.uv[0] = uv;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
uv.y = 1-uv.y;
|
||||
#endif
|
||||
|
||||
o.uv[1] = uv;
|
||||
o.uv[4] = uv;
|
||||
|
||||
// offsets for two additional samples
|
||||
o.uv[2] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
|
||||
o.uv[3] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
v2fd vertD( appdata_img v )
|
||||
{
|
||||
v2fd o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
o.uv[0] = uv;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
uv.y = 1-uv.y;
|
||||
#endif
|
||||
|
||||
o.uv[1] = uv;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 fragDCheap(v2fd i) : SV_Target
|
||||
{
|
||||
// inspired by borderlands implementation of popular "sobel filter"
|
||||
|
||||
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
|
||||
float4 depthsDiag;
|
||||
float4 depthsAxis;
|
||||
|
||||
float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
|
||||
|
||||
depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
|
||||
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
|
||||
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
|
||||
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
|
||||
|
||||
depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
|
||||
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
|
||||
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
|
||||
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
|
||||
|
||||
depthsDiag -= centerDepth;
|
||||
depthsAxis /= centerDepth;
|
||||
|
||||
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
|
||||
const float4 VertDiagCoeff = float4(-1,1,-1,1);
|
||||
const float4 HorizAxisCoeff = float4(1,0,0,-1);
|
||||
const float4 VertAxisCoeff = float4(0,1,-1,0);
|
||||
|
||||
float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
|
||||
float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
|
||||
|
||||
float SobelX = dot(SobelH, float4(1,1,1,1));
|
||||
float SobelY = dot(SobelV, float4(1,1,1,1));
|
||||
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
|
||||
|
||||
Sobel = 1.0-pow(saturate(Sobel), _Exponent);
|
||||
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
|
||||
}
|
||||
|
||||
// pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
|
||||
// which makes it compatible with other depth based post fx
|
||||
|
||||
float4 fragD(v2fd i) : SV_Target
|
||||
{
|
||||
// inspired by borderlands implementation of popular "sobel filter"
|
||||
|
||||
float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
|
||||
float4 depthsDiag;
|
||||
float4 depthsAxis;
|
||||
|
||||
float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
|
||||
|
||||
depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist)); // TR
|
||||
depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(-1,1))); // TL
|
||||
depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(-1,1))); // BR
|
||||
depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist)); // BL
|
||||
|
||||
depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(0,1))); // T
|
||||
depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(1,0))); // L
|
||||
depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]+uvDist*float2(1,0))); // R
|
||||
depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv[1]-uvDist*float2(0,1))); // B
|
||||
|
||||
// make it work nicely with depth based image effects such as depth of field:
|
||||
depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
|
||||
depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;
|
||||
|
||||
depthsDiag -= centerDepth;
|
||||
depthsAxis /= centerDepth;
|
||||
|
||||
const float4 HorizDiagCoeff = float4(1,1,-1,-1);
|
||||
const float4 VertDiagCoeff = float4(-1,1,-1,1);
|
||||
const float4 HorizAxisCoeff = float4(1,0,0,-1);
|
||||
const float4 VertAxisCoeff = float4(0,1,-1,0);
|
||||
|
||||
float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
|
||||
float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
|
||||
|
||||
float SobelX = dot(SobelH, float4(1,1,1,1));
|
||||
float SobelY = dot(SobelV, float4(1,1,1,1));
|
||||
float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
|
||||
|
||||
Sobel = 1.0-pow(saturate(Sobel), _Exponent);
|
||||
return Sobel * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
|
||||
}
|
||||
|
||||
half4 fragRobert(v2f i) : SV_Target {
|
||||
half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
|
||||
half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
|
||||
half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
|
||||
half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);
|
||||
|
||||
half edge = 1.0;
|
||||
|
||||
edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
|
||||
edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
|
||||
|
||||
return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
|
||||
}
|
||||
|
||||
half4 fragThin (v2f i) : SV_Target
|
||||
{
|
||||
half4 original = tex2D(_MainTex, i.uv[0]);
|
||||
|
||||
half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
|
||||
half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
|
||||
half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
|
||||
|
||||
// encoded normal
|
||||
half2 centerNormal = center.xy;
|
||||
// decoded depth
|
||||
float centerDepth = DecodeFloatRG (center.zw);
|
||||
|
||||
half edge = 1.0;
|
||||
|
||||
edge *= CheckSame(centerNormal, centerDepth, sample1);
|
||||
edge *= CheckSame(centerNormal, centerDepth, sample2);
|
||||
|
||||
return edge * lerp(original, _BgColor, _BgFade);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertThin
|
||||
#pragma fragment fragThin
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertRobert
|
||||
#pragma fragment fragRobert
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vertD
|
||||
#pragma fragment fragDCheap
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vertD
|
||||
#pragma fragment fragD
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma target 3.0
|
||||
#pragma vertex vertLum
|
||||
#pragma fragment fragLum
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d1644bdf064147baa97f235fc5b4903
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,60 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/FisheyeShader" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float2 intensity;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
half2 coords = i.uv;
|
||||
coords = (coords - 0.5) * 2.0;
|
||||
|
||||
half2 realCoordOffs;
|
||||
realCoordOffs.x = (1-coords.y * coords.y) * intensity.y * (coords.x);
|
||||
realCoordOffs.y = (1-coords.x * coords.x) * intensity.x * (coords.y);
|
||||
|
||||
half4 color = tex2D (_MainTex, i.uv - realCoordOffs);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 874ceab4425f64bccb1d14032f4452b1
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,188 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/GlobalFog" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "black" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D_float _CameraDepthTexture;
|
||||
|
||||
// x = fog height
|
||||
// y = FdotC (CameraY-FogHeight)
|
||||
// z = k (FdotC > 0.0)
|
||||
// w = a/2
|
||||
uniform float4 _HeightParams;
|
||||
|
||||
// x = start distance
|
||||
uniform float4 _DistanceParams;
|
||||
|
||||
int4 _SceneFogMode; // x = fog mode, y = use radial flag
|
||||
float4 _SceneFogParams;
|
||||
#ifndef UNITY_APPLY_FOG
|
||||
half4 unity_FogColor;
|
||||
half4 unity_FogDensity;
|
||||
#endif
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
// for fast world space reconstruction
|
||||
uniform float4x4 _FrustumCornersWS;
|
||||
uniform float4 _CameraWS;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv_depth : TEXCOORD1;
|
||||
float4 interpolatedRay : TEXCOORD2;
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
half index = v.vertex.z;
|
||||
v.vertex.z = 0.1;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
o.uv_depth = v.texcoord.xy;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv.y = 1-o.uv.y;
|
||||
#endif
|
||||
|
||||
o.interpolatedRay = _FrustumCornersWS[(int)index];
|
||||
o.interpolatedRay.w = index;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
// Applies one of standard fog formulas, given fog coordinate (i.e. distance)
|
||||
half ComputeFogFactor (float coord)
|
||||
{
|
||||
float fogFac = 0.0;
|
||||
if (_SceneFogMode.x == 1) // linear
|
||||
{
|
||||
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
|
||||
fogFac = coord * _SceneFogParams.z + _SceneFogParams.w;
|
||||
}
|
||||
if (_SceneFogMode.x == 2) // exp
|
||||
{
|
||||
// factor = exp(-density*z)
|
||||
fogFac = _SceneFogParams.y * coord; fogFac = exp2(-fogFac);
|
||||
}
|
||||
if (_SceneFogMode.x == 3) // exp2
|
||||
{
|
||||
// factor = exp(-(density*z)^2)
|
||||
fogFac = _SceneFogParams.x * coord; fogFac = exp2(-fogFac*fogFac);
|
||||
}
|
||||
return saturate(fogFac);
|
||||
}
|
||||
|
||||
// Distance-based fog
|
||||
float ComputeDistance (float3 camDir, float zdepth)
|
||||
{
|
||||
float dist;
|
||||
if (_SceneFogMode.y == 1)
|
||||
dist = length(camDir);
|
||||
else
|
||||
dist = zdepth * _ProjectionParams.z;
|
||||
// Built-in fog starts at near plane, so match that by
|
||||
// subtracting the near value. Not a perfect approximation
|
||||
// if near plane is very large, but good enough.
|
||||
dist -= _ProjectionParams.y;
|
||||
return dist;
|
||||
}
|
||||
|
||||
// Linear half-space fog, from https://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf
|
||||
float ComputeHalfSpace (float3 wsDir)
|
||||
{
|
||||
float3 wpos = _CameraWS + wsDir;
|
||||
float FH = _HeightParams.x;
|
||||
float3 C = _CameraWS;
|
||||
float3 V = wsDir;
|
||||
float3 P = wpos;
|
||||
float3 aV = _HeightParams.w * V;
|
||||
float FdotC = _HeightParams.y;
|
||||
float k = _HeightParams.z;
|
||||
float FdotP = P.y-FH;
|
||||
float FdotV = wsDir.y;
|
||||
float c1 = k * (FdotP + FdotC);
|
||||
float c2 = (1-2*k) * FdotP;
|
||||
float g = min(c2, 0.0);
|
||||
g = -length(aV) * (c1 - g * g / abs(FdotV+1.0e-5f));
|
||||
return g;
|
||||
}
|
||||
|
||||
half4 ComputeFog (v2f i, bool distance, bool height) : SV_Target
|
||||
{
|
||||
half4 sceneColor = tex2D(_MainTex, i.uv);
|
||||
|
||||
// Reconstruct world space position & direction
|
||||
// towards this screen pixel.
|
||||
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture,i.uv_depth);
|
||||
float dpth = Linear01Depth(rawDepth);
|
||||
float4 wsDir = dpth * i.interpolatedRay;
|
||||
float4 wsPos = _CameraWS + wsDir;
|
||||
|
||||
// Compute fog distance
|
||||
float g = _DistanceParams.x;
|
||||
if (distance)
|
||||
g += ComputeDistance (wsDir, dpth);
|
||||
if (height)
|
||||
g += ComputeHalfSpace (wsDir);
|
||||
|
||||
// Compute fog amount
|
||||
half fogFac = ComputeFogFactor (max(0.0,g));
|
||||
// Do not fog skybox
|
||||
if (rawDepth == _DistanceParams.y)
|
||||
fogFac = 1.0;
|
||||
//return fogFac; // for debugging
|
||||
|
||||
// Lerp between fog color & original scene color
|
||||
// by fog amount
|
||||
return lerp (unity_FogColor, sceneColor, fogFac);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader
|
||||
{
|
||||
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
|
||||
|
||||
// 0: distance + height
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, true); }
|
||||
ENDCG
|
||||
}
|
||||
// 1: distance
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
half4 frag (v2f i) : SV_Target { return ComputeFog (i, true, false); }
|
||||
ENDCG
|
||||
}
|
||||
// 2: height
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
half4 frag (v2f i) : SV_Target { return ComputeFog (i, false, true); }
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70d8568987ac0499f952b54c7c13e265
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,36 @@
|
||||
Shader "Hidden/Grayscale Effect" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_RampTex ("Base (RGB)", 2D) = "grayscaleRamp" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_img
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _RampTex;
|
||||
uniform half _RampOffset;
|
||||
|
||||
fixed4 frag (v2f_img i) : SV_Target
|
||||
{
|
||||
fixed4 original = tex2D(_MainTex, i.uv);
|
||||
fixed grayscale = Luminance(original.rgb);
|
||||
half2 remap = half2 (grayscale + _RampOffset, .5);
|
||||
fixed4 output = tex2D(_RampTex, remap);
|
||||
output.a = original.a;
|
||||
return output;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daf9781cad112c75d0008dfa8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,122 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/MotionBlur" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_AccumOrig("AccumOrig", Float) = 0.65
|
||||
}
|
||||
|
||||
SubShader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
Pass {
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ColorMask RGB
|
||||
BindChannels {
|
||||
Bind "vertex", vertex
|
||||
Bind "texcoord", texcoord
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata_t {
|
||||
float4 vertex : POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 vertex : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
float4 _MainTex_ST;
|
||||
float _AccumOrig;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return half4(tex2D(_MainTex, i.texcoord).rgb, _AccumOrig );
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
Blend One Zero
|
||||
ColorMask A
|
||||
|
||||
BindChannels {
|
||||
Bind "vertex", vertex
|
||||
Bind "texcoord", texcoord
|
||||
}
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata_t {
|
||||
float4 vertex : POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 vertex : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert (appdata_t v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return tex2D(_MainTex, i.texcoord);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SubShader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
Pass {
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
ColorMask RGB
|
||||
SetTexture [_MainTex] {
|
||||
ConstantColor (0,0,0,[_AccumOrig])
|
||||
Combine texture, constant
|
||||
}
|
||||
}
|
||||
Pass {
|
||||
Blend One Zero
|
||||
ColorMask A
|
||||
SetTexture [_MainTex] {
|
||||
Combine texture
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9ba2083ad114a07d000fbfb8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,60 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
Shader "Hidden/MotionBlurClear"
|
||||
{
|
||||
|
||||
Properties { }
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
//ZTest LEqual
|
||||
ZTest Always // lame depth test
|
||||
ZWrite Off // lame depth test
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct vs_input {
|
||||
float4 vertex : POSITION;
|
||||
};
|
||||
|
||||
struct ps_input {
|
||||
float4 pos : SV_POSITION;
|
||||
float4 screen : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
ps_input vert (vs_input v)
|
||||
{
|
||||
ps_input o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.screen = ComputeScreenPos(o.pos);
|
||||
COMPUTE_EYEDEPTH(o.screen.z);
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag (ps_input i) : SV_Target
|
||||
{
|
||||
// superlame: manual depth test needed as we can't bind depth, FIXME for 4.x
|
||||
// alternatively implement SM > 3 version where we write out custom depth
|
||||
|
||||
float d = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screen));
|
||||
d = LinearEyeDepth(d);
|
||||
|
||||
clip(d - i.screen.z + 1e-2f);
|
||||
return float4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback Off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7699c5fbfa27745a1abe111ab7bf9785
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,158 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/NoiseAndGrain" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_NoiseTex ("Noise (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _NoiseTex;
|
||||
float4 _NoiseTex_TexelSize;
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
uniform float3 _NoisePerChannel;
|
||||
uniform float3 _NoiseTilingPerChannel;
|
||||
uniform float3 _NoiseAmount;
|
||||
uniform float3 _ThreshholdRGB;
|
||||
uniform float3 _MidGrey;
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv_screen : TEXCOORD0;
|
||||
float4 uvRg : TEXCOORD1;
|
||||
float2 uvB : TEXCOORD2;
|
||||
};
|
||||
|
||||
struct appdata_img2
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
inline float3 Overlay(float3 m, float3 color) {
|
||||
color = saturate(color);
|
||||
float3 check = step(float3(0.5,0.5,0.5), color.rgb);
|
||||
float3 result = check * (float3(1,1,1) - ((float3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
|
||||
result += (1-check) * (2*color.rgb) * m.rgb;
|
||||
return result;
|
||||
}
|
||||
|
||||
v2f vert (appdata_img2 v)
|
||||
{
|
||||
v2f o;
|
||||
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.uv_screen = v.vertex.xyxy;
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv_screen.y = 1-o.uv_screen.y;
|
||||
#else
|
||||
o.uv_screen = v.vertex.xy;
|
||||
#endif
|
||||
|
||||
// different tiling for 3 channels
|
||||
o.uvRg = v.texcoord.xyxy + v.texcoord1.xyxy * _NoiseTilingPerChannel.rrgg * _NoiseTex_TexelSize.xyxy;
|
||||
o.uvB = v.texcoord.xy + v.texcoord1.xy * _NoiseTilingPerChannel.bb * _NoiseTex_TexelSize.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = (tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
// fetching & scaling noise (COMPILER BUG WORKAROUND)
|
||||
float3 m = float3(0,0,0);
|
||||
m += (tex2D(_NoiseTex, i.uvRg.xy) * float4(1,0,0,0)).rgb;
|
||||
m += (tex2D(_NoiseTex, i.uvRg.zw) * float4(0,1,0,0)).rgb;
|
||||
m += (tex2D(_NoiseTex, i.uvB.xy) * float4(0,0,1,0)).rgb;
|
||||
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * float3(finalIntensity,finalIntensity,finalIntensity) ));
|
||||
|
||||
return float4(Overlay(m, color.rgb), color.a);
|
||||
}
|
||||
|
||||
float4 fragTmp ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = (tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
// fetching & scaling noise (COMPILER BUG WORKAROUND)
|
||||
float3 m = float3(0,0,0);
|
||||
m += (tex2D(_NoiseTex, i.uvRg.xy) * float4(1,0,0,0)).rgb;
|
||||
m += (tex2D(_NoiseTex, i.uvRg.zw) * float4(0,1,0,0)).rgb;
|
||||
m += (tex2D(_NoiseTex, i.uvB.xy) * float4(0,0,1,0)).rgb;
|
||||
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * float3(finalIntensity,finalIntensity,finalIntensity)));
|
||||
|
||||
return float4(m.rgb, color.a);
|
||||
}
|
||||
|
||||
float4 fragOverlayBlend ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = tex2D(_MainTex, i.uv_screen.xy);
|
||||
float4 m = tex2D(_NoiseTex, i.uv_screen.xy);
|
||||
|
||||
return float4(Overlay(m, color.rgb), color.a);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragOverlayBlend
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragTmp
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
FallBack Off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0249d8c935344451aa4de6db76f0688
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,239 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/NoiseAndGrainDX11" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_NoiseTex ("Noise (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _NoiseTex;
|
||||
float4 _NoiseTex_TexelSize;
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
uniform float3 _NoisePerChannel;
|
||||
uniform float3 _NoiseTilingPerChannel;
|
||||
uniform float3 _NoiseAmount;
|
||||
uniform float3 _ThreshholdRGB;
|
||||
uniform float3 _MidGrey;
|
||||
uniform float _DX11NoiseTime;
|
||||
|
||||
// DX11 noise helper functions, credit: rgba/iq
|
||||
|
||||
int ihash(int n)
|
||||
{
|
||||
n = (n<<13)^n;
|
||||
return (n*(n*n*15731+789221)+1376312589) & 2147483647;
|
||||
}
|
||||
|
||||
float frand(int n)
|
||||
{
|
||||
return ihash(n) / 2147483647.0;
|
||||
}
|
||||
|
||||
float cellNoise1f(int3 p)
|
||||
{
|
||||
return frand(p.z*65536 + p.y*256 + p.x);//*2.0-1.0;
|
||||
}
|
||||
|
||||
float3 cellNoise3f(int3 p)
|
||||
{
|
||||
int i = p.z*65536 + p.y*256 + p.x;
|
||||
return float3(frand(i), frand(i + 57), frand(i + 113));//*2.0-1.0;
|
||||
}
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv_screen : TEXCOORD0;
|
||||
float4 uvRg : TEXCOORD1;
|
||||
float2 uvB : TEXCOORD2;
|
||||
float2 uvOffsets : TEXCOORD4;
|
||||
};
|
||||
|
||||
struct appdata_img2
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float2 texcoord1 : TEXCOORD1;
|
||||
};
|
||||
|
||||
inline float3 Overlay(float3 m, float3 color) {
|
||||
float3 check = step(0.5, color.rgb);
|
||||
float3 result = check * (float3(1,1,1) - ((float3(1,1,1) - 2*(color.rgb-0.5)) * (1-m.rgb)));
|
||||
result += (1-check) * (2*color.rgb) * m.rgb;
|
||||
return result;
|
||||
}
|
||||
|
||||
v2f vert (appdata_img2 v)
|
||||
{
|
||||
v2f o;
|
||||
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.uv_screen = v.vertex.xyxy;
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv_screen.y = 1-o.uv_screen.y;
|
||||
#else
|
||||
o.uv_screen = v.vertex.xy;
|
||||
#endif
|
||||
|
||||
// different tiling for 3 channels
|
||||
o.uvRg = v.texcoord.xyxy + v.texcoord1.xyxy * _NoiseTilingPerChannel.rrgg * _NoiseTex_TexelSize.xyxy;
|
||||
o.uvB = v.texcoord.xy + v.texcoord1.xy * _NoiseTilingPerChannel.bb * _NoiseTex_TexelSize.xy;
|
||||
|
||||
o.uvOffsets = v.texcoord.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 fragDX11 ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
float3 m = cellNoise3f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * finalIntensity));
|
||||
|
||||
return float4(Overlay(m, color.rgb), color.a);
|
||||
}
|
||||
|
||||
float4 fragDX11Monochrome ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
float3 m = cellNoise1f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, finalIntensity));
|
||||
|
||||
return float4(Overlay(m, color.rgb), color.a);
|
||||
}
|
||||
|
||||
float4 fragDX11Tmp ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
float3 m = cellNoise3f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, _NoisePerChannel.rgb * finalIntensity));
|
||||
|
||||
return float4(m.rgb, color.a);
|
||||
}
|
||||
|
||||
float4 fragDX11MonochromeTmp ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
|
||||
|
||||
// black & white intensities
|
||||
float2 blackWhiteCurve = Luminance(color.rgb) - _MidGrey.x; // maybe tweak middle grey
|
||||
blackWhiteCurve.xy = saturate(blackWhiteCurve.xy * _MidGrey.yz); //float2(1.0/0.8, -1.0/0.2));
|
||||
|
||||
float finalIntensity = _NoiseAmount.x + max(0.0f, dot(_NoiseAmount.zy, blackWhiteCurve.xy));
|
||||
|
||||
float3 m = cellNoise1f(float3( (i.uv_screen.xy + i.uvOffsets) * _MainTex_TexelSize.zw, _DX11NoiseTime));
|
||||
m = saturate(lerp(float3(0.5,0.5,0.5), m, finalIntensity));
|
||||
|
||||
return float4(m.rgb, color.a);
|
||||
}
|
||||
|
||||
float4 fragOverlayBlend ( v2f i ) : SV_Target
|
||||
{
|
||||
float4 color = saturate(tex2D (_MainTex, i.uv_screen.xy));
|
||||
float4 m = saturate(tex2D (_NoiseTex, i.uv_screen.xy));
|
||||
|
||||
return float4(Overlay(m, color.rgb), color.a);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader {
|
||||
ZTest Always Cull Off ZWrite Off Blend Off
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma exclude_renderers gles xbox360 ps3 d3d9
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDX11
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma exclude_renderers gles xbox360 ps3 d3d9
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDX11Monochrome
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma exclude_renderers gles xbox360 ps3 d3d9
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDX11Tmp
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma exclude_renderers gles xbox360 ps3 d3d9
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDX11MonochromeTmp
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma exclude_renderers gles xbox360 ps3 d3d9
|
||||
#pragma target 5.0
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragOverlayBlend
|
||||
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
FallBack Off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b30686bb4322ab42ad5eb50a0210b58
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,64 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Noise Shader RGB" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_GrainTex ("Base (RGB)", 2D) = "gray" {}
|
||||
_ScratchTex ("Base (RGB)", 2D) = "gray" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uvg : TEXCOORD1; // grain
|
||||
float2 uvs : TEXCOORD2; // scratch
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _GrainTex;
|
||||
uniform sampler2D _ScratchTex;
|
||||
|
||||
uniform float4 _GrainOffsetScale;
|
||||
uniform float4 _ScratchOffsetScale;
|
||||
uniform fixed4 _Intensity; // x=grain, y=scratch
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
|
||||
o.uvg = v.texcoord.xy * _GrainOffsetScale.zw + _GrainOffsetScale.xy;
|
||||
o.uvs = v.texcoord.xy * _ScratchOffsetScale.zw + _ScratchOffsetScale.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
fixed4 col = tex2D(_MainTex, i.uv);
|
||||
|
||||
// sample noise texture and do a signed add
|
||||
fixed3 grain = tex2D(_GrainTex, i.uvg).rgb * 2 - 1;
|
||||
col.rgb += grain * _Intensity.x;
|
||||
|
||||
// sample scratch texture and do a signed add
|
||||
fixed3 scratch = tex2D(_ScratchTex, i.uvs).rgb * 2 - 1;
|
||||
col.rgb += scratch * _Intensity.y;
|
||||
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d7f4c401ae8946bcb0d6ff68a9e7466
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,75 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Noise Shader YUV" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_GrainTex ("Base (RGB)", 2D) = "gray" {}
|
||||
_ScratchTex ("Base (RGB)", 2D) = "gray" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uvg : TEXCOORD1; // grain
|
||||
float2 uvs : TEXCOORD2; // scratch
|
||||
};
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _GrainTex;
|
||||
uniform sampler2D _ScratchTex;
|
||||
|
||||
uniform float4 _GrainOffsetScale;
|
||||
uniform float4 _ScratchOffsetScale;
|
||||
uniform fixed4 _Intensity; // x=grain, y=scratch
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
|
||||
o.uvg = v.texcoord.xy * _GrainOffsetScale.zw + _GrainOffsetScale.xy;
|
||||
o.uvs = v.texcoord.xy * _ScratchOffsetScale.zw + _ScratchOffsetScale.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
fixed4 col = tex2D(_MainTex, i.uv);
|
||||
|
||||
// convert to YUV
|
||||
fixed3 yuv;
|
||||
yuv.x = dot( col.rgb, half3(0.299,0.587,0.114) );
|
||||
yuv.y = (col.b-yuv.x)*0.492;
|
||||
yuv.z = (col.r-yuv.x)*0.877;
|
||||
|
||||
// sample noise texture and do a signed add
|
||||
fixed3 grain = tex2D(_GrainTex, i.uvg).rgb * 2 - 1;
|
||||
yuv.rgb += grain * _Intensity.x;
|
||||
|
||||
// convert back to rgb
|
||||
col.r = yuv.z * 1.140 + yuv.x;
|
||||
col.g = yuv.z * (-0.581) + yuv.y * (-0.395) + yuv.x;
|
||||
col.b = yuv.y * 2.032 + yuv.x;
|
||||
|
||||
// sample scratch texture and add
|
||||
fixed3 scratch = tex2D(_ScratchTex, i.uvs).rgb * 2 - 1;
|
||||
col.rgb += scratch * _Intensity.y;
|
||||
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e447868506ba49f0a73235b8a8b647a
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,99 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
Shader "Hidden/PrepareSunShaftsBlur" {
|
||||
Properties {
|
||||
_MainTex ("Base", 2D) = "" {}
|
||||
_Skybox ("Skybox", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _Skybox;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
uniform half _NoSkyBoxMask;
|
||||
uniform half4 _SunPosition;
|
||||
|
||||
v2f vert (appdata_img v) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half TransformColor (half4 skyboxValue) {
|
||||
return max (skyboxValue.a, _NoSkyBoxMask * dot (skyboxValue.rgb, float3 (0.59,0.3,0.11)));
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target {
|
||||
float depthSample = SAMPLE_DEPTH_TEXTURE( _CameraDepthTexture, i.uv.xy);
|
||||
half4 tex = tex2D (_MainTex, i.uv.xy);
|
||||
|
||||
depthSample = Linear01Depth (depthSample);
|
||||
|
||||
// consider maximum radius
|
||||
half2 vec = _SunPosition.xy - i.uv.xy;
|
||||
half dist = saturate (_SunPosition.w - length (vec.xy));
|
||||
|
||||
half4 outColor = 0;
|
||||
|
||||
// consider shafts blockers
|
||||
if (depthSample > 0.99)
|
||||
outColor = TransformColor (tex) * dist;
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
half4 fragNoDepthNeeded (v2f i) : SV_Target {
|
||||
float4 sky = (tex2D (_Skybox, i.uv.xy));
|
||||
float4 tex = (tex2D (_MainTex, i.uv.xy));
|
||||
|
||||
// consider maximum radius
|
||||
half2 vec = _SunPosition.xy - i.uv.xy;
|
||||
half dist = saturate (_SunPosition.w - length (vec));
|
||||
|
||||
half4 outColor = 0;
|
||||
|
||||
if (Luminance ( abs(sky.rgb - tex.rgb)) < 0.2)
|
||||
outColor = TransformColor (sky) * dist;
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragNoDepthNeeded
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ad381ed8492840ab9f165df743e4826
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,73 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/RadialBlur"
|
||||
{
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "" {}
|
||||
}
|
||||
|
||||
// Shader code pasted into all further CGPROGRAM blocks
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 blurVector : TEXCOORD1;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 _BlurRadius4;
|
||||
float4 _SunPosition;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv.xy = v.texcoord.xy;
|
||||
|
||||
o.blurVector = (_SunPosition.xy - v.texcoord.xy) * _BlurRadius4.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
#define SAMPLES_FLOAT 6.0f
|
||||
#define SAMPLES_INT 6
|
||||
|
||||
half4 frag(v2f i) : SV_Target
|
||||
{
|
||||
half4 color = half4(0,0,0,0);
|
||||
|
||||
for(int j = 0; j < SAMPLES_INT; j++)
|
||||
{
|
||||
half4 tmpColor = tex2D(_MainTex, i.uv.xy);
|
||||
color += tmpColor;
|
||||
|
||||
i.uv.xy += i.blurVector;
|
||||
}
|
||||
|
||||
return color / SAMPLES_FLOAT;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader
|
||||
{
|
||||
Blend One Zero
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
ENDCG
|
||||
} // Pass
|
||||
} // Subshader
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f58445347fe2e4b8396487ed2bfa02ad
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,281 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/SSAO" {
|
||||
Properties {
|
||||
_MainTex ("", 2D) = "" {}
|
||||
_RandomTexture ("", 2D) = "" {}
|
||||
_SSAO ("", 2D) = "" {}
|
||||
}
|
||||
Subshader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGINCLUDE
|
||||
// Common code used by several SSAO passes below
|
||||
#include "UnityCG.cginc"
|
||||
struct v2f_ao {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uvr : TEXCOORD1;
|
||||
};
|
||||
|
||||
uniform float2 _NoiseScale;
|
||||
float4 _CameraDepthNormalsTexture_ST;
|
||||
|
||||
v2f_ao vert_ao (appdata_img v)
|
||||
{
|
||||
v2f_ao o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.texcoord, _CameraDepthNormalsTexture);
|
||||
o.uvr = v.texcoord.xy * _NoiseScale;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _CameraDepthNormalsTexture;
|
||||
sampler2D _RandomTexture;
|
||||
float4 _Params; // x=radius, y=minz, z=attenuation power, w=SSAO power
|
||||
|
||||
// HLSL and GLSL do not support arbitrarily sized arrays as function parameters (eg. float bla[]), whereas Cg does.
|
||||
#if !defined(UNITY_COMPILER_CG)
|
||||
|
||||
# define INPUT_SAMPLE_COUNT 8
|
||||
# include "frag_ao.cginc"
|
||||
# undef INPUT_SAMPLE_COUNT
|
||||
|
||||
# define INPUT_SAMPLE_COUNT 14
|
||||
# include "frag_ao.cginc"
|
||||
# undef INPUT_SAMPLE_COUNT
|
||||
|
||||
# define INPUT_SAMPLE_COUNT 26
|
||||
# include "frag_ao.cginc"
|
||||
# undef INPUT_SAMPLE_COUNT
|
||||
|
||||
# define INPUT_SAMPLE_COUNT 34
|
||||
# include "frag_ao.cginc"
|
||||
# undef INPUT_SAMPLE_COUNT
|
||||
|
||||
#else
|
||||
# define INPUT_SAMPLE_COUNT
|
||||
# include "frag_ao.cginc"
|
||||
#endif
|
||||
|
||||
ENDCG
|
||||
|
||||
// ---- SSAO pass, 8 samples
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_ao
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
|
||||
|
||||
half4 frag (v2f_ao i) : SV_Target
|
||||
{
|
||||
#define SAMPLE_COUNT 8
|
||||
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
|
||||
float3(0.01305719,0.5872321,-0.119337),
|
||||
float3(0.3230782,0.02207272,-0.4188725),
|
||||
float3(-0.310725,-0.191367,0.05613686),
|
||||
float3(-0.4796457,0.09398766,-0.5802653),
|
||||
float3(0.1399992,-0.3357702,0.5596789),
|
||||
float3(-0.2484578,0.2555322,0.3489439),
|
||||
float3(0.1871898,-0.702764,-0.2317479),
|
||||
float3(0.8849149,0.2842076,0.368524),
|
||||
};
|
||||
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
// ---- SSAO pass, 14 samples
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_ao
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
|
||||
|
||||
half4 frag (v2f_ao i) : SV_Target
|
||||
{
|
||||
#define SAMPLE_COUNT 14
|
||||
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
|
||||
float3(0.4010039,0.8899381,-0.01751772),
|
||||
float3(0.1617837,0.1338552,-0.3530486),
|
||||
float3(-0.2305296,-0.1900085,0.5025396),
|
||||
float3(-0.6256684,0.1241661,0.1163932),
|
||||
float3(0.3820786,-0.3241398,0.4112825),
|
||||
float3(-0.08829653,0.1649759,0.1395879),
|
||||
float3(0.1891677,-0.1283755,-0.09873557),
|
||||
float3(0.1986142,0.1767239,0.4380491),
|
||||
float3(-0.3294966,0.02684341,-0.4021836),
|
||||
float3(-0.01956503,-0.3108062,-0.410663),
|
||||
float3(-0.3215499,0.6832048,-0.3433446),
|
||||
float3(0.7026125,0.1648249,0.02250625),
|
||||
float3(0.03704464,-0.939131,0.1358765),
|
||||
float3(-0.6984446,-0.6003422,-0.04016943),
|
||||
};
|
||||
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
// ---- SSAO pass, 26 samples
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_ao
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
|
||||
|
||||
half4 frag (v2f_ao i) : SV_Target
|
||||
{
|
||||
#define SAMPLE_COUNT 26
|
||||
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
|
||||
float3(0.2196607,0.9032637,0.2254677),
|
||||
float3(0.05916681,0.2201506,-0.1430302),
|
||||
float3(-0.4152246,0.1320857,0.7036734),
|
||||
float3(-0.3790807,0.1454145,0.100605),
|
||||
float3(0.3149606,-0.1294581,0.7044517),
|
||||
float3(-0.1108412,0.2162839,0.1336278),
|
||||
float3(0.658012,-0.4395972,-0.2919373),
|
||||
float3(0.5377914,0.3112189,0.426864),
|
||||
float3(-0.2752537,0.07625949,-0.1273409),
|
||||
float3(-0.1915639,-0.4973421,-0.3129629),
|
||||
float3(-0.2634767,0.5277923,-0.1107446),
|
||||
float3(0.8242752,0.02434147,0.06049098),
|
||||
float3(0.06262707,-0.2128643,-0.03671562),
|
||||
float3(-0.1795662,-0.3543862,0.07924347),
|
||||
float3(0.06039629,0.24629,0.4501176),
|
||||
float3(-0.7786345,-0.3814852,-0.2391262),
|
||||
float3(0.2792919,0.2487278,-0.05185341),
|
||||
float3(0.1841383,0.1696993,-0.8936281),
|
||||
float3(-0.3479781,0.4725766,-0.719685),
|
||||
float3(-0.1365018,-0.2513416,0.470937),
|
||||
float3(0.1280388,-0.563242,0.3419276),
|
||||
float3(-0.4800232,-0.1899473,0.2398808),
|
||||
float3(0.6389147,0.1191014,-0.5271206),
|
||||
float3(0.1932822,-0.3692099,-0.6060588),
|
||||
float3(-0.3465451,-0.1654651,-0.6746758),
|
||||
float3(0.2448421,-0.1610962,0.1289366),
|
||||
};
|
||||
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
// ---- Blur pass
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = TRANSFORM_TEX (v.texcoord, _CameraDepthNormalsTexture);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _SSAO;
|
||||
float3 _TexelOffsetScale;
|
||||
|
||||
inline half CheckSame (half4 n, half4 nn)
|
||||
{
|
||||
// difference in normals
|
||||
half2 diff = abs(n.xy - nn.xy);
|
||||
half sn = (diff.x + diff.y) < 0.1;
|
||||
// difference in depth
|
||||
float z = DecodeFloatRG (n.zw);
|
||||
float zz = DecodeFloatRG (nn.zw);
|
||||
float zdiff = abs(z-zz) * _ProjectionParams.z;
|
||||
half sz = zdiff < 0.2;
|
||||
return sn * sz;
|
||||
}
|
||||
|
||||
|
||||
half4 frag( v2f i ) : SV_Target
|
||||
{
|
||||
#define NUM_BLUR_SAMPLES 4
|
||||
|
||||
float2 o = _TexelOffsetScale.xy;
|
||||
|
||||
half sum = tex2D(_SSAO, i.uv).r * (NUM_BLUR_SAMPLES + 1);
|
||||
half denom = NUM_BLUR_SAMPLES + 1;
|
||||
|
||||
half4 geom = tex2D (_CameraDepthNormalsTexture, i.uv);
|
||||
|
||||
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
|
||||
{
|
||||
float2 nuv = i.uv + o * (s+1);
|
||||
half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
|
||||
half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
|
||||
sum += tex2D (_SSAO, nuv.xy).r * coef;
|
||||
denom += coef;
|
||||
}
|
||||
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
|
||||
{
|
||||
float2 nuv = i.uv - o * (s+1);
|
||||
half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
|
||||
half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
|
||||
sum += tex2D (_SSAO, nuv.xy).r * coef;
|
||||
denom += coef;
|
||||
}
|
||||
return sum / denom;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// ---- Composite pass
|
||||
Pass {
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv[0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
|
||||
o.uv[1] = MultiplyUV (UNITY_MATRIX_TEXTURE1, v.texcoord);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _SSAO;
|
||||
|
||||
half4 frag( v2f i ) : SV_Target
|
||||
{
|
||||
half4 c = tex2D (_MainTex, i.uv[0]);
|
||||
half ao = tex2D (_SSAO, i.uv[1]).r;
|
||||
ao = pow (ao, _Params.w);
|
||||
c.rgb *= ao;
|
||||
return c;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43ca18288c424f645aaa1e9e07f04c50
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,404 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
// This Ambient Occlusion image effect is based on "Scalable Ambient Obscurance":
|
||||
|
||||
/**
|
||||
|
||||
\author Morgan McGuire and Michael Mara, NVIDIA and Williams College, http://research.nvidia.com, http://graphics.cs.williams.edu
|
||||
|
||||
Open Source under the "BSD" license: http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
Copyright (c) 2011-2012, NVIDIA
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
Shader "Hidden/ScreenSpaceAmbientObscurance"
|
||||
{
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
#ifdef SHADER_API_D3D11
|
||||
#define NUM_SAMPLES (15)
|
||||
#else
|
||||
#define NUM_SAMPLES (11)
|
||||
#endif
|
||||
|
||||
#define FAR_PLANE_Z (300.0)
|
||||
#define NUM_SPIRAL_TURNS (7)
|
||||
#define bias (0.01)
|
||||
|
||||
float _Radius;
|
||||
float _Radius2; // _Radius * _Radius;
|
||||
float _Intensity;
|
||||
float4 _ProjInfo;
|
||||
float4x4 _ProjectionInv; // ref only
|
||||
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
sampler2D _Rand;
|
||||
sampler2D _AOTex;
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
static const float gaussian[5] = { 0.153170, 0.144893, 0.122649, 0.092902, 0.062970 }; // stddev = 2.0
|
||||
|
||||
float2 _Axis;
|
||||
|
||||
/** Increase to make edges crisper. Decrease to reduce temporal flicker. */
|
||||
#define EDGE_SHARPNESS (1.0)
|
||||
|
||||
float _BlurFilterDistance;
|
||||
#define SCALE _BlurFilterDistance
|
||||
|
||||
/** Filter _Radius in pixels. This will be multiplied by SCALE. */
|
||||
#define R (4)
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv2 : TEXCOORD1;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
o.uv2 = v.texcoord.xy;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv2.y = 1-o.uv2.y;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
float3 ReconstructCSPosition(float2 S, float z)
|
||||
{
|
||||
float linEyeZ = LinearEyeDepth(z);
|
||||
return float3(( ( S.xy * _MainTex_TexelSize.zw) * _ProjInfo.xy + _ProjInfo.zw) * linEyeZ, linEyeZ);
|
||||
|
||||
/*
|
||||
// for reference
|
||||
float4 clipPos = float4(S*2.0-1.0, (z*2-1), 1);
|
||||
float4 viewPos;
|
||||
viewPos.x = dot((float4)_ProjectionInv[0], clipPos);
|
||||
viewPos.y = dot((float4)_ProjectionInv[1], clipPos);
|
||||
viewPos.w = dot((float4)_ProjectionInv[3], clipPos);
|
||||
viewPos.z = z;
|
||||
viewPos = viewPos/viewPos.w;
|
||||
return viewPos.xyz;
|
||||
*/
|
||||
}
|
||||
|
||||
float3 ReconstructCSFaceNormal(float3 C) {
|
||||
return normalize(cross(ddy(C), ddx(C)));
|
||||
}
|
||||
|
||||
|
||||
/** Returns a unit vector and a screen-space _Radius for the tap on a unit disk (the caller should scale by the actual disk _Radius) */
|
||||
|
||||
float2 TapLocation(int sampleNumber, float spinAngle, out float ssR){
|
||||
// Radius relative to ssR
|
||||
float alpha = float(sampleNumber + 0.5) * (1.0 / NUM_SAMPLES);
|
||||
float angle = alpha * (NUM_SPIRAL_TURNS * 6.28) + spinAngle;
|
||||
|
||||
ssR = alpha;
|
||||
return float2(cos(angle), sin(angle));
|
||||
}
|
||||
|
||||
/** Used for packing Z into the GB channels */
|
||||
float CSZToKey(float z) {
|
||||
return saturate(z * (1.0 / FAR_PLANE_Z));
|
||||
}
|
||||
|
||||
/** Used for packing Z into the GB channels */
|
||||
void packKey(float key, out float2 p) {
|
||||
// Round to the nearest 1/256.0
|
||||
float temp = floor(key * 256.0);
|
||||
|
||||
// Integer part
|
||||
p.x = temp * (1.0 / 256.0);
|
||||
|
||||
// Fractional part
|
||||
p.y = key * 256.0 - temp;
|
||||
}
|
||||
|
||||
/** Returns a number on (0, 1) */
|
||||
float UnpackKey(float2 p)
|
||||
{
|
||||
return p.x * (256.0 / 257.0) + p.y * (1.0 / 257.0);
|
||||
}
|
||||
|
||||
|
||||
/** Read the camera-space position of the point at screen-space pixel ssP */
|
||||
float3 GetPosition(float2 ssP) {
|
||||
float3 P;
|
||||
|
||||
P.z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssP.xy);
|
||||
|
||||
// Offset to pixel center
|
||||
P = ReconstructCSPosition(float2(ssP) /*+ float2(0.5, 0.5)*/, P.z);
|
||||
return P;
|
||||
}
|
||||
|
||||
/** Read the camera-space position of the point at screen-space pixel ssP + unitOffset * ssR. Assumes length(unitOffset) == 1 */
|
||||
float3 GetOffsetPosition(float2 ssC, float2 unitOffset, float ssR)
|
||||
{
|
||||
float2 ssP = saturate(float2(ssR*unitOffset) + ssC);
|
||||
|
||||
float3 P;
|
||||
P.z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssP.xy);
|
||||
|
||||
// Offset to pixel center
|
||||
P = ReconstructCSPosition(float2(ssP)/* + float2(0.5, 0.5)*/, P.z);
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
/** Compute the occlusion due to sample with index \a i about the pixel at \a ssC that corresponds
|
||||
to camera-space point \a C with unit normal \a n_C, using maximum screen-space sampling _Radius \a ssDiskRadius */
|
||||
|
||||
float SampleAO(in float2 ssC, in float3 C, in float3 n_C, in float ssDiskRadius, in int tapIndex, in float randomPatternRotationAngle)
|
||||
{
|
||||
// Offset on the unit disk, spun for this pixel
|
||||
float ssR;
|
||||
float2 unitOffset = TapLocation(tapIndex, randomPatternRotationAngle, ssR);
|
||||
ssR *= ssDiskRadius;
|
||||
|
||||
// The occluding point in camera space
|
||||
float3 Q = GetOffsetPosition(ssC, unitOffset, ssR);
|
||||
|
||||
float3 v = Q - C;
|
||||
|
||||
float vv = dot(v, v);
|
||||
float vn = dot(v, n_C);
|
||||
|
||||
const float epsilon = 0.01;
|
||||
float f = max(_Radius2 - vv, 0.0);
|
||||
return f * f * f * max((vn - bias) / (epsilon + vv), 0.0);
|
||||
}
|
||||
|
||||
float4 fragAO(v2f i) : SV_Target
|
||||
{
|
||||
float4 fragment = fixed4(1,1,1,1);
|
||||
|
||||
// Pixel being shaded
|
||||
float2 ssC = i.uv2.xy;// * _MainTex_TexelSize.zw;
|
||||
|
||||
// View space point being shaded
|
||||
float3 C = GetPosition(ssC);
|
||||
|
||||
//return abs(float4(C.xyz,0));
|
||||
//if(abs(C.z)<0.31)
|
||||
// return 1;
|
||||
//return abs(C.z);
|
||||
|
||||
packKey(CSZToKey(C.z), fragment.gb);
|
||||
//packKey(CSZToKey(C.z), bilateralKey);
|
||||
|
||||
float randomPatternRotationAngle = 1.0;
|
||||
#ifdef SHADER_API_D3D11
|
||||
int2 ssCInt = ssC.xy * _MainTex_TexelSize.zw;
|
||||
randomPatternRotationAngle = (3 * ssCInt.x ^ ssCInt.y + ssCInt.x * ssCInt.y) * 10;
|
||||
#else
|
||||
// TODO: make dx9 rand better
|
||||
randomPatternRotationAngle = tex2D(_Rand, i.uv*12.0).x * 1000.0;
|
||||
#endif
|
||||
|
||||
// Reconstruct normals from positions. These will lead to 1-pixel black lines
|
||||
// at depth discontinuities, however the blur will wipe those out so they are not visible
|
||||
// in the final image.
|
||||
float3 n_C = ReconstructCSFaceNormal(C);
|
||||
|
||||
//return float4((n_C),0);
|
||||
|
||||
// Choose the screen-space sample _Radius
|
||||
// proportional to the projected area of the sphere
|
||||
float ssDiskRadius = -_Radius / C.z; // -projScale * _Radius / C.z; // <:::::
|
||||
|
||||
float sum = 0.0;
|
||||
for (int l = 0; l < NUM_SAMPLES; ++l) {
|
||||
sum += SampleAO(ssC, C, n_C, (ssDiskRadius), l, randomPatternRotationAngle);
|
||||
}
|
||||
|
||||
float temp = _Radius2 * _Radius;
|
||||
sum /= temp * temp;
|
||||
|
||||
float A = max(0.0, 1.0 - sum * _Intensity * (5.0 / NUM_SAMPLES));
|
||||
fragment.ra = float2(A,A);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
float4 fragUpsample (v2f i) : SV_Target
|
||||
{
|
||||
float4 fragment = fixed4(1,1,1,1);
|
||||
|
||||
// View space point being shaded
|
||||
float3 C = GetPosition(i.uv.xy);
|
||||
|
||||
packKey(CSZToKey(C.z), fragment.gb);
|
||||
fragment.ra = tex2D(_MainTex, i.uv.xy).ra;
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
float4 fragApply (v2f i) : SV_Target
|
||||
{
|
||||
float4 ao = tex2D(_AOTex, i.uv2.xy);
|
||||
return tex2D(_MainTex, i.uv.xy) * ao.rrrr;
|
||||
}
|
||||
|
||||
float4 fragApplySoft (v2f i) : SV_Target
|
||||
{
|
||||
float4 color = tex2D(_MainTex, i.uv.xy);
|
||||
|
||||
float ao = tex2D(_AOTex, i.uv2.xy).r;
|
||||
ao += tex2D(_AOTex, i.uv2.xy + _MainTex_TexelSize.xy * 0.75).r;
|
||||
ao += tex2D(_AOTex, i.uv2.xy - _MainTex_TexelSize.xy * 0.75).r;
|
||||
ao += tex2D(_AOTex, i.uv2.xy + _MainTex_TexelSize.xy * float2(-0.75,0.75)).r;
|
||||
ao += tex2D(_AOTex, i.uv2.xy - _MainTex_TexelSize.xy * float2(-0.75,0.75)).r;
|
||||
|
||||
return color * float4(ao,ao,ao,5)/5;
|
||||
}
|
||||
|
||||
float4 fragBlurBL (v2f i) : SV_Target
|
||||
{
|
||||
float4 fragment = float4(1,1,1,1);
|
||||
|
||||
float2 ssC = i.uv.xy;
|
||||
|
||||
float4 temp = tex2Dlod(_MainTex, float4(i.uv.xy,0,0));
|
||||
|
||||
float2 passthrough2 = temp.gb;
|
||||
float key = UnpackKey(passthrough2);
|
||||
|
||||
float sum = temp.r;
|
||||
|
||||
/*
|
||||
if (key >= 0.999) {
|
||||
// Sky pixel (if you aren't using depth keying, disable this test)
|
||||
fragment.gb = passthrough2;
|
||||
return fragment;
|
||||
}
|
||||
*/
|
||||
|
||||
// Base weight for depth falloff. Increase this for more blurriness, decrease it for better edge discrimination
|
||||
|
||||
float BASE = gaussian[0] * 0.5; // ole: i decreased
|
||||
float totalWeight = BASE;
|
||||
sum *= totalWeight;
|
||||
|
||||
for (int r = -R; r <= R; ++r) {
|
||||
// We already handled the zero case above. This loop should be unrolled and the branch discarded
|
||||
if (r != 0) {
|
||||
temp = tex2Dlod(_MainTex, float4(ssC + _Axis * _MainTex_TexelSize.xy * (r * SCALE),0,0) );
|
||||
float tapKey = UnpackKey(temp.gb);
|
||||
float value = temp.r;
|
||||
|
||||
// spatial domain: offset gaussian tap
|
||||
float weight = 0.3 + gaussian[abs(r)];
|
||||
|
||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
||||
weight *= max(0.0, 1.0 - (2000.0 * EDGE_SHARPNESS) * abs(tapKey - key));
|
||||
|
||||
sum += value * weight;
|
||||
totalWeight += weight;
|
||||
}
|
||||
}
|
||||
|
||||
const float epsilon = 0.0001;
|
||||
fragment = sum / (totalWeight + epsilon);
|
||||
|
||||
fragment.gb = passthrough2;
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader {
|
||||
|
||||
// 0: get ao
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAO
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 1: bilateral blur
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragBlurBL
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 2: apply ao
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragApply
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 3: apply with a slight box filter
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragApplySoft
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 4: in case you want to blur in high rez for nicer z borders
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragUpsample
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95616c020c5604dda96cf76afbbc0272
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,38 @@
|
||||
Shader "Hidden/Sepiatone Effect" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert_img
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
|
||||
fixed4 frag (v2f_img i) : SV_Target
|
||||
{
|
||||
fixed4 original = tex2D(_MainTex, i.uv);
|
||||
|
||||
// get intensity value (Y part of YIQ color space)
|
||||
fixed Y = dot (fixed3(0.299, 0.587, 0.114), original.rgb);
|
||||
|
||||
// Convert to Sepia Tone by adding constant
|
||||
fixed4 sepiaConvert = float4 (0.191, -0.054, -0.221, 0.0);
|
||||
fixed4 output = sepiaConvert + Y;
|
||||
output.a = original.a;
|
||||
|
||||
return output;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6aa781cad112c75d0008dfa8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,56 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
|
||||
Shader "Hidden/ShowAlphaChannel" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_EdgeTex ("_EdgeTex", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform sampler2D _EdgeTex;
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
float filterRadius;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
|
||||
half4 color = tex2D(_MainTex, i.uv.xy);
|
||||
half edges = color.a;
|
||||
|
||||
return edges;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da310021e2a4142429d95c537846dc38
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,43 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
|
||||
Shader "Hidden/SimpleClear" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return half4(0,0,0,0);
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f688f89ed5eb847c5b19c934a0f1e772
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,224 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/SunShaftsComposite" {
|
||||
Properties {
|
||||
_MainTex ("Base", 2D) = "" {}
|
||||
_ColorBuffer ("Color", 2D) = "" {}
|
||||
_Skybox ("Skybox", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
float2 uv1 : TEXCOORD1;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct v2f_radial {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 blurVector : TEXCOORD1;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _ColorBuffer;
|
||||
sampler2D _Skybox;
|
||||
sampler2D_float _CameraDepthTexture;
|
||||
|
||||
uniform half4 _SunThreshold;
|
||||
|
||||
uniform half4 _SunColor;
|
||||
uniform half4 _BlurRadius4;
|
||||
uniform half4 _SunPosition;
|
||||
uniform half4 _MainTex_TexelSize;
|
||||
|
||||
#define SAMPLES_FLOAT 6.0f
|
||||
#define SAMPLES_INT 6
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
o.uv1 = v.texcoord.xy;
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv1.y = 1-o.uv1.y;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragScreen(v2f i) : SV_Target {
|
||||
half4 colorA = tex2D (_MainTex, i.uv.xy);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
half4 colorB = tex2D (_ColorBuffer, i.uv1.xy);
|
||||
#else
|
||||
half4 colorB = tex2D (_ColorBuffer, i.uv.xy);
|
||||
#endif
|
||||
half4 depthMask = saturate (colorB * _SunColor);
|
||||
return 1.0f - (1.0f-colorA) * (1.0f-depthMask);
|
||||
}
|
||||
|
||||
half4 fragAdd(v2f i) : SV_Target {
|
||||
half4 colorA = tex2D (_MainTex, i.uv.xy);
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
half4 colorB = tex2D (_ColorBuffer, i.uv1.xy);
|
||||
#else
|
||||
half4 colorB = tex2D (_ColorBuffer, i.uv.xy);
|
||||
#endif
|
||||
half4 depthMask = saturate (colorB * _SunColor);
|
||||
return colorA + depthMask;
|
||||
}
|
||||
|
||||
v2f_radial vert_radial( appdata_img v ) {
|
||||
v2f_radial o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
|
||||
o.uv.xy = v.texcoord.xy;
|
||||
o.blurVector = (_SunPosition.xy - v.texcoord.xy) * _BlurRadius4.xy;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag_radial(v2f_radial i) : SV_Target
|
||||
{
|
||||
half4 color = half4(0,0,0,0);
|
||||
for(int j = 0; j < SAMPLES_INT; j++)
|
||||
{
|
||||
half4 tmpColor = tex2D(_MainTex, i.uv.xy);
|
||||
color += tmpColor;
|
||||
i.uv.xy += i.blurVector;
|
||||
}
|
||||
return color / SAMPLES_FLOAT;
|
||||
}
|
||||
|
||||
half TransformColor (half4 skyboxValue) {
|
||||
return dot(max(skyboxValue.rgb - _SunThreshold.rgb, half3(0,0,0)), half3(1,1,1)); // threshold and convert to greyscale
|
||||
}
|
||||
|
||||
half4 frag_depth (v2f i) : SV_Target {
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
float depthSample = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv1.xy);
|
||||
#else
|
||||
float depthSample = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv.xy);
|
||||
#endif
|
||||
|
||||
half4 tex = tex2D (_MainTex, i.uv.xy);
|
||||
|
||||
depthSample = Linear01Depth (depthSample);
|
||||
|
||||
// consider maximum radius
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
half2 vec = _SunPosition.xy - i.uv1.xy;
|
||||
#else
|
||||
half2 vec = _SunPosition.xy - i.uv.xy;
|
||||
#endif
|
||||
half dist = saturate (_SunPosition.w - length (vec.xy));
|
||||
|
||||
half4 outColor = 0;
|
||||
|
||||
// consider shafts blockers
|
||||
if (depthSample > 0.99)
|
||||
outColor = TransformColor (tex) * dist;
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
half4 frag_nodepth (v2f i) : SV_Target {
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
float4 sky = (tex2D (_Skybox, i.uv1.xy));
|
||||
#else
|
||||
float4 sky = (tex2D (_Skybox, i.uv.xy));
|
||||
#endif
|
||||
|
||||
float4 tex = (tex2D (_MainTex, i.uv.xy));
|
||||
|
||||
// consider maximum radius
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
half2 vec = _SunPosition.xy - i.uv1.xy;
|
||||
#else
|
||||
half2 vec = _SunPosition.xy - i.uv.xy;
|
||||
#endif
|
||||
half dist = saturate (_SunPosition.w - length (vec));
|
||||
|
||||
half4 outColor = 0;
|
||||
|
||||
// find unoccluded sky pixels
|
||||
// consider pixel values that differ significantly between framebuffer and sky-only buffer as occluded
|
||||
if (Luminance ( abs(sky.rgb - tex.rgb)) < 0.2)
|
||||
outColor = TransformColor (sky) * dist;
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragScreen
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert_radial
|
||||
#pragma fragment frag_radial
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_depth
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag_nodepth
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAdd
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3b1c8c1036784176946f5cfbfb7fe4c
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,356 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Tonemapper" {
|
||||
Properties {
|
||||
_MainTex ("", 2D) = "black" {}
|
||||
_SmallTex ("", 2D) = "grey" {}
|
||||
_Curve ("", 2D) = "black" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _SmallTex;
|
||||
sampler2D _Curve;
|
||||
|
||||
float4 _HdrParams;
|
||||
float2 intensity;
|
||||
float4 _MainTex_TexelSize;
|
||||
float _AdaptionSpeed;
|
||||
float _ExposureAdjustment;
|
||||
float _RangeScale;
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 fragLog(v2f i) : SV_Target
|
||||
{
|
||||
const float DELTA = 0.0001f;
|
||||
|
||||
float fLogLumSum = 0.0f;
|
||||
|
||||
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,-1)).rgb) + DELTA);
|
||||
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,1)).rgb) + DELTA);
|
||||
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,1)).rgb) + DELTA);
|
||||
fLogLumSum += log( Luminance(tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,-1)).rgb) + DELTA);
|
||||
|
||||
float avg = fLogLumSum / 4.0;
|
||||
return float4(avg, avg, avg, avg);
|
||||
}
|
||||
|
||||
float4 fragExp(v2f i) : SV_Target
|
||||
{
|
||||
float2 lum = float2(0.0f, 0.0f);
|
||||
|
||||
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,-1)).xy;
|
||||
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,1)).xy;
|
||||
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(1,-1)).xy;
|
||||
lum += tex2D(_MainTex, i.uv + _MainTex_TexelSize.xy * float2(-1,1)).xy;
|
||||
|
||||
lum = exp(lum / 4.0f);
|
||||
|
||||
return float4(lum.x, lum.y, lum.x, saturate(0.0125 * _AdaptionSpeed));
|
||||
}
|
||||
|
||||
float3 ToCIE(float3 FullScreenImage)
|
||||
{
|
||||
// RGB -> XYZ conversion
|
||||
// http://www.w3.org/Graphics/Color/sRGB
|
||||
// The official sRGB to XYZ conversion matrix is (following ITU-R BT.709)
|
||||
// 0.4125 0.3576 0.1805
|
||||
// 0.2126 0.7152 0.0722
|
||||
// 0.0193 0.1192 0.9505
|
||||
|
||||
float3x3 RGB2XYZ = {0.5141364, 0.3238786, 0.16036376, 0.265068, 0.67023428, 0.06409157, 0.0241188, 0.1228178, 0.84442666};
|
||||
|
||||
float3 XYZ = mul(RGB2XYZ, FullScreenImage.rgb);
|
||||
|
||||
// XYZ -> Yxy conversion
|
||||
|
||||
float3 Yxy;
|
||||
|
||||
Yxy.r = XYZ.g;
|
||||
|
||||
// x = X / (X + Y + Z)
|
||||
// y = X / (X + Y + Z)
|
||||
|
||||
float temp = dot(float3(1.0,1.0,1.0), XYZ.rgb);
|
||||
|
||||
Yxy.gb = XYZ.rg / temp;
|
||||
|
||||
return Yxy;
|
||||
}
|
||||
|
||||
float3 FromCIE(float3 Yxy)
|
||||
{
|
||||
float3 XYZ;
|
||||
// Yxy -> XYZ conversion
|
||||
XYZ.r = Yxy.r * Yxy.g / Yxy. b;
|
||||
|
||||
// X = Y * x / y
|
||||
XYZ.g = Yxy.r;
|
||||
|
||||
// copy luminance Y
|
||||
XYZ.b = Yxy.r * (1 - Yxy.g - Yxy.b) / Yxy.b;
|
||||
|
||||
// Z = Y * (1-x-y) / y
|
||||
|
||||
// XYZ -> RGB conversion
|
||||
// The official XYZ to sRGB conversion matrix is (following ITU-R BT.709)
|
||||
// 3.2410 -1.5374 -0.4986
|
||||
// -0.9692 1.8760 0.0416
|
||||
// 0.0556 -0.2040 1.0570
|
||||
|
||||
float3x3 XYZ2RGB = { 2.5651,-1.1665,-0.3986, -1.0217, 1.9777, 0.0439, 0.0753, -0.2543, 1.1892};
|
||||
|
||||
return mul(XYZ2RGB, XYZ);
|
||||
}
|
||||
|
||||
// NOTE/OPTIMIZATION: we're not going the extra CIE detour anymore, but
|
||||
// scale with the OUT/IN luminance ratio,this is sooooo much faster
|
||||
|
||||
float4 fragAdaptive(v2f i) : SV_Target
|
||||
{
|
||||
float avgLum = tex2D(_SmallTex, i.uv).x;
|
||||
float4 color = tex2D (_MainTex, i.uv);
|
||||
|
||||
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
|
||||
|
||||
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
|
||||
|
||||
lumScaled = (lumScaled * (1.0f + lumScaled / (_HdrParams.w)))/(1.0f + lumScaled);
|
||||
|
||||
//cie.r = lumScaled;
|
||||
|
||||
color.rgb = color.rgb * (lumScaled / cieLum);
|
||||
|
||||
//color.rgb = FromCIE(cie);
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 fragAdaptiveAutoWhite(v2f i) : SV_Target
|
||||
{
|
||||
float2 avgLum = tex2D(_SmallTex, i.uv).xy;
|
||||
float4 color = tex2D(_MainTex, i.uv);
|
||||
|
||||
float cieLum = max(0.000001, Luminance(color.rgb)); //ToCIE(color.rgb);
|
||||
|
||||
float lumScaled = cieLum * _HdrParams.z / (0.001 + avgLum.x);
|
||||
|
||||
lumScaled = (lumScaled * (1.0f + lumScaled / (avgLum.y*avgLum.y)))/(1.0f + lumScaled);
|
||||
|
||||
//cie.r = lumScaled;
|
||||
|
||||
color.rgb = color.rgb * (lumScaled / cieLum);
|
||||
|
||||
//color.rgb = FromCIE(cie);
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 fragCurve(v2f i) : SV_Target
|
||||
{
|
||||
float4 color = tex2D(_MainTex, i.uv);
|
||||
float3 cie = ToCIE(color.rgb);
|
||||
|
||||
// Remap to new lum range
|
||||
float newLum = tex2D(_Curve, float2(cie.r * _RangeScale, 0.5)).r;
|
||||
cie.r = newLum;
|
||||
color.rgb = FromCIE(cie);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 fragHable(v2f i) : SV_Target
|
||||
{
|
||||
const float A = 0.15;
|
||||
const float B = 0.50;
|
||||
const float C = 0.10;
|
||||
const float D = 0.20;
|
||||
const float E = 0.02;
|
||||
const float F = 0.30;
|
||||
const float W = 11.2;
|
||||
|
||||
float3 texColor = tex2D(_MainTex, i.uv).rgb;
|
||||
texColor *= _ExposureAdjustment;
|
||||
|
||||
float ExposureBias = 2.0;
|
||||
float3 x = ExposureBias*texColor;
|
||||
float3 curr = ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
|
||||
|
||||
x = W;
|
||||
float3 whiteScale = 1.0f/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);
|
||||
float3 color = curr*whiteScale;
|
||||
|
||||
// float3 retColor = pow(color,1/2.2); // we have SRGB write enabled at this stage
|
||||
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
|
||||
// we are doing it on luminance here (better color preservation, but some other problems like very fast saturation)
|
||||
float4 fragSimpleReinhard(v2f i) : SV_Target
|
||||
{
|
||||
float4 texColor = tex2D(_MainTex, i.uv);
|
||||
float lum = Luminance(texColor.rgb);
|
||||
float lumTm = lum * _ExposureAdjustment;
|
||||
float scale = lumTm / (1+lumTm);
|
||||
return float4(texColor.rgb * scale / lum, texColor.a);
|
||||
}
|
||||
|
||||
float4 fragOptimizedHejiDawson(v2f i) : SV_Target
|
||||
{
|
||||
float4 texColor = tex2D(_MainTex, i.uv );
|
||||
texColor *= _ExposureAdjustment;
|
||||
float4 X = max(float4(0.0,0.0,0.0,0.0), texColor-0.004);
|
||||
float4 retColor = (X*(6.2*X+.5))/(X*(6.2*X+1.7)+0.06);
|
||||
return retColor*retColor;
|
||||
}
|
||||
|
||||
float4 fragPhotographic(v2f i) : SV_Target
|
||||
{
|
||||
float4 texColor = tex2D(_MainTex, i.uv);
|
||||
return 1-exp2(-_ExposureAdjustment * texColor);
|
||||
}
|
||||
|
||||
float4 fragDownsample(v2f i) : SV_Target
|
||||
{
|
||||
float4 tapA = tex2D(_MainTex, i.uv + _MainTex_TexelSize * 0.5);
|
||||
float4 tapB = tex2D(_MainTex, i.uv - _MainTex_TexelSize * 0.5);
|
||||
float4 tapC = tex2D(_MainTex, i.uv + _MainTex_TexelSize * float2(0.5,-0.5));
|
||||
float4 tapD = tex2D(_MainTex, i.uv - _MainTex_TexelSize * float2(0.5,-0.5));
|
||||
|
||||
float4 average = (tapA+tapB+tapC+tapD)/4;
|
||||
average.y = max(max(tapA.y,tapB.y), max(tapC.y,tapD.y));
|
||||
|
||||
return average;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
// adaptive reinhhard apply
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAdaptive
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 1
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragLog
|
||||
ENDCG
|
||||
}
|
||||
// 2
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragExp
|
||||
ENDCG
|
||||
}
|
||||
// 3
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
Blend Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragExp
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 4 user controllable tonemap curve
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragCurve
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 5 tonemapping in uncharted
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragHable
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 6 simple tonemapping based reinhard
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragSimpleReinhard
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 7 OptimizedHejiDawson
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragOptimizedHejiDawson
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 8 Photographic
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragPhotographic
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 9 Downsample with auto white detection
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDownsample
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 10 adaptive reinhhard apply with auto white
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAdaptiveAutoWhite
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 003377fc2620a44939dadde6fe3f8190
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,54 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Twirt Effect Shader" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
uniform float4 _CenterRadius;
|
||||
uniform float4x4 _RotationMatrix;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord - _CenterRadius.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float2 offset = i.uv;
|
||||
float2 distortedOffset = MultiplyUV (_RotationMatrix, offset.xy);
|
||||
float2 tmp = offset / _CenterRadius.zw;
|
||||
float t = min (1, length(tmp));
|
||||
|
||||
offset = lerp (distortedOffset, offset, t);
|
||||
offset += _CenterRadius.xy;
|
||||
|
||||
return tex2D(_MainTex, offset);
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 641b781cad112c75d0008dfa8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,71 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Vignetting" {
|
||||
Properties {
|
||||
_MainTex ("Base", 2D) = "white" {}
|
||||
_VignetteTex ("Vignette", 2D) = "white" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uv2 : TEXCOORD1;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
sampler2D _VignetteTex;
|
||||
|
||||
half _Intensity;
|
||||
half _Blur;
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
o.uv2 = v.texcoord.xy;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_MainTex_TexelSize.y < 0)
|
||||
o.uv2.y = 1.0 - o.uv2.y;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target {
|
||||
half2 coords = i.uv;
|
||||
half2 uv = i.uv;
|
||||
|
||||
coords = (coords - 0.5) * 2.0;
|
||||
half coordDot = dot (coords,coords);
|
||||
half4 color = tex2D (_MainTex, uv);
|
||||
|
||||
float mask = 1.0 - coordDot * _Intensity;
|
||||
|
||||
half4 colorBlur = tex2D (_VignetteTex, i.uv2);
|
||||
color = lerp (color, colorBlur, saturate (_Blur * coordDot));
|
||||
|
||||
return color * mask;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 627943dc7a9a74286b70a4f694a0acd5
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,67 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Twist Effect" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader
|
||||
{
|
||||
Pass
|
||||
{
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
|
||||
uniform float4 _MainTex_ST;
|
||||
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
uniform float _Angle;
|
||||
uniform float4 _CenterRadius;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float2 uvOrig : TEXCOORD1;
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
float2 uv = v.texcoord.xy - _CenterRadius.xy;
|
||||
o.uv = TRANSFORM_TEX(uv, _MainTex); //MultiplyUV (UNITY_MATRIX_TEXTURE0, uv);
|
||||
o.uvOrig = uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float2 offset = i.uvOrig;
|
||||
float angle = 1.0 - length(offset / _CenterRadius.zw);
|
||||
angle = max (0, angle);
|
||||
angle = angle * angle * _Angle;
|
||||
float cosLength, sinLength;
|
||||
sincos (angle, sinLength, cosLength);
|
||||
|
||||
float2 uv;
|
||||
uv.x = cosLength * offset[0] - sinLength * offset[1];
|
||||
uv.y = sinLength * offset[0] + cosLength * offset[1];
|
||||
uv += _CenterRadius.xy;
|
||||
|
||||
return tex2D(_MainTex, uv);
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 708b781cad112c75d0008dfa8d76c639
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d55b5e91b95c41739cdf4f804dd383d
|
@ -0,0 +1,346 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
//
|
||||
// modified and adapted DLAA code based on Dmitry Andreev's
|
||||
// Directionally Localized Anti-Aliasing (DLAA)
|
||||
//
|
||||
// as seen in "The Force Unleashed 2"
|
||||
//
|
||||
|
||||
Shader "Hidden/DLAA" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
#define LD( o, dx, dy ) o = tex2D( _MainTex, texCoord + float2( dx, dy ) * _MainTex_TexelSize.xy );
|
||||
|
||||
float GetIntensity( float3 col )
|
||||
{
|
||||
return dot( col, float3( 0.33f, 0.33f, 0.33f ) );
|
||||
}
|
||||
|
||||
float4 highPassPre( float2 texCoord )
|
||||
{
|
||||
LD(float4 sCenter, 0.0,0.0)
|
||||
LD(float4 sUpLeft, -1.0,-1.0)
|
||||
LD(float4 sUpRight, 1.0,-1.0)
|
||||
LD(float4 sDownLeft, -1.0,1.0)
|
||||
LD(float4 sDownRight, 1.0,1.0)
|
||||
|
||||
float4 diff = 4.0f * abs( (sUpLeft + sUpRight + sDownLeft + sDownRight) - 4.0f * sCenter );
|
||||
float edgeMask = GetIntensity(diff.xyz);
|
||||
|
||||
return float4(sCenter.rgb, edgeMask);
|
||||
}
|
||||
|
||||
// Softer (5-pixel wide high-pass)
|
||||
/*
|
||||
void HighPassEdgeHV (out float4 edge_h, out float4 edge_v, float4 center, float4 w_h, float4 w_v, float2 texCoord) {
|
||||
edge_h = abs( w_h - 4.0f * center ) / 4.0f;
|
||||
edge_v = abs( w_v - 4.0f * center ) / 4.0f;
|
||||
}
|
||||
|
||||
// Sharper (3-pixel wide high-pass)
|
||||
void EdgeHV (out float4 edge_h, out float4 edge_v, float4 center, float2 texCoord) {
|
||||
float4 left, right, top, bottom;
|
||||
|
||||
LD( left, -1, 0 )
|
||||
LD( right, 1, 0 )
|
||||
LD( top, 0, -1 )
|
||||
LD( bottom, 0, 1 )
|
||||
|
||||
edge_h = abs( left + right - 2.0f * center ) / 2.0f;
|
||||
edge_v = abs( top + bottom - 2.0f * center ) / 2.0f;
|
||||
}
|
||||
*/
|
||||
|
||||
float4 edgeDetectAndBlur( float2 texCoord )
|
||||
{
|
||||
float lambda = 3.0f;
|
||||
float epsilon = 0.1f;
|
||||
|
||||
//
|
||||
// Short Edges
|
||||
//
|
||||
|
||||
float4 center, left_01, right_01, top_01, bottom_01;
|
||||
|
||||
// sample 5x5 cross
|
||||
LD( center, 0, 0 )
|
||||
LD( left_01, -1.5, 0 )
|
||||
LD( right_01, 1.5, 0 )
|
||||
LD( top_01, 0,-1.5 )
|
||||
LD( bottom_01, 0, 1.5 )
|
||||
|
||||
|
||||
float4 w_h = 2.0f * ( left_01 + right_01 );
|
||||
float4 w_v = 2.0f * ( top_01 + bottom_01 );
|
||||
|
||||
|
||||
// Softer (5-pixel wide high-pass)
|
||||
float4 edge_h = abs( w_h - 4.0f * center ) / 4.0f;
|
||||
float4 edge_v = abs( w_v - 4.0f * center ) / 4.0f;
|
||||
|
||||
|
||||
float4 blurred_h = ( w_h + 2.0f * center ) / 6.0f;
|
||||
float4 blurred_v = ( w_v + 2.0f * center ) / 6.0f;
|
||||
|
||||
float edge_h_lum = GetIntensity( edge_h.xyz );
|
||||
float edge_v_lum = GetIntensity( edge_v.xyz );
|
||||
float blurred_h_lum = GetIntensity( blurred_h.xyz );
|
||||
float blurred_v_lum = GetIntensity( blurred_v.xyz );
|
||||
|
||||
float edge_mask_h = saturate( ( lambda * edge_h_lum - epsilon ) / blurred_v_lum );
|
||||
float edge_mask_v = saturate( ( lambda * edge_v_lum - epsilon ) / blurred_h_lum );
|
||||
|
||||
float4 clr = center;
|
||||
clr = lerp( clr, blurred_h, edge_mask_v );
|
||||
clr = lerp( clr, blurred_v, edge_mask_h ); // blurrier version
|
||||
|
||||
//
|
||||
// Long Edges
|
||||
//
|
||||
|
||||
float4 h0, h1, h2, h3, h4, h5, h6, h7;
|
||||
float4 v0, v1, v2, v3, v4, v5, v6, v7;
|
||||
|
||||
// sample 16x16 cross (sparse-sample on X360, incremental kernel update on SPUs)
|
||||
LD( h0, 1.5, 0 ) LD( h1, 3.5, 0 ) LD( h2, 5.5, 0 ) LD( h3, 7.5, 0 ) LD( h4, -1.5,0 ) LD( h5, -3.5,0 ) LD( h6, -5.5,0 ) LD( h7, -7.5,0 )
|
||||
LD( v0, 0, 1.5 ) LD( v1, 0, 3.5 ) LD( v2, 0, 5.5 ) LD( v3, 0, 7.5 ) LD( v4, 0,-1.5 ) LD( v5, 0,-3.5 ) LD( v6, 0,-5.5 ) LD( v7, 0,-7.5 )
|
||||
|
||||
float long_edge_mask_h = ( h0.a + h1.a + h2.a + h3.a + h4.a + h5.a + h6.a + h7.a ) / 8.0f;
|
||||
float long_edge_mask_v = ( v0.a + v1.a + v2.a + v3.a + v4.a + v5.a + v6.a + v7.a ) / 8.0f;
|
||||
|
||||
long_edge_mask_h = saturate( long_edge_mask_h * 2.0f - 1.0f );
|
||||
long_edge_mask_v = saturate( long_edge_mask_v * 2.0f - 1.0f );
|
||||
|
||||
float4 left, right, top, bottom;
|
||||
|
||||
LD( left, -1, 0 )
|
||||
LD( right, 1, 0 )
|
||||
LD( top, 0, -1 )
|
||||
LD( bottom, 0, 1 )
|
||||
|
||||
if ( long_edge_mask_h > 0 || long_edge_mask_v > 0 ) // faster but less resistant to noise (TFU2 X360)
|
||||
//if ( abs( long_edge_mask_h - long_edge_mask_v ) > 0.2f ) // resistant to noise (TFU2 SPUs)
|
||||
{
|
||||
float4 long_blurred_h = ( h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 ) / 8.0f;
|
||||
float4 long_blurred_v = ( v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 ) / 8.0f;
|
||||
|
||||
float lb_h_lum = GetIntensity( long_blurred_h.xyz );
|
||||
float lb_v_lum = GetIntensity( long_blurred_v.xyz );
|
||||
|
||||
float center_lum = GetIntensity( center.xyz );
|
||||
float left_lum = GetIntensity( left.xyz );
|
||||
float right_lum = GetIntensity( right.xyz );
|
||||
float top_lum = GetIntensity( top.xyz );
|
||||
float bottom_lum = GetIntensity( bottom.xyz );
|
||||
|
||||
float4 clr_v = center;
|
||||
float4 clr_h = center;
|
||||
|
||||
// we had to hack this because DIV by 0 gives some artefacts on different platforms
|
||||
float hx = center_lum == top_lum ? 0.0 : saturate( 0 + ( lb_h_lum - top_lum ) / ( center_lum - top_lum ) );
|
||||
float hy = center_lum == bottom_lum ? 0.0 : saturate( 1 + ( lb_h_lum - center_lum ) / ( center_lum - bottom_lum ) );
|
||||
float vx = center_lum == left_lum ? 0.0 : saturate( 0 + ( lb_v_lum - left_lum ) / ( center_lum - left_lum ) );
|
||||
float vy = center_lum == right_lum ? 0.0 : saturate( 1 + ( lb_v_lum - center_lum ) / ( center_lum - right_lum ) );
|
||||
|
||||
float4 vhxy = float4( vx, vy, hx, hy );
|
||||
//vhxy = vhxy == float4( 0, 0, 0, 0 ) ? float4( 1, 1, 1, 1 ) : vhxy;
|
||||
|
||||
clr_v = lerp( left , clr_v, vhxy.x );
|
||||
clr_v = lerp( right , clr_v, vhxy.y );
|
||||
clr_h = lerp( top , clr_h, vhxy.z );
|
||||
clr_h = lerp( bottom, clr_h, vhxy.w );
|
||||
|
||||
clr = lerp( clr, clr_v, long_edge_mask_v );
|
||||
clr = lerp( clr, clr_h, long_edge_mask_h );
|
||||
}
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
float4 edgeDetectAndBlurSharper(float2 texCoord)
|
||||
{
|
||||
float lambda = 3.0f;
|
||||
float epsilon = 0.1f;
|
||||
|
||||
//
|
||||
// Short Edges
|
||||
//
|
||||
|
||||
float4 center, left_01, right_01, top_01, bottom_01;
|
||||
|
||||
// sample 5x5 cross
|
||||
LD( center, 0, 0 )
|
||||
LD( left_01, -1.5, 0 )
|
||||
LD( right_01, 1.5, 0 )
|
||||
LD( top_01, 0,-1.5 )
|
||||
LD( bottom_01, 0, 1.5 )
|
||||
|
||||
|
||||
float4 w_h = 2.0f * ( left_01 + right_01 );
|
||||
float4 w_v = 2.0f * ( top_01 + bottom_01 );
|
||||
|
||||
// Sharper (3-pixel wide high-pass)
|
||||
float4 left, right, top, bottom;
|
||||
|
||||
LD( left, -1, 0 )
|
||||
LD( right, 1, 0 )
|
||||
LD( top, 0, -1 )
|
||||
LD( bottom, 0, 1 )
|
||||
|
||||
float4 edge_h = abs( left + right - 2.0f * center ) / 2.0f;
|
||||
float4 edge_v = abs( top + bottom - 2.0f * center ) / 2.0f;
|
||||
|
||||
float4 blurred_h = ( w_h + 2.0f * center ) / 6.0f;
|
||||
float4 blurred_v = ( w_v + 2.0f * center ) / 6.0f;
|
||||
|
||||
float edge_h_lum = GetIntensity( edge_h.xyz );
|
||||
float edge_v_lum = GetIntensity( edge_v.xyz );
|
||||
float blurred_h_lum = GetIntensity( blurred_h.xyz );
|
||||
float blurred_v_lum = GetIntensity( blurred_v.xyz );
|
||||
|
||||
float edge_mask_h = saturate( ( lambda * edge_h_lum - epsilon ) / blurred_v_lum );
|
||||
float edge_mask_v = saturate( ( lambda * edge_v_lum - epsilon ) / blurred_h_lum );
|
||||
|
||||
float4 clr = center;
|
||||
clr = lerp( clr, blurred_h, edge_mask_v );
|
||||
clr = lerp( clr, blurred_v, edge_mask_h * 0.5f ); // TFU2 uses 1.0f instead of 0.5f
|
||||
|
||||
//
|
||||
// Long Edges
|
||||
//
|
||||
|
||||
float4 h0, h1, h2, h3, h4, h5, h6, h7;
|
||||
float4 v0, v1, v2, v3, v4, v5, v6, v7;
|
||||
|
||||
// sample 16x16 cross (sparse-sample on X360, incremental kernel update on SPUs)
|
||||
LD( h0, 1.5, 0 ) LD( h1, 3.5, 0 ) LD( h2, 5.5, 0 ) LD( h3, 7.5, 0 ) LD( h4, -1.5,0 ) LD( h5, -3.5,0 ) LD( h6, -5.5,0 ) LD( h7, -7.5,0 )
|
||||
LD( v0, 0, 1.5 ) LD( v1, 0, 3.5 ) LD( v2, 0, 5.5 ) LD( v3, 0, 7.5 ) LD( v4, 0,-1.5 ) LD( v5, 0,-3.5 ) LD( v6, 0,-5.5 ) LD( v7, 0,-7.5 )
|
||||
|
||||
float long_edge_mask_h = ( h0.a + h1.a + h2.a + h3.a + h4.a + h5.a + h6.a + h7.a ) / 8.0f;
|
||||
float long_edge_mask_v = ( v0.a + v1.a + v2.a + v3.a + v4.a + v5.a + v6.a + v7.a ) / 8.0f;
|
||||
|
||||
long_edge_mask_h = saturate( long_edge_mask_h * 2.0f - 1.0f );
|
||||
long_edge_mask_v = saturate( long_edge_mask_v * 2.0f - 1.0f );
|
||||
|
||||
//if ( long_edge_mask_h > 0 || long_edge_mask_v > 0 ) // faster but less resistant to noise (TFU2 X360)
|
||||
if ( abs( long_edge_mask_h - long_edge_mask_v ) > 0.2f ) // resistant to noise (TFU2 SPUs)
|
||||
{
|
||||
float4 long_blurred_h = ( h0 + h1 + h2 + h3 + h4 + h5 + h6 + h7 ) / 8.0f;
|
||||
float4 long_blurred_v = ( v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 ) / 8.0f;
|
||||
|
||||
float lb_h_lum = GetIntensity( long_blurred_h.xyz );
|
||||
float lb_v_lum = GetIntensity( long_blurred_v.xyz );
|
||||
|
||||
float center_lum = GetIntensity( center.xyz );
|
||||
float left_lum = GetIntensity( left.xyz );
|
||||
float right_lum = GetIntensity( right.xyz );
|
||||
float top_lum = GetIntensity( top.xyz );
|
||||
float bottom_lum = GetIntensity( bottom.xyz );
|
||||
|
||||
float4 clr_v = center;
|
||||
float4 clr_h = center;
|
||||
|
||||
// we had to hack this because DIV by 0 gives some artefacts on different platforms
|
||||
float hx = center_lum == top_lum ? 0.0 : saturate( 0 + ( lb_h_lum - top_lum ) / ( center_lum - top_lum ) );
|
||||
float hy = center_lum == bottom_lum ? 0.0 : saturate( 1 + ( lb_h_lum - center_lum ) / ( center_lum - bottom_lum ) );
|
||||
float vx = center_lum == left_lum ? 0.0 : saturate( 0 + ( lb_v_lum - left_lum ) / ( center_lum - left_lum ) );
|
||||
float vy = center_lum == right_lum ? 0.0 : saturate( 1 + ( lb_v_lum - center_lum ) / ( center_lum - right_lum ) );
|
||||
|
||||
float4 vhxy = float4( vx, vy, hx, hy );
|
||||
//vhxy = vhxy == float4( 0, 0, 0, 0 ) ? float4( 1, 1, 1, 1 ) : vhxy;
|
||||
|
||||
clr_v = lerp( left , clr_v, vhxy.x );
|
||||
clr_v = lerp( right , clr_v, vhxy.y );
|
||||
clr_h = lerp( top , clr_h, vhxy.z );
|
||||
clr_h = lerp( bottom, clr_h, vhxy.w );
|
||||
|
||||
clr = lerp( clr, clr_v, long_edge_mask_v );
|
||||
clr = lerp( clr, clr_h, long_edge_mask_h );
|
||||
}
|
||||
|
||||
return clr;
|
||||
}
|
||||
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
o.uv.xy = uv;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragFirst (v2f i) : SV_Target {
|
||||
return highPassPre (i.uv);
|
||||
}
|
||||
|
||||
half4 fragSecond (v2f i) : SV_Target {
|
||||
return edgeDetectAndBlur( i.uv );
|
||||
}
|
||||
|
||||
half4 fragThird (v2f i) : SV_Target {
|
||||
return edgeDetectAndBlurSharper( i.uv );
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragFirst
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragSecond
|
||||
#pragma target 3.0
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
|
||||
ENDCG
|
||||
}
|
||||
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragThird
|
||||
#pragma target 3.0
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 017ca72b9e8a749058d13ebd527e98fa
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,189 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/FXAA II" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
#pragma target 3.0
|
||||
|
||||
#define FXAA_HLSL_3 1
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA v2 CONSOLE by TIMOTHY LOTTES @ NVIDIA
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*============================================================================
|
||||
API PORTING
|
||||
============================================================================*/
|
||||
#ifndef FXAA_GLSL_120
|
||||
#define FXAA_GLSL_120 0
|
||||
#endif
|
||||
#ifndef FXAA_GLSL_130
|
||||
#define FXAA_GLSL_130 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_3
|
||||
#define FXAA_HLSL_3 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_120
|
||||
// Requires,
|
||||
// #version 120
|
||||
// #extension GL_EXT_gpu_shader4 : enable
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaSat(a) clamp((a), 0.0, 1.0)
|
||||
#define FxaaTex sampler2D
|
||||
#define FxaaTexLod0(t, p) texture2DLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_130
|
||||
// Requires "#version 130" or better
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaSat(a) clamp((a), 0.0, 1.0)
|
||||
#define FxaaTex sampler2D
|
||||
#define FxaaTexLod0(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_3
|
||||
#define int2 float2
|
||||
#define FxaaInt2 float2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaSat(a) saturate((a))
|
||||
#define FxaaTex sampler2D
|
||||
#define FxaaTexLod0(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
|
||||
#define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_4
|
||||
#define FxaaInt2 int2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaSat(a) saturate((a))
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#define FxaaTexLod0(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
|
||||
#endif
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
VERTEX SHADER
|
||||
|
||||
============================================================================*/
|
||||
float4 FxaaVertexShader(
|
||||
float2 pos, // Both x and y range {-1.0 to 1.0 across screen}.
|
||||
float2 rcpFrame) { // {1.0/frameWidth, 1.0/frameHeight}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FXAA_SUBPIX_SHIFT (1.0/4.0)
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 posPos;
|
||||
posPos.xy = (pos.xy * 0.5) + 0.5;
|
||||
posPos.zw = posPos.xy - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT));
|
||||
return posPos; }
|
||||
|
||||
/*============================================================================
|
||||
|
||||
PIXEL SHADER
|
||||
|
||||
============================================================================*/
|
||||
float3 FxaaPixelShader(
|
||||
float4 posPos, // Output of FxaaVertexShader interpolated across screen.
|
||||
FxaaTex tex, // Input texture.
|
||||
float2 rcpFrame) { // Constant {1.0/frameWidth, 1.0/frameHeight}.
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FXAA_REDUCE_MIN (1.0/128.0)
|
||||
#define FXAA_REDUCE_MUL (1.0/8.0)
|
||||
#define FXAA_SPAN_MAX 8.0
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float3 rgbNW = FxaaTexLod0(tex, posPos.zw).xyz;
|
||||
float3 rgbNE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,0), rcpFrame.xy).xyz;
|
||||
float3 rgbSW = FxaaTexOff(tex, posPos.zw, FxaaInt2(0,1), rcpFrame.xy).xyz;
|
||||
float3 rgbSE = FxaaTexOff(tex, posPos.zw, FxaaInt2(1,1), rcpFrame.xy).xyz;
|
||||
float3 rgbM = FxaaTexLod0(tex, posPos.xy).xyz;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float3 luma = float3(0.299, 0.587, 0.114);
|
||||
float lumaNW = dot(rgbNW, luma);
|
||||
float lumaNE = dot(rgbNE, luma);
|
||||
float lumaSW = dot(rgbSW, luma);
|
||||
float lumaSE = dot(rgbSE, luma);
|
||||
float lumaM = dot(rgbM, luma);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float2 dir;
|
||||
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float dirReduce = max(
|
||||
(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
|
||||
FXAA_REDUCE_MIN);
|
||||
float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||
dir = min(FxaaFloat2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||
max(FxaaFloat2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
|
||||
dir * rcpDirMin)) * rcpFrame.xy;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float3 rgbA = (1.0/2.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (1.0/3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (2.0/3.0 - 0.5)).xyz);
|
||||
float3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (0.0/3.0 - 0.5)).xyz +
|
||||
FxaaTexLod0(tex, posPos.xy + dir * (3.0/3.0 - 0.5)).xyz);
|
||||
float lumaB = dot(rgbB, luma);
|
||||
if((lumaB < lumaMin) || (lumaB > lumaMax)) return rgbA;
|
||||
return rgbB; }
|
||||
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float4 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = FxaaVertexShader (v.texcoord.xy*2-1, _MainTex_TexelSize.xy);
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return float4(FxaaPixelShader(i.uv, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd5b323dcc592457790ff18b528f5e67
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,174 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
|
||||
/*============================================================================
|
||||
|
||||
source taken from
|
||||
|
||||
|
||||
NVIDIA FXAA 3.11 by TIMOTHY LOTTES
|
||||
|
||||
|
||||
and adapted and ported to Unity by Unity Technologies
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.
|
||||
------------------------------------------------------------------------------
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
|
||||
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA
|
||||
OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
|
||||
LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
|
||||
OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
|
||||
THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
|
||||
Shader "Hidden/FXAA III (Console)" {
|
||||
Properties {
|
||||
_MainTex ("-", 2D) = "white" {}
|
||||
_EdgeThresholdMin ("Edge threshold min",float) = 0.125
|
||||
_EdgeThreshold("Edge Threshold", float) = 0.25
|
||||
_EdgeSharpness("Edge sharpness",float) = 4.0
|
||||
}
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform half _EdgeThresholdMin;
|
||||
uniform half _EdgeThreshold;
|
||||
uniform half _EdgeSharpness;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 interpolatorA : TEXCOORD1;
|
||||
float4 interpolatorB : TEXCOORD2;
|
||||
float4 interpolatorC : TEXCOORD3;
|
||||
};
|
||||
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
o.uv = v.texcoord.xy;
|
||||
|
||||
float4 extents;
|
||||
float2 offset = ( _MainTex_TexelSize.xy ) * 0.5f;
|
||||
extents.xy = v.texcoord.xy - offset;
|
||||
extents.zw = v.texcoord.xy + offset;
|
||||
|
||||
float4 rcpSize;
|
||||
rcpSize.xy = -_MainTex_TexelSize.xy * 0.5f;
|
||||
rcpSize.zw = _MainTex_TexelSize.xy * 0.5f;
|
||||
#if defined (SHADER_API_PSP2)
|
||||
//cg compiler linker bug workaround
|
||||
float almostzero = v.texcoord.x*0.000001f;
|
||||
rcpSize.x += almostzero;
|
||||
#endif
|
||||
o.interpolatorA = extents;
|
||||
o.interpolatorB = rcpSize;
|
||||
o.interpolatorC = rcpSize;
|
||||
|
||||
o.interpolatorC.xy *= 4.0;
|
||||
o.interpolatorC.zw *= 4.0;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
// hacky support for NaCl
|
||||
#if defined(SHADER_API_GLES) && defined(SHADER_API_DESKTOP)
|
||||
#define FxaaTexTop(t, p) tex2D(t, p)
|
||||
#else
|
||||
#define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
|
||||
#endif
|
||||
|
||||
inline half TexLuminance( float2 uv )
|
||||
{
|
||||
return Luminance(FxaaTexTop(_MainTex, uv).rgb);
|
||||
}
|
||||
|
||||
half3 FxaaPixelShader(float2 pos, float4 extents, float4 rcpSize, float4 rcpSize2)
|
||||
{
|
||||
half lumaNw = TexLuminance(extents.xy);
|
||||
half lumaSw = TexLuminance(extents.xw);
|
||||
half lumaNe = TexLuminance(extents.zy);
|
||||
half lumaSe = TexLuminance(extents.zw);
|
||||
|
||||
half3 centre = FxaaTexTop(_MainTex, pos).rgb;
|
||||
half lumaCentre = Luminance(centre);
|
||||
|
||||
half lumaMaxNwSw = max( lumaNw , lumaSw );
|
||||
lumaNe += 1.0/384.0;
|
||||
half lumaMinNwSw = min( lumaNw , lumaSw );
|
||||
|
||||
half lumaMaxNeSe = max( lumaNe , lumaSe );
|
||||
half lumaMinNeSe = min( lumaNe , lumaSe );
|
||||
|
||||
half lumaMax = max( lumaMaxNeSe, lumaMaxNwSw );
|
||||
half lumaMin = min( lumaMinNeSe, lumaMinNwSw );
|
||||
|
||||
half lumaMaxScaled = lumaMax * _EdgeThreshold;
|
||||
|
||||
half lumaMinCentre = min( lumaMin , lumaCentre );
|
||||
half lumaMaxScaledClamped = max( _EdgeThresholdMin , lumaMaxScaled );
|
||||
half lumaMaxCentre = max( lumaMax , lumaCentre );
|
||||
half dirSWMinusNE = lumaSw - lumaNe;
|
||||
half lumaMaxCMinusMinC = lumaMaxCentre - lumaMinCentre;
|
||||
half dirSEMinusNW = lumaSe - lumaNw;
|
||||
|
||||
if(lumaMaxCMinusMinC < lumaMaxScaledClamped)
|
||||
return centre;
|
||||
|
||||
half2 dir;
|
||||
dir.x = dirSWMinusNE + dirSEMinusNW;
|
||||
dir.y = dirSWMinusNE - dirSEMinusNW;
|
||||
|
||||
dir = normalize(dir);
|
||||
half3 col1 = FxaaTexTop(_MainTex, pos.xy - dir * rcpSize.zw).rgb;
|
||||
half3 col2 = FxaaTexTop(_MainTex, pos.xy + dir * rcpSize.zw).rgb;
|
||||
|
||||
half dirAbsMinTimesC = min( abs( dir.x ) , abs( dir.y ) ) * _EdgeSharpness;
|
||||
dir = clamp(dir.xy/dirAbsMinTimesC, -2.0, 2.0);
|
||||
|
||||
half3 col3 = FxaaTexTop(_MainTex, pos.xy - dir * rcpSize2.zw).rgb;
|
||||
half3 col4 = FxaaTexTop(_MainTex, pos.xy + dir * rcpSize2.zw).rgb;
|
||||
|
||||
half3 rgbyA = col1 + col2;
|
||||
half3 rgbyB = ((col3 + col4) * 0.25) + (rgbyA * 0.25);
|
||||
|
||||
if((Luminance(rgbyA) < lumaMin) || (Luminance(rgbyB) > lumaMax))
|
||||
return rgbyA * 0.5;
|
||||
else
|
||||
return rgbyB;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
half3 color = FxaaPixelShader(i.uv, i.interpolatorA, i.interpolatorB, i.interpolatorC);
|
||||
return half4(color, 1.0);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
FallBack Off
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c547503fff0e8482ea5793727057041c
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,829 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/FXAA Preset 2" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
#pragma target 3.0
|
||||
|
||||
// doesn't make sense to have this on consoles, it'll fallback to FXAA2
|
||||
#pragma exclude_renderers xbox360 ps3 gles
|
||||
|
||||
|
||||
#define FXAA_HLSL_3 1
|
||||
#define FXAA_PRESET 2
|
||||
|
||||
|
||||
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
|
||||
//
|
||||
// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
|
||||
// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
|
||||
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
|
||||
// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
||||
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
|
||||
// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
|
||||
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*============================================================================
|
||||
API PORTING
|
||||
============================================================================*/
|
||||
#ifndef FXAA_GLSL_120
|
||||
#define FXAA_GLSL_120 0
|
||||
#endif
|
||||
#ifndef FXAA_GLSL_130
|
||||
#define FXAA_GLSL_130 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_3
|
||||
#define FXAA_HLSL_3 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_120
|
||||
// Requires,
|
||||
// #version 120
|
||||
// #extension GL_EXT_gpu_shader4 : enable
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaBool3 bvec3
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) mix((f), (t), (b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_130
|
||||
// Requires "#version 130" or better
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaBool3 bvec3
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) mix((f), (t), (b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_3
|
||||
#define int2 float2
|
||||
#define FxaaInt2 float2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaFloat3 float3
|
||||
#define FxaaFloat4 float4
|
||||
#define FxaaBool2Float(a) (a)
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_4
|
||||
#define FxaaInt2 int2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaFloat3 float3
|
||||
#define FxaaFloat4 float4
|
||||
#define FxaaBool2Float(a) (a)
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexLod0(FxaaTex tex, float2 pos) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DLod(tex, pos.xy, 0.0);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureLod(tex, pos.xy, 0.0);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0);
|
||||
#endif
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DGrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureGrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dgrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleGrad(tex.smpl, pos.xy, grad, grad);
|
||||
#endif
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DLodOffset(tex, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureLodOffset(tex, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dlod(tex, float4(pos.xy + (off * rcpFrame), 0, 0));
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
SRGB KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
|
||||
This will do the sRGB to linear transform,
|
||||
as ROP will expect linear color from this shader,
|
||||
and this shader works in non-linear color.
|
||||
============================================================================*/
|
||||
#define FXAA_SRGB_ROP 0
|
||||
|
||||
/*============================================================================
|
||||
DEBUG KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
|
||||
|
||||
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
|
||||
yellow tint on sub-pixel aliasing filtered by FXAA.
|
||||
FXAA_DEBUG_HORZVERT - Blue for horizontal edges, gold for vertical edges.
|
||||
FXAA_DEBUG_PAIR - Blue/green for the 2 pixel pair choice.
|
||||
FXAA_DEBUG_NEGPOS - Red/blue for which side of center of span.
|
||||
FXAA_DEBUG_OFFSET - Red/blue for -/+ x, gold/skyblue for -/+ y.
|
||||
============================================================================*/
|
||||
#ifndef FXAA_DEBUG_PASSTHROUGH
|
||||
#define FXAA_DEBUG_PASSTHROUGH 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_HORZVERT
|
||||
#define FXAA_DEBUG_HORZVERT 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_PAIR
|
||||
#define FXAA_DEBUG_PAIR 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_NEGPOS
|
||||
#define FXAA_DEBUG_NEGPOS 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_OFFSET
|
||||
#define FXAA_DEBUG_OFFSET 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
|
||||
#define FXAA_DEBUG 1
|
||||
#endif
|
||||
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
|
||||
#define FXAA_DEBUG 1
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG
|
||||
#define FXAA_DEBUG 0
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
COMPILE-IN KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_PRESET - Choose compile-in knob preset 0-5.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
|
||||
to apply algorithm.
|
||||
1.0/3.0 - too little
|
||||
1.0/4.0 - good start
|
||||
1.0/8.0 - applies to more edges
|
||||
1.0/16.0 - overkill
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
|
||||
Perf optimization.
|
||||
1.0/32.0 - visible limit (smaller isn't visible)
|
||||
1.0/16.0 - good compromise
|
||||
1.0/12.0 - upper limit (seeing artifacts)
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
|
||||
1 - no acceleration
|
||||
2 - skip by 2 pixels
|
||||
3 - skip by 3 pixels
|
||||
4 - skip by 4 pixels
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
|
||||
1.0/4.0 - seems to be the best quality wise
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
|
||||
Not recomended, but used in preset 0.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX - Toggle subpix filtering.
|
||||
0 - turn off
|
||||
1 - turn on
|
||||
2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
|
||||
1.0/2.0 - low removal
|
||||
1.0/3.0 - medium removal
|
||||
1.0/4.0 - default removal
|
||||
1.0/8.0 - high removal
|
||||
0.0 - complete removal
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
|
||||
This is important for the transition of sub-pixel detail,
|
||||
like fences and wires.
|
||||
3.0/4.0 - default (medium amount of filtering)
|
||||
7.0/8.0 - high amount of filtering
|
||||
1.0 - no capping of sub-pixel aliasing removal
|
||||
============================================================================*/
|
||||
#ifndef FXAA_PRESET
|
||||
#define FXAA_PRESET 3
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 0)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
|
||||
#define FXAA_SEARCH_STEPS 2
|
||||
#define FXAA_SEARCH_ACCELERATION 4
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 1
|
||||
#define FXAA_SUBPIX_CAP (2.0/3.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 1)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
|
||||
#define FXAA_SEARCH_STEPS 4
|
||||
#define FXAA_SEARCH_ACCELERATION 3
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 2)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 8
|
||||
#define FXAA_SEARCH_ACCELERATION 2
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 3)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 16
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 4)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 24
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 5)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 32
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
|
||||
|
||||
/*============================================================================
|
||||
HELPERS
|
||||
============================================================================*/
|
||||
// Return the luma, the estimation of luminance from rgb inputs.
|
||||
// This approximates luma using one FMA instruction,
|
||||
// skipping normalization and tossing out blue.
|
||||
// FxaaLuma() will range 0.0 to 2.963210702.
|
||||
float FxaaLuma(float3 rgb) {
|
||||
return rgb.y * (0.587/0.299) + rgb.x; }
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
|
||||
return (FxaaToFloat3(-amountOfA) * b) +
|
||||
((a * FxaaToFloat3(amountOfA)) + b); }
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// Support any extra filtering before returning color.
|
||||
float3 FxaaFilterReturn(float3 rgb) {
|
||||
#if FXAA_SRGB_ROP
|
||||
// Do sRGB encoded value to linear conversion.
|
||||
return FxaaSel3(
|
||||
rgb * FxaaToFloat3(1.0/12.92),
|
||||
FxaaPow3(
|
||||
rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
|
||||
FxaaToFloat3(2.4)),
|
||||
rgb > FxaaToFloat3(0.04045));
|
||||
#else
|
||||
return rgb;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
VERTEX SHADER
|
||||
============================================================================*/
|
||||
float2 FxaaVertexShader(
|
||||
// Both x and y range {-1.0 to 1.0 across screen}.
|
||||
float2 inPos) {
|
||||
float2 pos;
|
||||
pos.xy = (inPos.xy * FxaaFloat2(0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
|
||||
return pos; }
|
||||
|
||||
/*============================================================================
|
||||
|
||||
PIXEL SHADER
|
||||
|
||||
============================================================================*/
|
||||
float3 FxaaPixelShader(
|
||||
// Output of FxaaVertexShader interpolated across screen.
|
||||
// xy -> actual texture position {0.0 to 1.0}
|
||||
float2 pos,
|
||||
// Input texture.
|
||||
FxaaTex tex,
|
||||
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// {1.0/frameWidth, 1.0/frameHeight}
|
||||
float2 rcpFrame) {
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
|
||||
------------------------------------------------------------------------------
|
||||
Majority of pixels of a typical image do not require filtering,
|
||||
often pixels are grouped into blocks which could benefit from early exit
|
||||
right at the beginning of the algorithm.
|
||||
Given the following neighborhood,
|
||||
|
||||
N
|
||||
W M E
|
||||
S
|
||||
|
||||
If the difference in local maximum and minimum luma (contrast "range")
|
||||
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
|
||||
then the shader early exits (no visible aliasing).
|
||||
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
|
||||
to avoid processing in really dark areas.
|
||||
----------------------------------------------------------------------------*/
|
||||
float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
|
||||
float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
|
||||
float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
|
||||
float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
|
||||
float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
|
||||
float lumaN = FxaaLuma(rgbN);
|
||||
float lumaW = FxaaLuma(rgbW);
|
||||
float lumaM = FxaaLuma(rgbM);
|
||||
float lumaE = FxaaLuma(rgbE);
|
||||
float lumaS = FxaaLuma(rgbS);
|
||||
float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
|
||||
float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
|
||||
float range = rangeMax - rangeMin;
|
||||
#if FXAA_DEBUG
|
||||
float lumaO = lumaM / (1.0 + (0.587/0.299));
|
||||
#endif
|
||||
if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
|
||||
#if FXAA_DEBUG
|
||||
return FxaaFilterReturn(FxaaToFloat3(lumaO));
|
||||
#endif
|
||||
return FxaaFilterReturn(rgbM); }
|
||||
#if FXAA_SUBPIX > 0
|
||||
#if FXAA_SUBPIX_FASTER
|
||||
float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
|
||||
FxaaToFloat3(1.0/5.0);
|
||||
#else
|
||||
float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
COMPUTE LOWPASS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA computes a local neighborhood lowpass value as follows,
|
||||
|
||||
(N + W + E + S)/4
|
||||
|
||||
Then uses the ratio of the contrast range of the lowpass
|
||||
and the range found in the early exit check,
|
||||
as a sub-pixel aliasing detection filter.
|
||||
When FXAA detects sub-pixel aliasing (such as single pixel dots),
|
||||
it later blends in "blendL" amount
|
||||
of a lowpass value (computed in the next section) to the final result.
|
||||
----------------------------------------------------------------------------*/
|
||||
#if FXAA_SUBPIX != 0
|
||||
float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
|
||||
float rangeL = abs(lumaL - lumaM);
|
||||
#endif
|
||||
#if FXAA_SUBPIX == 1
|
||||
float blendL = max(0.0,
|
||||
(rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
|
||||
blendL = min(FXAA_SUBPIX_CAP, blendL);
|
||||
#endif
|
||||
#if FXAA_SUBPIX == 2
|
||||
float blendL = rangeL / range;
|
||||
#endif
|
||||
#if FXAA_DEBUG_PASSTHROUGH
|
||||
#if FXAA_SUBPIX == 0
|
||||
float blendL = 0.0;
|
||||
#endif
|
||||
return FxaaFilterReturn(
|
||||
FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE VERTICAL OR HORIZONTAL SEARCH
|
||||
------------------------------------------------------------------------------
|
||||
FXAA uses the following local neighborhood,
|
||||
|
||||
NW N NE
|
||||
W M E
|
||||
SW S SE
|
||||
|
||||
To compute an edge amount for both vertical and horizontal directions.
|
||||
Note edge detect filters like Sobel fail on single pixel lines through M.
|
||||
FXAA takes the weighted average magnitude of the high-pass values
|
||||
for rows and columns as an indication of local edge amount.
|
||||
|
||||
A lowpass value for anti-sub-pixel-aliasing is computed as
|
||||
(N+W+E+S+M+NW+NE+SW+SE)/9.
|
||||
This full box pattern has higher quality than other options.
|
||||
|
||||
Note following this block, both vertical and horizontal cases
|
||||
flow in parallel (reusing the horizontal variables).
|
||||
----------------------------------------------------------------------------*/
|
||||
float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
|
||||
float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
|
||||
float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
|
||||
float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
|
||||
#if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
|
||||
rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
|
||||
rgbL *= FxaaToFloat3(1.0/9.0);
|
||||
#endif
|
||||
float lumaNW = FxaaLuma(rgbNW);
|
||||
float lumaNE = FxaaLuma(rgbNE);
|
||||
float lumaSW = FxaaLuma(rgbSW);
|
||||
float lumaSE = FxaaLuma(rgbSE);
|
||||
float edgeVert =
|
||||
abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
|
||||
abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
|
||||
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
|
||||
float edgeHorz =
|
||||
abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
|
||||
abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
|
||||
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
|
||||
bool horzSpan = edgeHorz >= edgeVert;
|
||||
#if FXAA_DEBUG_HORZVERT
|
||||
if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
|
||||
#endif
|
||||
float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
|
||||
if(!horzSpan) lumaN = lumaW;
|
||||
if(!horzSpan) lumaS = lumaE;
|
||||
float gradientN = abs(lumaN - lumaM);
|
||||
float gradientS = abs(lumaS - lumaM);
|
||||
lumaN = (lumaN + lumaM) * 0.5;
|
||||
lumaS = (lumaS + lumaM) * 0.5;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
|
||||
------------------------------------------------------------------------------
|
||||
This chooses a pixel pair.
|
||||
For "horzSpan == true" this will be a vertical pair,
|
||||
|
||||
[N] N
|
||||
[M] or [M]
|
||||
S [S]
|
||||
|
||||
Note following this block, both {N,M} and {S,M} cases
|
||||
flow in parallel (reusing the {N,M} variables).
|
||||
|
||||
This pair of image rows or columns is searched below
|
||||
in the positive and negative direction
|
||||
until edge status changes
|
||||
(or the maximum number of search steps is reached).
|
||||
----------------------------------------------------------------------------*/
|
||||
bool pairN = gradientN >= gradientS;
|
||||
#if FXAA_DEBUG_PAIR
|
||||
if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
|
||||
#endif
|
||||
if(!pairN) lumaN = lumaS;
|
||||
if(!pairN) gradientN = gradientS;
|
||||
if(!pairN) lengthSign *= -1.0;
|
||||
float2 posN;
|
||||
posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
|
||||
posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE SEARCH LIMITING VALUES
|
||||
------------------------------------------------------------------------------
|
||||
Search limit (+/- gradientN) is a function of local gradient.
|
||||
----------------------------------------------------------------------------*/
|
||||
gradientN *= FXAA_SEARCH_THRESHOLD;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
|
||||
------------------------------------------------------------------------------
|
||||
This loop searches either in vertical or horizontal directions,
|
||||
and in both the negative and positive direction in parallel.
|
||||
This loop fusion is faster than searching separately.
|
||||
|
||||
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
|
||||
via anisotropic filtering with specified texture gradients.
|
||||
----------------------------------------------------------------------------*/
|
||||
float2 posP = posN;
|
||||
float2 offNP = horzSpan ?
|
||||
FxaaFloat2(rcpFrame.x, 0.0) :
|
||||
FxaaFloat2(0.0f, rcpFrame.y);
|
||||
float lumaEndN = lumaN;
|
||||
float lumaEndP = lumaN;
|
||||
bool doneN = false;
|
||||
bool doneP = false;
|
||||
#if FXAA_SEARCH_ACCELERATION == 1
|
||||
posN += offNP * FxaaFloat2(-1.0, -1.0);
|
||||
posP += offNP * FxaaFloat2( 1.0, 1.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 2
|
||||
posN += offNP * FxaaFloat2(-1.5, -1.5);
|
||||
posP += offNP * FxaaFloat2( 1.5, 1.5);
|
||||
offNP *= FxaaFloat2(2.0, 2.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 3
|
||||
posN += offNP * FxaaFloat2(-2.0, -2.0);
|
||||
posP += offNP * FxaaFloat2( 2.0, 2.0);
|
||||
offNP *= FxaaFloat2(3.0, 3.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 4
|
||||
posN += offNP * FxaaFloat2(-2.5, -2.5);
|
||||
posP += offNP * FxaaFloat2( 2.5, 2.5);
|
||||
offNP *= FxaaFloat2(4.0, 4.0);
|
||||
#endif
|
||||
for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
|
||||
#if FXAA_SEARCH_ACCELERATION == 1
|
||||
if(!doneN) lumaEndN =
|
||||
FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
|
||||
if(!doneP) lumaEndP =
|
||||
FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
|
||||
#else
|
||||
if(!doneN) lumaEndN =
|
||||
FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
|
||||
if(!doneP) lumaEndP =
|
||||
FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
|
||||
#endif
|
||||
doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
|
||||
doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
|
||||
if(doneN && doneP) break;
|
||||
if(!doneN) posN -= offNP;
|
||||
if(!doneP) posP += offNP; }
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
|
||||
------------------------------------------------------------------------------
|
||||
FXAA uses the pixel's position in the span
|
||||
in combination with the values (lumaEnd*) at the ends of the span,
|
||||
to determine filtering.
|
||||
|
||||
This step computes which side of the span the pixel is on.
|
||||
On negative side if dstN < dstP,
|
||||
|
||||
posN pos posP
|
||||
|-----------|------|------------------|
|
||||
| | | |
|
||||
|<--dstN--->|<---------dstP---------->|
|
||||
|
|
||||
span center
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
|
||||
float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
|
||||
bool directionN = dstN < dstP;
|
||||
#if FXAA_DEBUG_NEGPOS
|
||||
if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
|
||||
#endif
|
||||
lumaEndN = directionN ? lumaEndN : lumaEndP;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
|
||||
------------------------------------------------------------------------------
|
||||
If both the pair luma at the end of the span (lumaEndN)
|
||||
and middle pixel luma (lumaM)
|
||||
are on the same side of the middle pair average luma (lumaN),
|
||||
then don't filter.
|
||||
|
||||
Cases,
|
||||
|
||||
(1.) "L",
|
||||
|
||||
lumaM
|
||||
|
|
||||
V XXXXXXXX <- other line averaged
|
||||
XXXXXXX[X]XXXXXXXXXXX <- source pixel line
|
||||
| . |
|
||||
--------------------------
|
||||
[ ]xxxxxx[x]xx[X]XXXXXX <- pair average
|
||||
--------------------------
|
||||
^ ^ ^ ^
|
||||
| | | |
|
||||
. |<---->|<---------- no filter region
|
||||
. | | |
|
||||
. center | |
|
||||
. | lumaEndN
|
||||
. | .
|
||||
. lumaN .
|
||||
. .
|
||||
|<--- span -->|
|
||||
|
||||
|
||||
(2.) "^" and "-",
|
||||
|
||||
<- other line averaged
|
||||
XXXXX[X]XXX <- source pixel line
|
||||
| | |
|
||||
--------------------------
|
||||
[ ]xxxx[x]xx[ ] <- pair average
|
||||
--------------------------
|
||||
| | |
|
||||
|<--->|<--->|<---------- filter both sides
|
||||
|
||||
|
||||
(3.) "v" and inverse of "-",
|
||||
|
||||
XXXXXX XXXXXXXXX <- other line averaged
|
||||
XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
|
||||
| | |
|
||||
--------------------------
|
||||
XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
|
||||
--------------------------
|
||||
| | |
|
||||
|<--->|<--->|<---------- don't filter both!
|
||||
|
||||
|
||||
Note the "v" case for FXAA requires no filtering.
|
||||
This is because the inverse of the "-" case is the "v".
|
||||
Filtering "v" case turns open spans like this,
|
||||
|
||||
XXXXXXXXX
|
||||
|
||||
Into this (which is not desired),
|
||||
|
||||
x+. .+x
|
||||
XXXXXXXXX
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
|
||||
lengthSign = 0.0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
|
||||
------------------------------------------------------------------------------
|
||||
FXAA filters using a bilinear texture fetch offset
|
||||
from the middle pixel M towards the center of the pair (NM below).
|
||||
Maximum filtering will be half way between pair.
|
||||
Reminder, at this point in the code,
|
||||
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
|
||||
|
||||
+-------+
|
||||
| | 0.5 offset
|
||||
| N | |
|
||||
| | V
|
||||
+-------+....---
|
||||
| |
|
||||
| M...|....---
|
||||
| | ^
|
||||
+-------+ |
|
||||
. . 0.0 offset
|
||||
. S .
|
||||
. .
|
||||
.........
|
||||
|
||||
Position on span is used to compute sub-pixel filter offset using simple ramp,
|
||||
|
||||
posN posP
|
||||
|\ |<------- 0.5 pixel offset into pair pixel
|
||||
| \ |
|
||||
| \ |
|
||||
---.......|...\..........|<------- 0.25 pixel offset into pair pixel
|
||||
^ | ^\ |
|
||||
| | | \ |
|
||||
V | | \ |
|
||||
---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
|
||||
^ . | ^ .
|
||||
| . pos | .
|
||||
| . . | .
|
||||
| . . center .
|
||||
| . . .
|
||||
| |<->|<---------.-------- dstN
|
||||
| . . .
|
||||
| . |<-------->|<------- dstP
|
||||
| . .
|
||||
| |<------------>|<------- spanLength
|
||||
|
|
||||
subPixelOffset
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
float spanLength = (dstP + dstN);
|
||||
dstN = directionN ? dstN : dstP;
|
||||
float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
|
||||
#if FXAA_DEBUG_OFFSET
|
||||
float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
|
||||
float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
|
||||
if(ox < 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(1.0, 0.0, 0.0), -ox));
|
||||
if(ox > 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(0.0, 0.0, 1.0), ox));
|
||||
if(oy < 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(1.0, 0.6, 0.2), -oy));
|
||||
if(oy > 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(0.2, 0.6, 1.0), oy));
|
||||
return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
|
||||
#endif
|
||||
float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
|
||||
pos.x + (horzSpan ? 0.0 : subPixelOffset),
|
||||
pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
|
||||
#if FXAA_SUBPIX == 0
|
||||
return FxaaFilterReturn(rgbF);
|
||||
#else
|
||||
return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return float4(FxaaPixelShader(i.uv.xy, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "Hidden/FXAA II"
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f1418cffd12146f2a83be795f6fa5a7
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,828 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/FXAA Preset 3" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
#pragma target 3.0
|
||||
|
||||
// Not very practical on consoles/mobile, and PS3 Cg takes ages to compile this :(
|
||||
#pragma exclude_renderers xbox360 ps3 gles
|
||||
|
||||
#define FXAA_HLSL_3 1
|
||||
#define FXAA_PRESET 3
|
||||
|
||||
|
||||
// Copyright (c) 2010 NVIDIA Corporation. All rights reserved.
|
||||
//
|
||||
// TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
|
||||
// *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
|
||||
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
|
||||
// BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
||||
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
|
||||
// ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
|
||||
// BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
/*============================================================================
|
||||
|
||||
FXAA
|
||||
|
||||
============================================================================*/
|
||||
|
||||
/*============================================================================
|
||||
API PORTING
|
||||
============================================================================*/
|
||||
#ifndef FXAA_GLSL_120
|
||||
#define FXAA_GLSL_120 0
|
||||
#endif
|
||||
#ifndef FXAA_GLSL_130
|
||||
#define FXAA_GLSL_130 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_3
|
||||
#define FXAA_HLSL_3 0
|
||||
#endif
|
||||
#ifndef FXAA_HLSL_4
|
||||
#define FXAA_HLSL_4 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_120
|
||||
// Requires,
|
||||
// #version 120
|
||||
// #extension GL_EXT_gpu_shader4 : enable
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaBool3 bvec3
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) mix((f), (t), (b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_GLSL_130
|
||||
// Requires "#version 130" or better
|
||||
#define int2 ivec2
|
||||
#define float2 vec2
|
||||
#define float3 vec3
|
||||
#define float4 vec4
|
||||
#define FxaaBool3 bvec3
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaBool2Float(a) mix(0.0, 1.0, (a))
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) mix((f), (t), (b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_3
|
||||
#define int2 float2
|
||||
#define FxaaInt2 float2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaFloat3 float3
|
||||
#define FxaaFloat4 float4
|
||||
#define FxaaBool2Float(a) (a)
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
|
||||
#define FxaaTex sampler2D
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_HLSL_4
|
||||
#define FxaaInt2 int2
|
||||
#define FxaaFloat2 float2
|
||||
#define FxaaFloat3 float3
|
||||
#define FxaaFloat4 float4
|
||||
#define FxaaBool2Float(a) (a)
|
||||
#define FxaaPow3(x, y) pow(x, y)
|
||||
#define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
|
||||
struct FxaaTex { SamplerState smpl; Texture2D tex; };
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexLod0(FxaaTex tex, float2 pos) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DLod(tex, pos.xy, 0.0);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureLod(tex, pos.xy, 0.0);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0);
|
||||
#endif
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DGrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureGrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dgrad(tex, pos.xy, grad, grad);
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleGrad(tex.smpl, pos.xy, grad, grad);
|
||||
#endif
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) {
|
||||
#if FXAA_GLSL_120
|
||||
return texture2DLodOffset(tex, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
#if FXAA_GLSL_130
|
||||
return textureLodOffset(tex, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
#if FXAA_HLSL_3
|
||||
return tex2Dlod(tex, float4(pos.xy + (off * rcpFrame), 0, 0));
|
||||
#endif
|
||||
#if FXAA_HLSL_4
|
||||
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0, off.xy);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
SRGB KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SRGB_ROP - Set to 1 when applying FXAA to an sRGB back buffer (DX10/11).
|
||||
This will do the sRGB to linear transform,
|
||||
as ROP will expect linear color from this shader,
|
||||
and this shader works in non-linear color.
|
||||
============================================================================*/
|
||||
#define FXAA_SRGB_ROP 0
|
||||
|
||||
/*============================================================================
|
||||
DEBUG KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
All debug knobs draw FXAA-untouched pixels in FXAA computed luma (monochrome).
|
||||
|
||||
FXAA_DEBUG_PASSTHROUGH - Red for pixels which are filtered by FXAA with a
|
||||
yellow tint on sub-pixel aliasing filtered by FXAA.
|
||||
FXAA_DEBUG_HORZVERT - Blue for horizontal edges, gold for vertical edges.
|
||||
FXAA_DEBUG_PAIR - Blue/green for the 2 pixel pair choice.
|
||||
FXAA_DEBUG_NEGPOS - Red/blue for which side of center of span.
|
||||
FXAA_DEBUG_OFFSET - Red/blue for -/+ x, gold/skyblue for -/+ y.
|
||||
============================================================================*/
|
||||
#ifndef FXAA_DEBUG_PASSTHROUGH
|
||||
#define FXAA_DEBUG_PASSTHROUGH 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_HORZVERT
|
||||
#define FXAA_DEBUG_HORZVERT 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_PAIR
|
||||
#define FXAA_DEBUG_PAIR 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_NEGPOS
|
||||
#define FXAA_DEBUG_NEGPOS 0
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG_OFFSET
|
||||
#define FXAA_DEBUG_OFFSET 0
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
|
||||
#define FXAA_DEBUG 1
|
||||
#endif
|
||||
#if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
|
||||
#define FXAA_DEBUG 1
|
||||
#endif
|
||||
#ifndef FXAA_DEBUG
|
||||
#define FXAA_DEBUG 0
|
||||
#endif
|
||||
|
||||
/*============================================================================
|
||||
COMPILE-IN KNOBS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_PRESET - Choose compile-in knob preset 0-5.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
|
||||
to apply algorithm.
|
||||
1.0/3.0 - too little
|
||||
1.0/4.0 - good start
|
||||
1.0/8.0 - applies to more edges
|
||||
1.0/16.0 - overkill
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks.
|
||||
Perf optimization.
|
||||
1.0/32.0 - visible limit (smaller isn't visible)
|
||||
1.0/16.0 - good compromise
|
||||
1.0/12.0 - upper limit (seeing artifacts)
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_STEPS - Maximum number of search steps for end of span.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_ACCELERATION - How much to accelerate search,
|
||||
1 - no acceleration
|
||||
2 - skip by 2 pixels
|
||||
3 - skip by 3 pixels
|
||||
4 - skip by 4 pixels
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SEARCH_THRESHOLD - Controls when to stop searching.
|
||||
1.0/4.0 - seems to be the best quality wise
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_FASTER - Turn on lower quality but faster subpix path.
|
||||
Not recomended, but used in preset 0.
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX - Toggle subpix filtering.
|
||||
0 - turn off
|
||||
1 - turn on
|
||||
2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
|
||||
1.0/2.0 - low removal
|
||||
1.0/3.0 - medium removal
|
||||
1.0/4.0 - default removal
|
||||
1.0/8.0 - high removal
|
||||
0.0 - complete removal
|
||||
------------------------------------------------------------------------------
|
||||
FXAA_SUBPIX_CAP - Insures fine detail is not completely removed.
|
||||
This is important for the transition of sub-pixel detail,
|
||||
like fences and wires.
|
||||
3.0/4.0 - default (medium amount of filtering)
|
||||
7.0/8.0 - high amount of filtering
|
||||
1.0 - no capping of sub-pixel aliasing removal
|
||||
============================================================================*/
|
||||
#ifndef FXAA_PRESET
|
||||
#define FXAA_PRESET 3
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 0)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
|
||||
#define FXAA_SEARCH_STEPS 2
|
||||
#define FXAA_SEARCH_ACCELERATION 4
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 1
|
||||
#define FXAA_SUBPIX_CAP (2.0/3.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 1)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
|
||||
#define FXAA_SEARCH_STEPS 4
|
||||
#define FXAA_SEARCH_ACCELERATION 3
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 2)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 8
|
||||
#define FXAA_SEARCH_ACCELERATION 2
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 3)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 16
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 4)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 24
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_PRESET == 5)
|
||||
#define FXAA_EDGE_THRESHOLD (1.0/8.0)
|
||||
#define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
|
||||
#define FXAA_SEARCH_STEPS 32
|
||||
#define FXAA_SEARCH_ACCELERATION 1
|
||||
#define FXAA_SEARCH_THRESHOLD (1.0/4.0)
|
||||
#define FXAA_SUBPIX 1
|
||||
#define FXAA_SUBPIX_FASTER 0
|
||||
#define FXAA_SUBPIX_CAP (3.0/4.0)
|
||||
#define FXAA_SUBPIX_TRIM (1.0/4.0)
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
|
||||
|
||||
/*============================================================================
|
||||
HELPERS
|
||||
============================================================================*/
|
||||
// Return the luma, the estimation of luminance from rgb inputs.
|
||||
// This approximates luma using one FMA instruction,
|
||||
// skipping normalization and tossing out blue.
|
||||
// FxaaLuma() will range 0.0 to 2.963210702.
|
||||
float FxaaLuma(float3 rgb) {
|
||||
return rgb.y * (0.587/0.299) + rgb.x; }
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
|
||||
return (FxaaToFloat3(-amountOfA) * b) +
|
||||
((a * FxaaToFloat3(amountOfA)) + b); }
|
||||
/*--------------------------------------------------------------------------*/
|
||||
// Support any extra filtering before returning color.
|
||||
float3 FxaaFilterReturn(float3 rgb) {
|
||||
#if FXAA_SRGB_ROP
|
||||
// Do sRGB encoded value to linear conversion.
|
||||
return FxaaSel3(
|
||||
rgb * FxaaToFloat3(1.0/12.92),
|
||||
FxaaPow3(
|
||||
rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
|
||||
FxaaToFloat3(2.4)),
|
||||
rgb > FxaaToFloat3(0.04045));
|
||||
#else
|
||||
return rgb;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
VERTEX SHADER
|
||||
============================================================================*/
|
||||
float2 FxaaVertexShader(
|
||||
// Both x and y range {-1.0 to 1.0 across screen}.
|
||||
float2 inPos) {
|
||||
float2 pos;
|
||||
pos.xy = (inPos.xy * FxaaFloat2(0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
|
||||
return pos; }
|
||||
|
||||
/*============================================================================
|
||||
|
||||
PIXEL SHADER
|
||||
|
||||
============================================================================*/
|
||||
float3 FxaaPixelShader(
|
||||
// Output of FxaaVertexShader interpolated across screen.
|
||||
// xy -> actual texture position {0.0 to 1.0}
|
||||
float2 pos,
|
||||
// Input texture.
|
||||
FxaaTex tex,
|
||||
// RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// {1.0/frameWidth, 1.0/frameHeight}
|
||||
float2 rcpFrame) {
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
|
||||
------------------------------------------------------------------------------
|
||||
Majority of pixels of a typical image do not require filtering,
|
||||
often pixels are grouped into blocks which could benefit from early exit
|
||||
right at the beginning of the algorithm.
|
||||
Given the following neighborhood,
|
||||
|
||||
N
|
||||
W M E
|
||||
S
|
||||
|
||||
If the difference in local maximum and minimum luma (contrast "range")
|
||||
is lower than a threshold proportional to the maximum local luma ("rangeMax"),
|
||||
then the shader early exits (no visible aliasing).
|
||||
This threshold is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
|
||||
to avoid processing in really dark areas.
|
||||
----------------------------------------------------------------------------*/
|
||||
float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
|
||||
float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
|
||||
float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
|
||||
float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
|
||||
float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
|
||||
float lumaN = FxaaLuma(rgbN);
|
||||
float lumaW = FxaaLuma(rgbW);
|
||||
float lumaM = FxaaLuma(rgbM);
|
||||
float lumaE = FxaaLuma(rgbE);
|
||||
float lumaS = FxaaLuma(rgbS);
|
||||
float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
|
||||
float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
|
||||
float range = rangeMax - rangeMin;
|
||||
#if FXAA_DEBUG
|
||||
float lumaO = lumaM / (1.0 + (0.587/0.299));
|
||||
#endif
|
||||
if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
|
||||
#if FXAA_DEBUG
|
||||
return FxaaFilterReturn(FxaaToFloat3(lumaO));
|
||||
#endif
|
||||
return FxaaFilterReturn(rgbM); }
|
||||
#if FXAA_SUBPIX > 0
|
||||
#if FXAA_SUBPIX_FASTER
|
||||
float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
|
||||
FxaaToFloat3(1.0/5.0);
|
||||
#else
|
||||
float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
COMPUTE LOWPASS
|
||||
------------------------------------------------------------------------------
|
||||
FXAA computes a local neighborhood lowpass value as follows,
|
||||
|
||||
(N + W + E + S)/4
|
||||
|
||||
Then uses the ratio of the contrast range of the lowpass
|
||||
and the range found in the early exit check,
|
||||
as a sub-pixel aliasing detection filter.
|
||||
When FXAA detects sub-pixel aliasing (such as single pixel dots),
|
||||
it later blends in "blendL" amount
|
||||
of a lowpass value (computed in the next section) to the final result.
|
||||
----------------------------------------------------------------------------*/
|
||||
#if FXAA_SUBPIX != 0
|
||||
float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
|
||||
float rangeL = abs(lumaL - lumaM);
|
||||
#endif
|
||||
#if FXAA_SUBPIX == 1
|
||||
float blendL = max(0.0,
|
||||
(rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
|
||||
blendL = min(FXAA_SUBPIX_CAP, blendL);
|
||||
#endif
|
||||
#if FXAA_SUBPIX == 2
|
||||
float blendL = rangeL / range;
|
||||
#endif
|
||||
#if FXAA_DEBUG_PASSTHROUGH
|
||||
#if FXAA_SUBPIX == 0
|
||||
float blendL = 0.0;
|
||||
#endif
|
||||
return FxaaFilterReturn(
|
||||
FxaaFloat3(1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE VERTICAL OR HORIZONTAL SEARCH
|
||||
------------------------------------------------------------------------------
|
||||
FXAA uses the following local neighborhood,
|
||||
|
||||
NW N NE
|
||||
W M E
|
||||
SW S SE
|
||||
|
||||
To compute an edge amount for both vertical and horizontal directions.
|
||||
Note edge detect filters like Sobel fail on single pixel lines through M.
|
||||
FXAA takes the weighted average magnitude of the high-pass values
|
||||
for rows and columns as an indication of local edge amount.
|
||||
|
||||
A lowpass value for anti-sub-pixel-aliasing is computed as
|
||||
(N+W+E+S+M+NW+NE+SW+SE)/9.
|
||||
This full box pattern has higher quality than other options.
|
||||
|
||||
Note following this block, both vertical and horizontal cases
|
||||
flow in parallel (reusing the horizontal variables).
|
||||
----------------------------------------------------------------------------*/
|
||||
float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
|
||||
float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
|
||||
float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
|
||||
float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
|
||||
#if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
|
||||
rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
|
||||
rgbL *= FxaaToFloat3(1.0/9.0);
|
||||
#endif
|
||||
float lumaNW = FxaaLuma(rgbNW);
|
||||
float lumaNE = FxaaLuma(rgbNE);
|
||||
float lumaSW = FxaaLuma(rgbSW);
|
||||
float lumaSE = FxaaLuma(rgbSE);
|
||||
float edgeVert =
|
||||
abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
|
||||
abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
|
||||
abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
|
||||
float edgeHorz =
|
||||
abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
|
||||
abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
|
||||
abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
|
||||
bool horzSpan = edgeHorz >= edgeVert;
|
||||
#if FXAA_DEBUG_HORZVERT
|
||||
if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
|
||||
#endif
|
||||
float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
|
||||
if(!horzSpan) lumaN = lumaW;
|
||||
if(!horzSpan) lumaS = lumaE;
|
||||
float gradientN = abs(lumaN - lumaM);
|
||||
float gradientS = abs(lumaS - lumaM);
|
||||
lumaN = (lumaN + lumaM) * 0.5;
|
||||
lumaS = (lumaS + lumaM) * 0.5;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
|
||||
------------------------------------------------------------------------------
|
||||
This chooses a pixel pair.
|
||||
For "horzSpan == true" this will be a vertical pair,
|
||||
|
||||
[N] N
|
||||
[M] or [M]
|
||||
S [S]
|
||||
|
||||
Note following this block, both {N,M} and {S,M} cases
|
||||
flow in parallel (reusing the {N,M} variables).
|
||||
|
||||
This pair of image rows or columns is searched below
|
||||
in the positive and negative direction
|
||||
until edge status changes
|
||||
(or the maximum number of search steps is reached).
|
||||
----------------------------------------------------------------------------*/
|
||||
bool pairN = gradientN >= gradientS;
|
||||
#if FXAA_DEBUG_PAIR
|
||||
if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
|
||||
#endif
|
||||
if(!pairN) lumaN = lumaS;
|
||||
if(!pairN) gradientN = gradientS;
|
||||
if(!pairN) lengthSign *= -1.0;
|
||||
float2 posN;
|
||||
posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
|
||||
posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHOOSE SEARCH LIMITING VALUES
|
||||
------------------------------------------------------------------------------
|
||||
Search limit (+/- gradientN) is a function of local gradient.
|
||||
----------------------------------------------------------------------------*/
|
||||
gradientN *= FXAA_SEARCH_THRESHOLD;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
|
||||
------------------------------------------------------------------------------
|
||||
This loop searches either in vertical or horizontal directions,
|
||||
and in both the negative and positive direction in parallel.
|
||||
This loop fusion is faster than searching separately.
|
||||
|
||||
The search is accelerated using FXAA_SEARCH_ACCELERATION length box filter
|
||||
via anisotropic filtering with specified texture gradients.
|
||||
----------------------------------------------------------------------------*/
|
||||
float2 posP = posN;
|
||||
float2 offNP = horzSpan ?
|
||||
FxaaFloat2(rcpFrame.x, 0.0) :
|
||||
FxaaFloat2(0.0f, rcpFrame.y);
|
||||
float lumaEndN = lumaN;
|
||||
float lumaEndP = lumaN;
|
||||
bool doneN = false;
|
||||
bool doneP = false;
|
||||
#if FXAA_SEARCH_ACCELERATION == 1
|
||||
posN += offNP * FxaaFloat2(-1.0, -1.0);
|
||||
posP += offNP * FxaaFloat2( 1.0, 1.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 2
|
||||
posN += offNP * FxaaFloat2(-1.5, -1.5);
|
||||
posP += offNP * FxaaFloat2( 1.5, 1.5);
|
||||
offNP *= FxaaFloat2(2.0, 2.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 3
|
||||
posN += offNP * FxaaFloat2(-2.0, -2.0);
|
||||
posP += offNP * FxaaFloat2( 2.0, 2.0);
|
||||
offNP *= FxaaFloat2(3.0, 3.0);
|
||||
#endif
|
||||
#if FXAA_SEARCH_ACCELERATION == 4
|
||||
posN += offNP * FxaaFloat2(-2.5, -2.5);
|
||||
posP += offNP * FxaaFloat2( 2.5, 2.5);
|
||||
offNP *= FxaaFloat2(4.0, 4.0);
|
||||
#endif
|
||||
for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
|
||||
#if FXAA_SEARCH_ACCELERATION == 1
|
||||
if(!doneN) lumaEndN =
|
||||
FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
|
||||
if(!doneP) lumaEndP =
|
||||
FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
|
||||
#else
|
||||
if(!doneN) lumaEndN =
|
||||
FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
|
||||
if(!doneP) lumaEndP =
|
||||
FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
|
||||
#endif
|
||||
doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
|
||||
doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
|
||||
if(doneN && doneP) break;
|
||||
if(!doneN) posN -= offNP;
|
||||
if(!doneP) posP += offNP; }
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
|
||||
------------------------------------------------------------------------------
|
||||
FXAA uses the pixel's position in the span
|
||||
in combination with the values (lumaEnd*) at the ends of the span,
|
||||
to determine filtering.
|
||||
|
||||
This step computes which side of the span the pixel is on.
|
||||
On negative side if dstN < dstP,
|
||||
|
||||
posN pos posP
|
||||
|-----------|------|------------------|
|
||||
| | | |
|
||||
|<--dstN--->|<---------dstP---------->|
|
||||
|
|
||||
span center
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
|
||||
float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
|
||||
bool directionN = dstN < dstP;
|
||||
#if FXAA_DEBUG_NEGPOS
|
||||
if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
|
||||
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
|
||||
#endif
|
||||
lumaEndN = directionN ? lumaEndN : lumaEndP;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
|
||||
------------------------------------------------------------------------------
|
||||
If both the pair luma at the end of the span (lumaEndN)
|
||||
and middle pixel luma (lumaM)
|
||||
are on the same side of the middle pair average luma (lumaN),
|
||||
then don't filter.
|
||||
|
||||
Cases,
|
||||
|
||||
(1.) "L",
|
||||
|
||||
lumaM
|
||||
|
|
||||
V XXXXXXXX <- other line averaged
|
||||
XXXXXXX[X]XXXXXXXXXXX <- source pixel line
|
||||
| . |
|
||||
--------------------------
|
||||
[ ]xxxxxx[x]xx[X]XXXXXX <- pair average
|
||||
--------------------------
|
||||
^ ^ ^ ^
|
||||
| | | |
|
||||
. |<---->|<---------- no filter region
|
||||
. | | |
|
||||
. center | |
|
||||
. | lumaEndN
|
||||
. | .
|
||||
. lumaN .
|
||||
. .
|
||||
|<--- span -->|
|
||||
|
||||
|
||||
(2.) "^" and "-",
|
||||
|
||||
<- other line averaged
|
||||
XXXXX[X]XXX <- source pixel line
|
||||
| | |
|
||||
--------------------------
|
||||
[ ]xxxx[x]xx[ ] <- pair average
|
||||
--------------------------
|
||||
| | |
|
||||
|<--->|<--->|<---------- filter both sides
|
||||
|
||||
|
||||
(3.) "v" and inverse of "-",
|
||||
|
||||
XXXXXX XXXXXXXXX <- other line averaged
|
||||
XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
|
||||
| | |
|
||||
--------------------------
|
||||
XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
|
||||
--------------------------
|
||||
| | |
|
||||
|<--->|<--->|<---------- don't filter both!
|
||||
|
||||
|
||||
Note the "v" case for FXAA requires no filtering.
|
||||
This is because the inverse of the "-" case is the "v".
|
||||
Filtering "v" case turns open spans like this,
|
||||
|
||||
XXXXXXXXX
|
||||
|
||||
Into this (which is not desired),
|
||||
|
||||
x+. .+x
|
||||
XXXXXXXXX
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
|
||||
lengthSign = 0.0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
|
||||
------------------------------------------------------------------------------
|
||||
FXAA filters using a bilinear texture fetch offset
|
||||
from the middle pixel M towards the center of the pair (NM below).
|
||||
Maximum filtering will be half way between pair.
|
||||
Reminder, at this point in the code,
|
||||
the {N,M} pair is also reused for all cases: {S,M}, {W,M}, and {E,M}.
|
||||
|
||||
+-------+
|
||||
| | 0.5 offset
|
||||
| N | |
|
||||
| | V
|
||||
+-------+....---
|
||||
| |
|
||||
| M...|....---
|
||||
| | ^
|
||||
+-------+ |
|
||||
. . 0.0 offset
|
||||
. S .
|
||||
. .
|
||||
.........
|
||||
|
||||
Position on span is used to compute sub-pixel filter offset using simple ramp,
|
||||
|
||||
posN posP
|
||||
|\ |<------- 0.5 pixel offset into pair pixel
|
||||
| \ |
|
||||
| \ |
|
||||
---.......|...\..........|<------- 0.25 pixel offset into pair pixel
|
||||
^ | ^\ |
|
||||
| | | \ |
|
||||
V | | \ |
|
||||
---.......|===|==========|<------- 0.0 pixel offset (ie M pixel)
|
||||
^ . | ^ .
|
||||
| . pos | .
|
||||
| . . | .
|
||||
| . . center .
|
||||
| . . .
|
||||
| |<->|<---------.-------- dstN
|
||||
| . . .
|
||||
| . |<-------->|<------- dstP
|
||||
| . .
|
||||
| |<------------>|<------- spanLength
|
||||
|
|
||||
subPixelOffset
|
||||
|
||||
----------------------------------------------------------------------------*/
|
||||
float spanLength = (dstP + dstN);
|
||||
dstN = directionN ? dstN : dstP;
|
||||
float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
|
||||
#if FXAA_DEBUG_OFFSET
|
||||
float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
|
||||
float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
|
||||
if(ox < 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(1.0, 0.0, 0.0), -ox));
|
||||
if(ox > 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(0.0, 0.0, 1.0), ox));
|
||||
if(oy < 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(1.0, 0.6, 0.2), -oy));
|
||||
if(oy > 0.0) return FxaaFilterReturn(
|
||||
FxaaLerp3(FxaaToFloat3(lumaO),
|
||||
FxaaFloat3(0.2, 0.6, 1.0), oy));
|
||||
return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
|
||||
#endif
|
||||
float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
|
||||
pos.x + (horzSpan ? 0.0 : subPixelOffset),
|
||||
pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
|
||||
#if FXAA_SUBPIX == 0
|
||||
return FxaaFilterReturn(rgbF);
|
||||
#else
|
||||
return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_TexelSize;
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
return float4(FxaaPixelShader(i.uv.xy, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "Hidden/FXAA II"
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c182fa94a5a0a4c02870641efcd38cd5
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,150 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
Shader "Hidden/NFAA" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
_BlurTex ("Base (RGB)", 2D) = "white" {}
|
||||
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
uniform float _OffsetScale;
|
||||
uniform float _BlurRadius;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[8] : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v )
|
||||
{
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
|
||||
float2 up = float2(0.0, _MainTex_TexelSize.y) * _OffsetScale;
|
||||
float2 right = float2(_MainTex_TexelSize.x, 0.0) * _OffsetScale;
|
||||
|
||||
o.uv[0].xy = uv + up;
|
||||
o.uv[1].xy = uv - up;
|
||||
o.uv[2].xy = uv + right;
|
||||
o.uv[3].xy = uv - right;
|
||||
o.uv[4].xy = uv - right + up;
|
||||
o.uv[5].xy = uv - right -up;
|
||||
o.uv[6].xy = uv + right + up;
|
||||
o.uv[7].xy = uv + right -up;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
// get luminance values
|
||||
// maybe: experiment with different luminance calculations
|
||||
float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
|
||||
float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
|
||||
float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
|
||||
float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
|
||||
float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
|
||||
float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
|
||||
float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
|
||||
float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
|
||||
|
||||
// 2 triangle subtractions
|
||||
float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
|
||||
float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
|
||||
float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
|
||||
float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
|
||||
|
||||
// figure out "normal"
|
||||
float2 blurDir = half2((sum0-sum1), (sum3-sum2));
|
||||
blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
|
||||
|
||||
// reconstruct normal uv
|
||||
float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
|
||||
|
||||
float4 returnColor = tex2D(_MainTex, uv_);
|
||||
returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
|
||||
returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
|
||||
returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
|
||||
returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
|
||||
|
||||
return returnColor * 0.2;
|
||||
}
|
||||
|
||||
half4 fragDebug (v2f i) : SV_Target
|
||||
{
|
||||
// get luminance values
|
||||
// maybe: experiment with different luminance calculations
|
||||
float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
|
||||
float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
|
||||
float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
|
||||
float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
|
||||
float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
|
||||
float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
|
||||
float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
|
||||
float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
|
||||
|
||||
// 2 triangle subtractions
|
||||
float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
|
||||
float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
|
||||
float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
|
||||
float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
|
||||
|
||||
// figure out "normal"
|
||||
float2 blurDir = half2((sum0-sum1), (sum3-sum2));
|
||||
blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
|
||||
|
||||
// reconstruct normal uv
|
||||
float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
|
||||
|
||||
float4 returnColor = tex2D(_MainTex, uv_);
|
||||
returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
|
||||
returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
|
||||
returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
|
||||
returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
|
||||
|
||||
blurDir = half2((sum0-sum1), (sum3-sum2)) * _BlurRadius;
|
||||
return half4(normalize( half3(blurDir,1) * 0.5 + 0.5), 1);
|
||||
return returnColor * 0.2;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma target 3.0
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
|
||||
ENDCG
|
||||
}
|
||||
Pass {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragDebug
|
||||
#pragma target 3.0
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce0cb2621f6d84e21a87414e471a3cce
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,87 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
|
||||
Shader "Hidden/SSAA" {
|
||||
Properties {
|
||||
_MainTex ("Base (RGB)", 2D) = "white" {}
|
||||
}
|
||||
|
||||
// very simple & fast AA by Emmanuel Julien
|
||||
|
||||
SubShader {
|
||||
Pass {
|
||||
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
uniform sampler2D _MainTex;
|
||||
uniform float4 _MainTex_TexelSize;
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[5] : TEXCOORD0;
|
||||
};
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos (v.vertex);
|
||||
|
||||
float2 uv = v.texcoord.xy;
|
||||
|
||||
float w = 1.75;
|
||||
|
||||
float2 up = float2(0.0, _MainTex_TexelSize.y) * w;
|
||||
float2 right = float2(_MainTex_TexelSize.x, 0.0) * w;
|
||||
|
||||
o.uv[0].xy = uv - up;
|
||||
o.uv[1].xy = uv - right;
|
||||
o.uv[2].xy = uv + right;
|
||||
o.uv[3].xy = uv + up;
|
||||
|
||||
o.uv[4].xy = uv;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag (v2f i) : SV_Target
|
||||
{
|
||||
half4 outColor;
|
||||
|
||||
float t = Luminance( tex2D( _MainTex, i.uv[0] ).xyz );
|
||||
float l = Luminance( tex2D( _MainTex, i.uv[1] ).xyz);
|
||||
float r = Luminance( tex2D( _MainTex, i.uv[2] ).xyz);
|
||||
float b = Luminance( tex2D( _MainTex, i.uv[3] ).xyz);
|
||||
|
||||
half2 n = half2( -( t - b ), r - l );
|
||||
float nl = length( n );
|
||||
|
||||
if ( nl < (1.0 / 16.0) )
|
||||
outColor = tex2D( _MainTex, i.uv[4] );
|
||||
else {
|
||||
n *= _MainTex_TexelSize.xy / nl;
|
||||
|
||||
half4 o = tex2D( _MainTex, i.uv[4]);
|
||||
half4 t0 = tex2D( _MainTex, i.uv[4] + n * 0.5) * 0.9;
|
||||
half4 t1 = tex2D( _MainTex, i.uv[4] - n * 0.5) * 0.9;
|
||||
half4 t2 = tex2D( _MainTex, i.uv[4] + n) * 0.75;
|
||||
half4 t3 = tex2D( _MainTex, i.uv[4] - n) * 0.75;
|
||||
|
||||
outColor = (o + t0 + t1 + t2 + t3) / 4.3;
|
||||
}
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3728d1488b02490cbd196c7941bf1f8
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6ef58fc6f637406bbe6814a19c377f8
|
@ -0,0 +1,116 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/Blend" {
|
||||
Properties {
|
||||
_MainTex ("Screen Blended", 2D) = "" {}
|
||||
_ColorBuffer ("Color", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
struct v2f_mt {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[4] : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _ColorBuffer;
|
||||
sampler2D _MainTex;
|
||||
|
||||
half _Intensity;
|
||||
half4 _ColorBuffer_TexelSize;
|
||||
half4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv[0] = v.texcoord.xy;
|
||||
o.uv[1] = v.texcoord.xy;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_ColorBuffer_TexelSize.y < 0)
|
||||
o.uv[1].y = 1-o.uv[1].y;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
v2f_mt vertMultiTap( appdata_img v ) {
|
||||
v2f_mt o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv[0] = v.texcoord.xy + _MainTex_TexelSize.xy * 0.5;
|
||||
o.uv[1] = v.texcoord.xy - _MainTex_TexelSize.xy * 0.5;
|
||||
o.uv[2] = v.texcoord.xy - _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
|
||||
o.uv[3] = v.texcoord.xy + _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragScreen (v2f i) : SV_Target {
|
||||
half4 toBlend = saturate (tex2D(_MainTex, i.uv[0]) * _Intensity);
|
||||
return 1-(1-toBlend)*(1-tex2D(_ColorBuffer, i.uv[1]));
|
||||
}
|
||||
|
||||
half4 fragAdd (v2f i) : SV_Target {
|
||||
return tex2D(_MainTex, i.uv[0].xy) * _Intensity + tex2D(_ColorBuffer, i.uv[1]);
|
||||
}
|
||||
|
||||
half4 fragVignetteBlend (v2f i) : SV_Target {
|
||||
return tex2D(_MainTex, i.uv[0].xy) * tex2D(_ColorBuffer, i.uv[0]);
|
||||
}
|
||||
|
||||
half4 fragMultiTap (v2f_mt i) : SV_Target {
|
||||
half4 outColor = tex2D(_MainTex, i.uv[0].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[1].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[2].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[3].xy);
|
||||
return outColor * 0.25;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
// 0: nicer & softer "screen" blend mode
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragScreen
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 1: simple "add" blend mode
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAdd
|
||||
ENDCG
|
||||
}
|
||||
// 2: used for "stable" downsampling
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertMultiTap
|
||||
#pragma fragment fragMultiTap
|
||||
ENDCG
|
||||
}
|
||||
// 3: vignette blending
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragVignetteBlend
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53b3960ee3d3d4a5caa8d5473d120187
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,222 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/BlendForBloom" {
|
||||
Properties {
|
||||
_MainTex ("Screen Blended", 2D) = "" {}
|
||||
_ColorBuffer ("Color", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[2] : TEXCOORD0;
|
||||
};
|
||||
struct v2f_mt {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv[5] : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _ColorBuffer;
|
||||
sampler2D _MainTex;
|
||||
|
||||
half _Intensity;
|
||||
half4 _ColorBuffer_TexelSize;
|
||||
half4 _MainTex_TexelSize;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv[0] = v.texcoord.xy;
|
||||
o.uv[1] = v.texcoord.xy;
|
||||
|
||||
#if UNITY_UV_STARTS_AT_TOP
|
||||
if (_ColorBuffer_TexelSize.y < 0)
|
||||
o.uv[1].y = 1-o.uv[1].y;
|
||||
#endif
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
v2f_mt vertMultiTap( appdata_img v ) {
|
||||
v2f_mt o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv[4] = v.texcoord.xy;
|
||||
o.uv[0] = v.texcoord.xy + _MainTex_TexelSize.xy * 0.5;
|
||||
o.uv[1] = v.texcoord.xy - _MainTex_TexelSize.xy * 0.5;
|
||||
o.uv[2] = v.texcoord.xy - _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
|
||||
o.uv[3] = v.texcoord.xy + _MainTex_TexelSize.xy * half2(1,-1) * 0.5;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 fragScreen (v2f i) : SV_Target {
|
||||
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy) * _Intensity;
|
||||
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
|
||||
return 1-(1-addedbloom)*(1-screencolor);
|
||||
}
|
||||
|
||||
half4 fragScreenCheap(v2f i) : SV_Target {
|
||||
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy) * _Intensity;
|
||||
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
|
||||
return 1-(1-addedbloom)*(1-screencolor);
|
||||
}
|
||||
|
||||
half4 fragAdd (v2f i) : SV_Target {
|
||||
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy);
|
||||
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
|
||||
return _Intensity * addedbloom + screencolor;
|
||||
}
|
||||
|
||||
half4 fragAddCheap (v2f i) : SV_Target {
|
||||
half4 addedbloom = tex2D(_MainTex, i.uv[0].xy);
|
||||
half4 screencolor = tex2D(_ColorBuffer, i.uv[1]);
|
||||
return _Intensity * addedbloom + screencolor;
|
||||
}
|
||||
|
||||
half4 fragVignetteMul (v2f i) : SV_Target {
|
||||
return tex2D(_MainTex, i.uv[0].xy) * tex2D(_ColorBuffer, i.uv[0]);
|
||||
}
|
||||
|
||||
half4 fragVignetteBlend (v2f i) : SV_Target {
|
||||
return half4(1,1,1, tex2D(_ColorBuffer, i.uv[0]).r);
|
||||
}
|
||||
|
||||
half4 fragClear (v2f i) : SV_Target {
|
||||
return 0;
|
||||
}
|
||||
|
||||
half4 fragAddOneOne (v2f i) : SV_Target {
|
||||
half4 addedColors = tex2D(_MainTex, i.uv[0].xy);
|
||||
return addedColors * _Intensity;
|
||||
}
|
||||
|
||||
half4 frag1Tap (v2f i) : SV_Target {
|
||||
return tex2D(_MainTex, i.uv[0].xy);
|
||||
}
|
||||
|
||||
half4 fragMultiTapMax (v2f_mt i) : SV_Target {
|
||||
half4 outColor = tex2D(_MainTex, i.uv[4].xy);
|
||||
outColor = max(outColor, tex2D(_MainTex, i.uv[0].xy));
|
||||
outColor = max(outColor, tex2D(_MainTex, i.uv[1].xy));
|
||||
outColor = max(outColor, tex2D(_MainTex, i.uv[2].xy));
|
||||
outColor = max(outColor, tex2D(_MainTex, i.uv[3].xy));
|
||||
return outColor;
|
||||
}
|
||||
|
||||
half4 fragMultiTapBlur (v2f_mt i) : SV_Target {
|
||||
half4 outColor = 0;
|
||||
outColor += tex2D(_MainTex, i.uv[0].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[1].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[2].xy);
|
||||
outColor += tex2D(_MainTex, i.uv[3].xy);
|
||||
return outColor/4;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
// 0: nicer & softer "screen" blend mode
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragScreen
|
||||
ENDCG
|
||||
}
|
||||
|
||||
// 1: "add" blend mode
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAdd
|
||||
ENDCG
|
||||
}
|
||||
// 2: several taps, maxxed
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertMultiTap
|
||||
#pragma fragment fragMultiTapMax
|
||||
ENDCG
|
||||
}
|
||||
// 3: vignette blending
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragVignetteMul
|
||||
ENDCG
|
||||
}
|
||||
// 4: nicer & softer "screen" blend mode(cheapest)
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragScreenCheap
|
||||
ENDCG
|
||||
}
|
||||
// 5: "add" blend mode (cheapest)
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAddCheap
|
||||
ENDCG
|
||||
}
|
||||
// 6: used for "stable" downsampling (blur)
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vertMultiTap
|
||||
#pragma fragment fragMultiTapBlur
|
||||
ENDCG
|
||||
}
|
||||
// 7: vignette blending (blend to dest)
|
||||
Pass {
|
||||
|
||||
Blend Zero SrcAlpha
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragVignetteBlend
|
||||
ENDCG
|
||||
}
|
||||
// 8: clear
|
||||
Pass {
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragClear
|
||||
ENDCG
|
||||
}
|
||||
// 9: fragAddOneOne
|
||||
Pass {
|
||||
|
||||
Blend One One
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment fragAddOneOne
|
||||
ENDCG
|
||||
}
|
||||
// 10: max blend
|
||||
Pass {
|
||||
|
||||
BlendOp Max
|
||||
Blend One One
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag1Tap
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
} // shader
|
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7856cbff0a0ca45c787d5431eb805bb0
|
||||
ShaderImporter:
|
||||
userData:
|
@ -0,0 +1,50 @@
|
||||
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
||||
|
||||
Shader "Hidden/BlendOneOne" {
|
||||
Properties {
|
||||
_MainTex ("-", 2D) = "" {}
|
||||
}
|
||||
|
||||
CGINCLUDE
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct v2f {
|
||||
float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
half _Intensity;
|
||||
|
||||
v2f vert( appdata_img v ) {
|
||||
v2f o;
|
||||
o.pos = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.texcoord.xy;
|
||||
return o;
|
||||
}
|
||||
|
||||
half4 frag(v2f i) : SV_Target {
|
||||
return tex2D(_MainTex, i.uv) * _Intensity;
|
||||
}
|
||||
|
||||
ENDCG
|
||||
|
||||
Subshader {
|
||||
|
||||
Pass {
|
||||
BlendOp Add
|
||||
Blend One One
|
||||
|
||||
ZTest Always Cull Off ZWrite Off
|
||||
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
|
||||
Fallback off
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user