Files
SimUL/Assets/o3n/o3nBaseUMARaces/Materials/o3n_Skin_FFS_Variant_Shader.shader
T
2025-01-08 00:15:45 +02:00

190 lines
6.3 KiB
Plaintext

Shader "o3n/Skin FFS Variant" {
Properties {
_MainTex ("Albedo (RGB) Alpha (A)", 2D) = "white" {}
_MaskTex ("Spec (R) Gloss (G) Occlusion (B)", 2D) = "white" {}
_SkinTex ("Skin Mask", 2D) = "white" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_BRDFTex ("Brdf Map", 2D) = "gray" {}
_BeckmannTex ("BeckmannTex", 2D) = "gray" {}
_SpecPow ("Specular", Range(0, 1)) = 0.03
_GlossPow ("Smoothness", Range(0, 1)) = 0.28
_AmbientContribution ("Ambience", Range(0, 1)) = 1
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags
{
"Queue" = "AlphaTest"
"RenderType" = "TransparentCutout"
}
LOD 300
Cull Back
CGPROGRAM
#pragma surface surf StandardSkin fullforwardshadows
#pragma target 3.0
#include "UnityCG.cginc"
struct SurfaceOutputStandardSkin {
fixed3 Albedo;
half Specular;
fixed3 Normal;
half3 Emission;
half Smoothness;
half Occlusion;
fixed Alpha;
fixed Skin;
};
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
float2 texcoord2 : TEXCOORD2;
};
struct Input {
float2 uv_MainTex;
float3 viewDir;
};
sampler2D _MainTex;
sampler2D _MaskTex;
sampler2D _NormalMap;
sampler2D _SkinTex;
float _SpecPow;
float _GlossPow;
float _AmbientContribution;
float _Cutoff;
sampler2D _BRDFTex;
sampler2D _BeckmannTex;
float Fresnel(float3 _half, float3 view, float f0) {
float base = 1.0 - dot(view, _half);
float exponential = pow(base, 5.0);
return exponential + f0 * (1.0 - exponential);
}
half SpecularKSK(sampler2D beckmannTex, float3 normal, float3 light, float3 view, float roughness) {
const float _specularFresnel = 1.08;
half3 _half = view + light;
half3 halfn = normalize(_half);
half ndotl = max(dot(normal, light), 0.0);
half ndoth = max(dot(normal, halfn), 0.0);
half ph = pow(2.0 * tex2D(beckmannTex, float2(ndoth, roughness)).r, 10.0);
half f = lerp(0.25, Fresnel(halfn, view, 0.028), _specularFresnel);
half ksk = max(ph * f / dot(_half, _half), 0.0);
return ndotl * ksk;
}
half3 Skin_BRDF_PBS (SurfaceOutputStandardSkin s, float oneMinusReflectivity, half3 viewDir, UnityLight light, UnityIndirect gi)
{
half3 normalizedLightDir = normalize(light.dir);
viewDir = normalize(viewDir);
float3 occl = light.color.rgb * s.Occlusion;
half specular = (s.Specular * SpecularKSK(_BeckmannTex, s.Normal, normalizedLightDir, viewDir , s.Smoothness) );
float dotNL = dot(s.Normal, normalizedLightDir);
float2 brdfUV = float2(dotNL * 0.5 + 0.5, 0.7 * dot(light.color, fixed3(0.2126, 0.7152, 0.0722)));
half3 brdf = tex2D( _BRDFTex, brdfUV ).rgb;
half nv = DotClamped (s.Normal, viewDir);
half grazingTerm = saturate(1-s.Smoothness + (1-oneMinusReflectivity));
half3 color = s.Albedo * (_AmbientContribution * gi.diffuse + occl * brdf)
+ specular * light.color
+ gi.specular * FresnelLerp (specular, grazingTerm, nv) * _AmbientContribution * 0.1; // reduced this effect to 10% to get rid of bright rim effect
// reflections
color += BRDF3_Indirect(0, s.Specular, gi, grazingTerm, 0);
return color;
}
half4 BRDF3_Unity_PBS__ (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness, half3 normal, half3 viewDir, UnityLight light, UnityIndirect gi)
{
half3 reflDir = reflect (viewDir, normal);
half nl = saturate(dot(normal, light.dir));
half nv = saturate(dot(normal, viewDir));
// Vectorize Pow4 to save instructions
half2 rlPow4AndFresnelTerm = Pow4 (half2(dot(reflDir, light.dir), 1-nv)); // use R.L instead of N.H to save couple of instructions
half rlPow4 = rlPow4AndFresnelTerm.x; // power exponent must match kHorizontalWarpExp in NHxRoughness() function in GeneratedTextures.cpp
half fresnelTerm = rlPow4AndFresnelTerm.y;
half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity));
half3 color = BRDF3_Direct(diffColor, specColor, rlPow4, smoothness);
color *= light.color * nl;
color += BRDF3_Indirect(diffColor, specColor, gi, grazingTerm, fresnelTerm);
return half4(color, 1);
}
inline half4 LightingStandardSkin (SurfaceOutputStandardSkin s, half3 viewDir, UnityGI gi)
{
s.Normal = normalize(s.Normal);
half oneMinusReflectivity;
half3 specColor;
s.Albedo = EnergyConservationBetweenDiffuseAndSpecular (s.Albedo, s.Specular, oneMinusReflectivity);
half outputAlpha;
s.Albedo = PreMultiplyAlpha (s.Albedo, s.Alpha, oneMinusReflectivity, outputAlpha);
half4 color = half4(0.0, 0.0, 0.0, 1.0);
if (s.Skin > 0.5) {
color.rgb = Skin_BRDF_PBS(s, oneMinusReflectivity, viewDir, gi.light, gi.indirect);
} else {
color.rgb = BRDF3_Unity_PBS__ (s.Albedo, s.Specular, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect);
}
color.a = outputAlpha;
return color;
}
inline void LightingStandardSkin_GI (SurfaceOutputStandardSkin s, UnityGIInput data, inout UnityGI gi)
{
gi = UnityGlobalIllumination (data, s.Occlusion, s.Smoothness, s.Normal);
}
void surf (Input IN, inout SurfaceOutputStandardSkin o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
if (c.a < _Cutoff) {
discard;
}
// Albedo
o.Albedo = c.rgb;
o.Alpha = c.a;
// Normal
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
// SPECULAR / GLOSS / Occlusion
half4 maskColor = tex2D (_MaskTex, IN.uv_MainTex);
o.Specular = maskColor.r * _SpecPow;
o.Smoothness = maskColor.g * _GlossPow;
o.Occlusion = maskColor.b;
// SET SKIN MASK
half4 skinFilter = tex2D(_SkinTex, IN.uv_MainTex);
o.Skin = skinFilter.r;
}
ENDCG
}
FallBack "Diffuse"
}