Files
AIC-Project/Client/Assets/Game/shader/SGame/Base/CharacterPBR_Inputs.hlsl
T

354 lines
14 KiB
HLSL

#ifndef CHARACTERCOMMONUTIL_BASE
#define CHARACTERCOMMONUTIL_BASE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
inline half3 BlendMode_Screen( half3 s, half3 d)
{
return s + d - s*d;
}
inline half3 RotationY(half3 pointP, half angle)
{
half radY = radians(angle);
half sinY = sin(radY);
half cosY = cos(radY);
return half3(pointP.x * cosY - pointP.z * sinY,
pointP.y, pointP.x * sinY + pointP.z * cosY);
}
inline half3 RgbToHsv_SGame(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));
half d = q.x - min(q.w, q.y);
half e = 1.0e-4;
return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
inline half3 HsvToRgb_SGame(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, saturate(p - K.xxx), c.y);
}
struct UnityLight
{
half3 color;
half3 dir;
half ndotl; // Deprecated: Ndotl is now calculated on the fly and is no longer stored. Do not used it.
};
struct UnityIndirect
{
half3 diffuse;
half3 specular;
};
struct UnityGI
{
UnityLight light;
UnityIndirect indirect;
};
struct UnityGIInput
{
UnityLight light; // pixel light, sent from the engine
float3 worldPos;
half3 worldViewDir;
half atten;
half3 ambient;
float4 lightmapUV; // .xy = static lightmap UV, .zw = dynamic lightmap UV
#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) || defined(UNITY_ENABLE_REFLECTION_BUFFERS)
float4 boxMin[2];
#endif
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
float4 boxMax[2];
float4 probePosition[2];
#endif
// HDR cubemap properties, use to decompress HDR texture
float4 probeHDR[2];
};
struct Unity_GlossyEnvironmentData
{
half roughness; // CAUTION: This is perceptualRoughness but because of compatibility this name can't be change :(
half3 reflUVW;
};
//-------------------------------------------------------------------------------------
half3 NormalizePerVertexNormal (float3 n) // takes float to avoid overflow
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return normalize(n);
#else
return n; // will normalize per-pixel instead
#endif
}
half3 NormalizePerPixelNormal (half3 n)
{
#if (SHADER_TARGET < 30) || UNITY_STANDARD_SIMPLE
return n;
#else
return normalize(n);
#endif
}
//-------------------------------------------------------------------------------------
UnityLight MainLight ()
{
UnityLight l;
l.color = GetMainLight().color.rgb;
half3 hsvLightCol = RgbToHsv_SGame(GetMainLight().color.rgb);
hsvLightCol.b = clamp(hsvLightCol.b, 0.9, 1.1);
l.color = HsvToRgb_SGame(hsvLightCol);
l.dir = GetMainLight().direction;
return l;
}
UnityLight AdditiveLight (half3 lightDir, half atten)
{
UnityLight l;
l.color = GetMainLight().color.rgb;
l.dir = lightDir;
#ifndef USING_DIRECTIONAL_LIGHT
l.dir = NormalizePerPixelNormal(l.dir);
#endif
l.color *= atten;
return l;
}
UnityLight DummyLight ()
{
UnityLight l;
l.color = 0;
l.dir = half3 (0,1,0);
return l;
}
UnityIndirect ZeroIndirect ()
{
UnityIndirect ind;
ind.diffuse = 0;
ind.specular = 0;
return ind;
}
Unity_GlossyEnvironmentData UnityGlossyEnvironmentSetup(half Smoothness, half3 worldViewDir, half3 Normal, half3 fresnel0)
{
Unity_GlossyEnvironmentData g;
g.roughness /* perceptualRoughness */ = PerceptualSmoothnessToPerceptualRoughness(Smoothness);
g.reflUVW = reflect(-worldViewDir, Normal);
return g;
}
inline void ResetUnityLight(out UnityLight outLight)
{
outLight.color = half3(0, 0, 0);
outLight.dir = half3(0, 1, 0); // Irrelevant direction, just not null
outLight.ndotl = 0; // Not used
}
inline void ResetUnityGI(out UnityGI outGI)
{
ResetUnityLight(outGI.light);
outGI.indirect.diffuse = 0;
outGI.indirect.specular = 0;
}
half3 UnpackScaleNormalRGorAG(half4 packednormal, half bumpScale)
{
#if defined(UNITY_NO_DXT5nm)
half3 normal = packednormal.xyz * 2 - 1;
#if (SHADER_TARGET >= 30)
normal.xy *= bumpScale;
#endif
return normal;
#elif defined(UNITY_ASTC_NORMALMAP_ENCODING)
half3 normal;
normal.xy = (packednormal.wy * 2 - 1);
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
normal.xy *= bumpScale;
return normal;
#else
packednormal.x *= packednormal.w;
half3 normal;
normal.xy = (packednormal.xy * 2 - 1);
#if (SHADER_TARGET >= 30)
normal.xy *= bumpScale;
#endif
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
return normal;
#endif
}
half3 UnpackScaleNormal(half4 packednormal, half bumpScale)
{
return UnpackScaleNormalRGorAG(packednormal, bumpScale);
}
half3x3 CreateTangentToWorldPerVertex(half3 normal, half3 tangent, half tangentSign)
{
// For odd-negative scale transforms we need to flip the sign
half sign = tangentSign * unity_WorldTransformParams.w;
half3 binormal = cross(normal, tangent) * sign;
return half3x3(tangent, binormal, normal);
}
// ----------------------------------------------------------------------------
inline half3 DecodeHDR (half4 data, half4 decodeInstructions)
{
// Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels)
half alpha = decodeInstructions.w * (data.a - 1.0) + 1.0;
// If Linear mode is not supported we can skip exponent part
#if defined(UNITY_COLORSPACE_GAMMA)
return (decodeInstructions.x * alpha) * data.rgb;
#else
#if defined(UNITY_USE_NATIVE_HDR)
return decodeInstructions.x * data.rgb; // Multiplier for future HDRI relative to absolute conversion.
#else
return (decodeInstructions.x * pow(alpha, decodeInstructions.y)) * data.rgb;
#endif
#endif
}
inline half3 PreMultiplyAlpha (half3 diffColor, half alpha, half oneMinusReflectivity, out half outModifiedAlpha)
{
diffColor *= alpha;
outModifiedAlpha = 1-oneMinusReflectivity + alpha*oneMinusReflectivity;
return diffColor;
}
inline half OneMinusReflectivityFromMetallic(half metallic)
{
half oneMinusDielectricSpec = 0.56;
return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
}
inline half3 DiffuseAndSpecularFromMetallic (half3 albedo, half metallic, out half3 specColor, out half oneMinusReflectivity)
{
specColor = lerp (UNITY_LIGHTMODEL_AMBIENT.xyz, albedo, metallic);
oneMinusReflectivity = OneMinusReflectivityFromMetallic(metallic);
return albedo * oneMinusReflectivity;
}
inline UnityGI UnityGI_Base(UnityGIInput data, half occlusion, half3 normalWorld)
{
UnityGI o_gi;
ResetUnityGI(o_gi);
o_gi.light = data.light;
o_gi.light.color *= data.atten;
o_gi.indirect.diffuse *= occlusion;
return o_gi;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, Unity_GlossyEnvironmentData glossIn)
{
half3 specular;
specular = unity_IndirectSpecColor.rgb;
return specular * occlusion;
}
inline half3 UnityGI_IndirectSpecular(UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
return UnityGI_IndirectSpecular(data, occlusion, glossIn);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld)
{
return UnityGI_Base(data, occlusion, normalWorld);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half3 normalWorld, Unity_GlossyEnvironmentData glossIn)
{
UnityGI o_gi = UnityGI_Base(data, occlusion, normalWorld);
o_gi.indirect.specular = UnityGI_IndirectSpecular(data, occlusion, glossIn);
return o_gi;
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld, bool reflections)
{
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(smoothness, data.worldViewDir, normalWorld, float3(0, 0, 0));
return UnityGlobalIllumination(data, occlusion, normalWorld, g);
}
inline UnityGI UnityGlobalIllumination (UnityGIInput data, half occlusion, half smoothness, half3 normalWorld)
{
bool sampleReflections = true;
return UnityGlobalIllumination (data, occlusion, smoothness, normalWorld, sampleReflections);
}
inline half3 GetSpecularColorGGX_Smoothness (half ndotH, half ndotL, half ldotH, half3 specularColor, half smoothness, half powFac = 64, half ggxClamp = 3)
{
half3 specular = 0;
#if defined(_SG_GGX_SMOOTH)
half perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.08, perceptualRoughness);
half roughness = PerceptualSmoothnessToPerceptualRoughness(perceptualRoughness);
half a = roughness;
half a2 = a * a;
half d = ndotH * ndotH * (a2 - 1) + 1.0001;
half specularTerm = a2 / (max(0.2, ldotH * ldotH) * (roughness + 0.5) * (d * d) * powFac);
specularTerm = specularTerm - 1e-4h;
specularTerm = clamp(specularTerm, 0, ggxClamp);
specular = specularTerm * specularColor.rgb;
#endif
return specular;
}
inline half3x3 GetDiffuseColor(half smoothness, half3 specularColor, half3 mainColor,
half3 worldNormal, half lightAtten, half3 NDotL)
{
half3 lightColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten * NDotL);
specularColor = lerp(half3(0,0,0), GetMainLight().color.rgb, lightAtten) * specularColor;
half3 diffuse = mainColor * lightColor;
#if defined(SGAME_WET) && defined(SGAME_QUALITY_PERFECT) || defined(SGAME_QUALITY_HIGH)
mainColor = lerp(mainColor, mainColor * _SG_WetColor, _SG_WetFactor);
specularColor = lerp(specularColor, _SG_WetSpecularColor * _SG_WetSpecularStrength, _SG_WetFactor);
smoothness = lerp(lerp(smoothness, _SG_WetSmoothness, _SG_WetFactor), smoothness, smoothness > _SG_WetSmoothness);
half thunderNDotL = saturate(dot(worldNormal, _SG_ThunderDirection));
half3 thunderDiffuse = mainColor * lerp(half3(0, 0, 0), _SG_ThunderColor, max(lightAtten,0.1)) * thunderNDotL * _SG_ThunderStrength;
diffuse += thunderDiffuse;
#endif
half3x3 matrixColor;
matrixColor[0] = diffuse;
matrixColor[1] = specularColor;
matrixColor[2] = half3(smoothness, 0, 0);
return matrixColor;
}
inline half3 GetSumLightingColorSpecGGX_Smoothness(half3 mainColor, half3 specularColor, half3 shLight,
half3 worldNormal, half3 worldPos, half smoothness, half lightAtten, half powFac = 64, half ggxClamp = 3, half intensity = 1)
{
half3 worldViewDir = normalize(GetCameraPositionWS() - worldPos);
half3 worldLightDir = normalize(GetMainLight().direction);
half3 halfDir = normalize(worldLightDir + worldViewDir);
half ndotH = max(dot(worldNormal, halfDir), 0);
half NDotL = max(dot(worldNormal, worldLightDir), 0);
half ldotH = max(dot(worldLightDir, halfDir), 0);
half3x3 colorMatrix = GetDiffuseColor(smoothness, specularColor, mainColor, worldNormal, lightAtten, NDotL);
specularColor = colorMatrix[1];
smoothness = colorMatrix[2].x;
half3 ambient = mainColor * 0.5;
half3 diffuse = colorMatrix[0];
half3 specular = GetSpecularColorGGX_Smoothness(ndotH, NDotL, ldotH, specularColor, smoothness, powFac, ggxClamp);
return ambient + diffuse + specular * intensity;
}
inline half SGameShadowAtten(half atten)
{
return max(atten, 0.2);
}
inline half SGameStylizedAtten(half atten, half _DoubleSGameShadowAtten)
{
half stylizedAtten = (atten + _DoubleSGameShadowAtten) * 0.5;
stylizedAtten = saturate(stylizedAtten);
return stylizedAtten;
}
inline half SGameRoughness(half smoothness, out half perceptualRoughness )
{
perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness (smoothness);
perceptualRoughness = max(0.001, perceptualRoughness);
half roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
return roughness;
}
inline half SGameDirectSpecular(half3 normal, half3 viewDir, half NDotL, half metallic, half nh, half lh)
{
half3 backfaceLightDir = viewDir;
half3 backfaceHalfDir = viewDir;
half backface_nh = saturate(dot(normal, backfaceHalfDir));
half backface_lh = saturate(dot(backfaceLightDir, backfaceHalfDir));
//half notBackface = smoothstep(0,0.5,NDotL * 0.5 + 0.5); //0背光 -> 1受光
half notBackface = smoothstep(-1,0.5,NDotL); //0背光 -> 1受光
//nh = lerp(backface_nh, nh, notBackface);
//lh = lerp(backface_lh, lh, notBackface);
half isBackface = 1 - smoothstep(-1,0.5,NDotL);
//half ratio = isBackface * step(0.5, metallic);
half ratio = isBackface * lerp(0.3,1,metallic);
nh = lerp(nh, backface_nh, ratio);
lh = lerp(lh, backface_lh, ratio);
return isBackface;
}
inline half3 SGameStylizedSpecularColor( half3 specularColor, half metallic )
{
half3 linearSpecularColor = specularColor * specularColor;
specularColor = lerp( linearSpecularColor, specularColor, metallic );
return specularColor;
}
#endif