hellcat-nardo-felidal/Assets/RalivDynamicPenetrationSystem/Plugins/Xiexes-Unity-Shaders-development/Main/CGIncludes/XSHelperFunctions.cginc
2023-09-09 21:16:23 -07:00

395 lines
14 KiB
HLSL
Executable file

void calcNormal(inout XSLighting i)
{
if(_NormalMapMode == 0)
{
half3 nMap = UnpackScaleNormal(i.normalMap, _BumpScale);
half3 detNMap = UnpackScaleNormal(i.detailNormal, _DetailNormalMapScale);
half3 blendedNormal = lerp(nMap, BlendNormals(nMap, detNMap), i.detailMask.r);
half3 tspace0 = half3(i.tangent.x, i.bitangent.x, i.normal.x);
half3 tspace1 = half3(i.tangent.y, i.bitangent.y, i.normal.y);
half3 tspace2 = half3(i.tangent.z, i.bitangent.z, i.normal.z);
half3 calcedNormal;
calcedNormal.x = dot(tspace0, blendedNormal);
calcedNormal.y = dot(tspace1, blendedNormal);
calcedNormal.z = dot(tspace2, blendedNormal);
calcedNormal = normalize(calcedNormal);
half3 bumpedTangent = cross(i.bitangent, calcedNormal);
half3 bumpedBitangent = cross(calcedNormal, bumpedTangent);
i.normal = calcedNormal;
i.tangent = bumpedTangent;
i.bitangent = bumpedBitangent;
}
else
{
float3 vcol = i.color.rgb * 2 - 1;
half3 tspace0 = half3(i.tangent.x, i.bitangent.x, i.normal.x);
half3 tspace1 = half3(i.tangent.y, i.bitangent.y, i.normal.y);
half3 tspace2 = half3(i.tangent.z, i.bitangent.z, i.normal.z);
half3 calcedNormal;
calcedNormal.x = dot(tspace0, vcol);
calcedNormal.y = dot(tspace1, vcol);
calcedNormal.z = dot(tspace2, vcol);
//calcedNormal = calcedNormal;
i.normal = normalize(calcedNormal);
}
}
void InitializeTextureUVs(
#if defined(Geometry)
in g2f i,
#else
in VertexOutput i,
#endif
inout TextureUV t)
{
#if defined(PatreonEyeTracking)
float2 eyeUvOffset = eyeOffsets(i.uv, i.objPos, i.worldPos, i.ntb[0]);
i.uv = eyeUvOffset;
i.uv1 = eyeUvOffset;
#endif
half2 uvSetAlbedo = (_UVSetAlbedo == 0) ? i.uv : i.uv1;
t.albedoUV = TRANSFORM_TEX(uvSetAlbedo, _MainTex);
half2 uvSetClipMap = (_UVSetClipMap == 0) ? i.uv : i.uv1;
t.clipMapUV = TRANSFORM_TEX(uvSetClipMap, _ClipMap);
half2 uvSetDissolveMap = (_UVSetDissolve == 0) ? i.uv : i.uv1;
t.dissolveUV = TRANSFORM_TEX(uvSetDissolveMap, _DissolveTexture);
#if !defined(UNITY_PASS_SHADOWCASTER)
half2 uvSetNormalMap = (_UVSetNormal == 0) ? i.uv : i.uv1;
t.normalMapUV = TRANSFORM_TEX(uvSetNormalMap, _BumpMap);
half2 uvSetEmissionMap = (_UVSetEmission == 0) ? i.uv : i.uv1;
t.emissionMapUV = TRANSFORM_TEX(uvSetEmissionMap, _EmissionMap);
half2 uvSetMetallicGlossMap = (_UVSetMetallic == 0) ? i.uv : i.uv1;
t.metallicGlossMapUV = TRANSFORM_TEX(uvSetMetallicGlossMap, _MetallicGlossMap);
half2 uvSetOcclusion = (_UVSetOcclusion == 0) ? i.uv : i.uv1;
t.occlusionUV = TRANSFORM_TEX(uvSetOcclusion, _OcclusionMap);
half2 uvSetDetailNormal = (_UVSetDetNormal == 0) ? i.uv : i.uv1;
t.detailNormalUV = TRANSFORM_TEX(uvSetDetailNormal, _DetailNormalMap);
half2 uvSetDetailMask = (_UVSetDetMask == 0) ? i.uv : i.uv1;
t.detailMaskUV = TRANSFORM_TEX(uvSetDetailMask, _DetailMask);
half2 uvSetSpecularMap = (_UVSetSpecular == 0) ? i.uv : i.uv1;
t.specularMapUV = TRANSFORM_TEX(uvSetSpecularMap, _SpecularMap);
half2 uvSetThickness = (_UVSetThickness == 0) ? i.uv : i.uv1;
t.thicknessMapUV = TRANSFORM_TEX(uvSetThickness, _ThicknessMap);
half2 uvSetReflectivityMask = (_UVSetReflectivity == 0) ? i.uv : i.uv1;
t.reflectivityMaskUV = TRANSFORM_TEX(uvSetReflectivityMask, _ReflectivityMask);
#endif
}
float Remap_Float(float In, float2 InMinMax, float2 OutMinMax)
{
return OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
}
half3 rgb2hsv(half3 c)
{
half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
half3 hsv2rgb(half3 c)
{
half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void InitializeTextureUVsMerged(
#if defined(Geometry)
in g2f i,
#else
in VertexOutput i,
#endif
inout TextureUV t)
{
half2 uvSetAlbedo = (_UVSetAlbedo == 0) ? i.uv : i.uv1;
t.albedoUV = TRANSFORM_TEX(uvSetAlbedo, _MainTex);
t.normalMapUV = t.albedoUV;
t.emissionMapUV = t.albedoUV;
t.metallicGlossMapUV = t.albedoUV;
t.occlusionUV = t.albedoUV;
t.detailNormalUV = t.albedoUV;
t.detailMaskUV = t.albedoUV;
t.specularMapUV = t.albedoUV;
t.thicknessMapUV = t.albedoUV;
t.reflectivityMaskUV = t.albedoUV;
t.clipMapUV = t.albedoUV;
//Dissolve map makes sense to be on a sep. UV always.
half2 uvSetDissolveMap = (_UVSetDissolve == 0) ? i.uv : i.uv1;
t.dissolveUV = TRANSFORM_TEX(uvSetDissolveMap, _DissolveTexture);
}
bool IsInMirror()
{
return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
}
inline half Dither8x8Bayer( int x, int y )
{
const half dither[ 64 ] = {
1, 49, 13, 61, 4, 52, 16, 64,
33, 17, 45, 29, 36, 20, 48, 32,
9, 57, 5, 53, 12, 60, 8, 56,
41, 25, 37, 21, 44, 28, 40, 24,
3, 51, 15, 63, 2, 50, 14, 62,
35, 19, 47, 31, 34, 18, 46, 30,
11, 59, 7, 55, 10, 58, 6, 54,
43, 27, 39, 23, 42, 26, 38, 22};
int r = y * 8 + x;
return dither[r] / 64;
}
half calcDither(half2 screenPos)
{
half dither = Dither8x8Bayer(fmod(screenPos.x, 8), fmod(screenPos.y, 8));
return dither;
}
half2 calcScreenUVs(half4 screenPos)
{
half2 uv = screenPos / (screenPos.w + 0.0000000001); //0.0x1 Stops division by 0 warning in console.
#if UNITY_SINGLE_PASS_STEREO
uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
#else
uv.xy *= _ScreenParams.xy;
#endif
return uv;
}
half3 calcViewDir(half3 worldPos)
{
half3 viewDir = _WorldSpaceCameraPos - worldPos;
return normalize(viewDir);
}
half3 calcStereoViewDir(half3 worldPos)
{
#if UNITY_SINGLE_PASS_STEREO
half3 cameraPos = half3((unity_StereoWorldSpaceCameraPos[0]+ unity_StereoWorldSpaceCameraPos[1])*.5);
#else
half3 cameraPos = _WorldSpaceCameraPos;
#endif
half3 viewDir = cameraPos - worldPos;
return normalize(viewDir);
}
half2 matcapSample(half3 worldUp, half3 viewDirection, half3 normalDirection)
{
half3 worldViewUp = normalize(worldUp - viewDirection * dot(viewDirection, worldUp));
half3 worldViewRight = normalize(cross(viewDirection, worldViewUp));
half2 matcapUV = half2(dot(worldViewRight, normalDirection), dot(worldViewUp, normalDirection)) * 0.5 + 0.5;
return matcapUV;
}
//Reflection direction, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax
half3 getReflectionUV(half3 direction, half3 position, half4 cubemapPosition, half3 boxMin, half3 boxMax)
{
#if UNITY_SPECCUBE_BOX_PROJECTION
if (cubemapPosition.w > 0) {
half3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
half scalar = min(min(factors.x, factors.y), factors.z);
direction = direction * scalar + (position - cubemapPosition);
}
#endif
return direction;
}
half3 getEnvMap(XSLighting i, DotProducts d, float blur, half3 reflDir, half3 indirectLight, half3 wnormal)
{//This function handls Unity style reflections, Matcaps, and a baked in fallback cubemap.
half3 envMap = half3(0,0,0);
#if defined(UNITY_PASS_FORWARDBASE) //Indirect PBR specular should only happen in the forward base pass. Otherwise each extra light adds another indirect sample, which could mean you're getting too much light.
half3 reflectionUV1 = getReflectionUV(reflDir, i.worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
half4 probe0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectionUV1, blur);
half3 probe0sample = DecodeHDR(probe0, unity_SpecCube0_HDR);
half3 indirectSpecular;
half interpolator = unity_SpecCube0_BoxMin.w;
UNITY_BRANCH
if (interpolator < 0.99999)
{
half3 reflectionUV2 = getReflectionUV(reflDir, i.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
half4 probe1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, reflectionUV2, blur);
half3 probe1sample = DecodeHDR(probe1, unity_SpecCube1_HDR);
indirectSpecular = lerp(probe1sample, probe0sample, interpolator);
}
else
{
indirectSpecular = probe0sample;
}
envMap = indirectSpecular;
#endif
return envMap;
}
float AlphaAdjust(float alphaToAdj, float3 vColor)
{
_ClipAgainstVertexColorGreaterZeroFive = saturate(_ClipAgainstVertexColorGreaterZeroFive); //So the lerp doesn't go crazy
_ClipAgainstVertexColorLessZeroFive = saturate(_ClipAgainstVertexColorLessZeroFive);
float modR = vColor.r < 0.5 ? _ClipAgainstVertexColorLessZeroFive.r : _ClipAgainstVertexColorGreaterZeroFive.r;
float modG = vColor.g < 0.5 ? _ClipAgainstVertexColorLessZeroFive.g : _ClipAgainstVertexColorGreaterZeroFive.g;
float modB = vColor.b < 0.5 ? _ClipAgainstVertexColorLessZeroFive.b : _ClipAgainstVertexColorGreaterZeroFive.b;
alphaToAdj *= lerp(0, 1, lerp(1, modR, step(0.01, vColor.r)));
alphaToAdj *= lerp(0, 1, lerp(1, modG, step(0.01, vColor.g)));
alphaToAdj *= lerp(0, 1, lerp(1, modB, step(0.01, vColor.b)));
return alphaToAdj;
}
void calcDissolve(inout XSLighting i, inout float4 col)
{
#ifdef _ALPHATEST_ON
half dissolveAmt = Remap_Float(i.dissolveMask.x, float2(0,1), float2(0.1, 0.9));
half dissolveProgress = saturate(_DissolveProgress + lerp(0, 1-AlphaAdjust(1, i.clipMap.rgb), _UseClipsForDissolve));
half dissolve = 0;
if (_DissolveCoordinates == 0)
{
dissolve = dissolveAmt - dissolveProgress;
clip(dissolve);
}
if(_DissolveCoordinates == 1)
{
half distToCenter = 1-length(i.objPos);
dissolve = ((distToCenter + dissolveAmt) * 0.5) - dissolveProgress;
clip(dissolve);
}
if(_DissolveCoordinates == 2)
{
half distToCenter = (1-i.objPos.y) * 0.5 + 0.5;
dissolve = ((distToCenter + dissolveAmt) * 0.5) - dissolveProgress;
clip(dissolve);
}
#if !defined(UNITY_PASS_SHADOWCASTER)
float4 dissCol = _DissolveColor;
dissCol.rgb = rgb2hsv(dissCol.rgb);
dissCol.x += fmod(_Hue, 360);
dissCol.y = saturate(dissCol.y * _Saturation);
dissCol.z *= _Value;
dissCol.rgb = hsv2rgb(dissCol.rgb);
half dissolveEdge = smoothstep(dissolve, dissolve - (_DissolveStrength * 0.01), dissolve * dissolveAmt);
col.rgb += (1-dissolveEdge) * dissCol.rgb;
#endif
#endif
}
void calcAlpha(inout XSLighting i)
{
i.alpha = 1;
#ifdef _ALPHABLEND_ON
i.alpha = i.albedo.a;
#ifdef UNITY_PASS_SHADOWCASTER
half dither = calcDither(i.screenUV.xy);
clip(i.alpha - dither);
#endif
#endif
#ifdef _ALPHATEST_ON
float modifiedAlpha = lerp(AlphaAdjust(i.albedo.a, i.clipMap.rgb), i.albedo.a, _UseClipsForDissolve);
if(_BlendMode >= 3)
{
half dither = calcDither(i.screenUV.xy);
i.alpha = modifiedAlpha - (dither * (1-i.albedo.a) * 0.15);
}
if(_BlendMode == 2)
{
half dither = calcDither(i.screenUV.xy);
float fadeDist = abs(_FadeDitherDistance);
float d = distance(_WorldSpaceCameraPos, i.worldPos);
d = smoothstep(fadeDist, fadeDist + 0.05, d);
d = lerp(d, 1-d, saturate(step(0, _FadeDitherDistance)));
dither += lerp(0, d, saturate(_FadeDither));
clip(modifiedAlpha - dither);
}
if(_BlendMode == 1)
{
clip(modifiedAlpha - _Cutoff);
}
#endif
}
// //Halftone functions, finish implementing later.. Not correct right now.
float2 SphereUV( float3 coords /*viewDir?*/)
{
float3 nc = normalize(coords);
float lat = acos(nc.y);
float lon = atan2(nc.z, nc.x);
float2 coord = 1.0 - (float2(lon, lat) * float2(1.0/UNITY_PI, 1.0/UNITY_PI));
return (coord + float4(0, 1-unity_StereoEyeIndex,1,1.0).xy) * float4(0, 1-unity_StereoEyeIndex,1,1.0).zw;
}
half2 rotateUV(half2 uv, half rotation)
{
half mid = 0.5;
return half2(
cos(rotation) * (uv.x - mid) + sin(rotation) * (uv.y - mid) + mid,
cos(rotation) * (uv.y - mid) - sin(rotation) * (uv.x - mid) + mid
);
}
half DotHalftone(XSLighting i, half scalar) //Scalar can be anything from attenuation to a dot product
{
bool inMirror = IsInMirror();
half2 uv = SphereUV(calcViewDir(i.worldPos));
uv.xy *= _HalftoneDotAmount;
half2 nearest = 2 * frac(100 * uv) - 1;
half dist = length(nearest);
half dotSize = 100 * _HalftoneDotSize * scalar;
half dotMask = step(dotSize, dist);
return lerp(1, 1-dotMask, smoothstep(0, 0.4, 1/distance(i.worldPos, _WorldSpaceCameraPos)));;
}
half LineHalftone(XSLighting i, half scalar)
{
// #if defined(DIRECTIONAL)
// scalar = saturate(scalar + ((1-i.attenuation) * 0.2));
// #endif
bool inMirror = IsInMirror();
half2 uv = SphereUV(calcViewDir(i.worldPos));
uv = rotateUV(uv, -0.785398);
uv.x = sin(uv.x * _HalftoneLineAmount * scalar);
half2 steppedUV = smoothstep(0,0.2,uv.x);
half lineMask = lerp(1, steppedUV, smoothstep(0, 0.4, 1/distance(i.worldPos, _WorldSpaceCameraPos)));
return saturate(lineMask);
}
//