Added new stocking surface feature; Added unity 6.3 support; Fixed the issue that ssr weight does not blend ibl and ssr properly; Fixed the issue that material recive ssr regardless of specular ambient mode;
297 lines
8.3 KiB
HLSL
297 lines
8.3 KiB
HLSL
#ifndef UTS_COMMON
|
|
#define UTS_COMMON
|
|
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
|
|
#define inverselerp(a, b, x) saturate(((x) - (a)) / ((b) - (a)))
|
|
|
|
#define APPLY_WEIGHT(x, y, t) lerp(x, x * y, t)
|
|
|
|
float2 GetWHRatio()
|
|
{
|
|
return float2(_ScreenParams.y / _ScreenParams.x, 1);
|
|
}
|
|
|
|
float StepAntiAliasing(float x, float y)
|
|
{
|
|
float v = x - y;
|
|
return saturate(v / fwidth(v) + HALF_MIN); //fwidth(x) = abs(ddx(x) + ddy(x))
|
|
}
|
|
|
|
float Remap(float In, float2 InMinMax, float2 OutMinMax)
|
|
{
|
|
return OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
|
|
}
|
|
|
|
float3 ToonMaping(float3 x)
|
|
{
|
|
x = x * (2.51 * x + 0.03) / (x * (2.43 * x + 0.59) + 0.14);
|
|
return x;
|
|
}
|
|
|
|
float3 GetSmoothedWorldNormal(float2 uv, float3x3 t_tbn)
|
|
{
|
|
float3 normal = float3(uv, 0);
|
|
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
|
|
return mul(normal, t_tbn);
|
|
}
|
|
|
|
float3 UtsComputeDiffuseColor(float3 baseColor, float metallic, float min)
|
|
{
|
|
#if _PBR_MODE_OFF
|
|
return baseColor;
|
|
#else
|
|
return baseColor * (max(min, 1.0 - metallic));
|
|
#endif
|
|
}
|
|
|
|
float3 UtsComputeDiffuseColor(float3 baseColor, float metallic)
|
|
{
|
|
return UtsComputeDiffuseColor(baseColor, metallic, 0.0);
|
|
}
|
|
|
|
float Random(float2 uv)
|
|
{
|
|
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
|
|
}
|
|
|
|
inline float2 voronoi_noise_random_vector (float2 UV, float offset)
|
|
{
|
|
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
|
|
UV = frac(sin(mul(UV, m)) * 46839.32);
|
|
return float2(sin(UV.y*+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
|
|
}
|
|
|
|
float Voronoi(float2 UV, float AngleOffset, float CellDensity)
|
|
{
|
|
float2 g = floor(UV * CellDensity);
|
|
float2 f = frac(UV * CellDensity);
|
|
float t = 8.0;
|
|
float res = 8.0;
|
|
|
|
for(int y=-1; y<=1; y++)
|
|
{
|
|
for(int x=-1; x<=1; x++)
|
|
{
|
|
float2 lattice = float2(x,y);
|
|
float2 offset = voronoi_noise_random_vector(lattice + g, AngleOffset);
|
|
float d = distance(lattice + offset, f);
|
|
if(d < res)
|
|
{
|
|
res = d;
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
float Dither(float In, float4 positionSS)
|
|
{
|
|
float2 uv = positionSS.xy;
|
|
float DITHER_THRESHOLDS[16] =
|
|
{
|
|
1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
|
|
13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
|
|
4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
|
|
16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
|
|
};
|
|
uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
|
|
return In - DITHER_THRESHOLDS[index];
|
|
}
|
|
|
|
#define SampleRampSignalLine(texture, u) (SAMPLE_TEXTURE2D_LOD(texture, s_linear_clamp_sampler, float2(u, 0.5), 0))
|
|
|
|
// Exposure
|
|
float3 ApplyCurrentExposureMultiplier(float3 color)
|
|
{
|
|
return color * lerp(GetCurrentExposureMultiplier(), 1, _ToonIgnoreExposureMultiplier);
|
|
}
|
|
|
|
float3 ConvertFromEV100(float3 EV100)
|
|
{
|
|
float3 value = pow(2, EV100) * 2.5f;
|
|
return value;
|
|
}
|
|
|
|
float3 ConvertToEV100(float3 value)
|
|
{
|
|
return log2(value * 0.4f);
|
|
}
|
|
|
|
float WeightSample(PositionInputs positionInput)
|
|
{
|
|
// Center-weighted
|
|
const float2 kCenter = _ScreenParams.xy * 0.5;
|
|
const float weight = pow(length((kCenter.xy - positionInput.positionSS.xy) / _ScreenParams.xy), 1.0);
|
|
return 1.0 - saturate(weight);
|
|
}
|
|
|
|
float3 ApplyCompensation(float3 originalColor)
|
|
{
|
|
float3 ev100_Color = ConvertToEV100(originalColor) + _ToonEvAdjustmentCompensation * 0.5f;
|
|
|
|
|
|
float3 resultColor = max(0, ConvertFromEV100(ev100_Color));
|
|
return resultColor;
|
|
}
|
|
|
|
float3 GetExposureAdjustedColor(float3 originalColor)
|
|
{
|
|
if (_ToonEvAdjustmentCurve != 0)
|
|
{
|
|
|
|
float3 ev100_Color = ConvertToEV100(originalColor);
|
|
ev100_Color = clamp(ev100_Color, _ToonEvAdjustmentValueMin, _ToonEvAdjustmentValueMax);
|
|
float3 ev100_remap = (ev100_Color - _ToonEvAdjustmentValueMin) * (128 - 1) / (_ToonEvAdjustmentValueMax - _ToonEvAdjustmentValueMin);
|
|
ev100_remap = clamp(ev100_remap, 0.0, 127.0);
|
|
int3 ev100_idx = (int3)ev100_remap;
|
|
float3 ev100_lerp = ev100_remap - ev100_idx;
|
|
float3 ev100_remapped;
|
|
|
|
ev100_remapped.r = _ToonEvAdjustmentValueArray[ev100_idx.r] + (_ToonEvAdjustmentValueArray[ev100_idx.r + 1] - _ToonEvAdjustmentValueArray[ev100_idx.r]) * ev100_lerp.r;
|
|
ev100_remapped.g = _ToonEvAdjustmentValueArray[ev100_idx.g] + (_ToonEvAdjustmentValueArray[ev100_idx.g + 1] - _ToonEvAdjustmentValueArray[ev100_idx.g]) * ev100_lerp.g;
|
|
ev100_remapped.b = _ToonEvAdjustmentValueArray[ev100_idx.b] + (_ToonEvAdjustmentValueArray[ev100_idx.b + 1] - _ToonEvAdjustmentValueArray[ev100_idx.b]) * ev100_lerp.b;
|
|
|
|
|
|
float3 resultColor = ConvertFromEV100(ev100_remapped);
|
|
|
|
|
|
return resultColor;
|
|
}
|
|
else // else is neccessary to avoid warrnings.
|
|
{
|
|
return originalColor;
|
|
}
|
|
}
|
|
|
|
void ApplyExposureAdjustment(inout float3 color)
|
|
{
|
|
color = GetExposureAdjustedColor(color);
|
|
color = ApplyCompensation(color);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Transform
|
|
// ----------------------------------------------------------------------------
|
|
|
|
float3 ProjectOnPlane(float3 vec, float3 normal)
|
|
{
|
|
return vec - normal * dot(vec, normal);
|
|
}
|
|
|
|
float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
|
|
{
|
|
float RotateUV_ang = _radian;
|
|
float RotateUV_cos = cos(_time * RotateUV_ang);
|
|
float RotateUV_sin = sin(_time * RotateUV_ang);
|
|
return(mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
|
|
}
|
|
|
|
// Anti-perspective form Colin: Counteract perspective effects by replacing regular depth with uniform depth
|
|
uniform float _AntiPerspectiveIntensity;
|
|
void AntiPerspective(inout float4 clipPos)
|
|
{
|
|
float centerVSz = mul(UNITY_MATRIX_V, float4(UNITY_MATRIX_M._m03_m13_m23, 1.0)).z;
|
|
clipPos.xy *= lerp(1.0, abs(clipPos.w) / - centerVSz, _AntiPerspectiveIntensity);
|
|
}
|
|
|
|
// ASE
|
|
float2 UnStereo(float2 UV)
|
|
{
|
|
#if UNITY_SINGLE_PASS_STEREO
|
|
float4 scaleOffset = unity_StereoScaleOffset[ unity_StereoEyeIndex ];
|
|
UV.xy = (UV.xy - scaleOffset.zw) / scaleOffset.xy;
|
|
#endif
|
|
return UV;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Color
|
|
// ----------------------------------------------------------------------------
|
|
float3 ShiftColorPurity(float3 color, float purity)
|
|
{
|
|
return lerp(Luminance(color), color, purity);
|
|
}
|
|
|
|
void AlphaGammaCorrection(inout float a1, inout float a2, inout float a3, inout float a4)
|
|
{
|
|
float4 a = float4(a1, a2, a3, a4);
|
|
a = pow(abs(a), 1 / 1.48);
|
|
a1 = a.x;
|
|
a2 = a.y;
|
|
a3 = a.z;
|
|
a4 = a.w;
|
|
}
|
|
|
|
void AlphaGammaCorrection(inout float alpha)
|
|
{
|
|
alpha = pow(abs(alpha), 1 / 1.48);
|
|
}
|
|
|
|
void AlphaGammaCorrection(inout float alpha, inout float alpha2)
|
|
{
|
|
AlphaGammaCorrection(alpha, alpha2, alpha, alpha);
|
|
}
|
|
|
|
void AlphaGammaCorrection(inout float alpha, inout float alpha2, inout float alpha3)
|
|
{
|
|
AlphaGammaCorrection(alpha, alpha2, alpha3, alpha3);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Depth
|
|
// ----------------------------------------------------------------------------
|
|
|
|
float LinearEyeDepth(float z)
|
|
{
|
|
return LinearEyeDepth(z, _ZBufferParams);
|
|
}
|
|
|
|
// https://forum.unity.com/threads/what-does-unity-exactly-do-when-we-modify-z-buffer-value-using-sv_depth.526406/
|
|
float LinearEyeDepthToOutDepth(float z)
|
|
{
|
|
return(1 - _ZBufferParams.w * z) / (_ZBufferParams.z * z);
|
|
}
|
|
|
|
// Returns the forward (Right) direction of the current view in the world space.
|
|
float3 GetViewRightDir()
|
|
{
|
|
float4x4 viewMat = GetWorldToViewMatrix();
|
|
return viewMat[0].xyz;
|
|
}
|
|
|
|
// ASE
|
|
float3 InvertDepthDirHD(float3 In)
|
|
{
|
|
float3 result = In;
|
|
#if !defined(ASE_SRP_VERSION) || ASE_SRP_VERSION <= 70301 || ASE_SRP_VERSION == 70503 || ASE_SRP_VERSION >= 80301
|
|
result *= float3(1, 1, -1);
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
float4x4 unity_CameraProjection;
|
|
float4x4 unity_CameraInvProjection;
|
|
float4x4 unity_WorldToCamera;
|
|
float4x4 unity_CameraToWorld;
|
|
|
|
// ASE
|
|
float3 GetWorldPosFromDepthBuffer(float2 clipPos01, float cameraDepth)
|
|
{
|
|
#ifdef UNITY_REVERSED_Z
|
|
float depth = (1.0 - cameraDepth);
|
|
#else
|
|
float depth = cameraDepth;
|
|
#endif
|
|
float3 screenPos_DepthBuffer = (float3(clipPos01, depth));
|
|
float4 clipPos = (float4((screenPos_DepthBuffer * 2.0 - 1.0), 1.0));
|
|
float4 viewPos = mul(unity_CameraInvProjection, clipPos);
|
|
float3 viewPosNorm = viewPos.xyz / viewPos.w;
|
|
float3 localInvertDepthDirHD = InvertDepthDirHD(viewPosNorm);
|
|
|
|
return mul(unity_CameraToWorld, float4(localInvertDepthDirHD, 1.0)).xyz;
|
|
}
|
|
#endif
|