206 lines
8.3 KiB
Plaintext
206 lines
8.3 KiB
Plaintext
// ***********************************************************************
|
|
// Author : Kimch
|
|
// Created : 2018-7-1
|
|
// Description : 角色Shader
|
|
// Last Modified By : Kimch
|
|
// Last Modified On : 2019-7-1
|
|
// ***********************************************************************
|
|
// <copyright file= "MY_PBS_SkinV2" company="kk"></copyright>
|
|
// ***********************************************************************
|
|
Shader "MY/PBS/Skin"
|
|
{
|
|
Properties
|
|
{
|
|
_Color("Color", Color) = (1,1,1,1)
|
|
_MainTex("Albedo (RGB)", 2D) = "white" {}
|
|
_Glossiness("Smoothness", Range(0,1)) = 0.5
|
|
_Metallic("Metallic", Range(0,1)) = 0.0
|
|
|
|
// BRDF Lookup texture, light direction on x and curvature on y.
|
|
_BRDFTex("BRDF Lookup (RGB)", 2D) = "gray" {}
|
|
_SSSTex("Curvature(R) thickness(G)", 2D) = "gray" {}
|
|
_CurvatureScale("Curvature Scale", Range(0,1)) = 1
|
|
_ThicknessScale("Subsurface Scale", Range(0,1)) = 0.5
|
|
_SubColor("Subsurface Color", Color) = (1, .4, .25, 1)
|
|
_Power("Subsurface Power", Range(0,100)) = 100
|
|
_Distortion("Subsurface Distortion", Range(0,1)) = 0
|
|
|
|
|
|
}
|
|
SubShader
|
|
{
|
|
Tags { "RenderType" = "Opaque" }
|
|
LOD 200
|
|
CGINCLUDE
|
|
//#include "UnityStandardBRDF.cginc"
|
|
ENDCG
|
|
|
|
CGPROGRAM
|
|
// Physically based Standard lighting model, and enable shadows on all light types
|
|
#pragma surface surf MYStandard fullforwardshadows exclude_path:deferred exclude_path:prepass nometa nolightmap nofog noambient nolppv noinstancing
|
|
|
|
// Use shader model 3.0 target, to get nicer looking lighting
|
|
#pragma target 3.0
|
|
|
|
sampler2D _MainTex;
|
|
|
|
sampler2D _BRDFTex; half4 _BRDFTex_ST;
|
|
sampler2D _SSSTex; half4 _SSSTex_ST;
|
|
half _CurvatureScale;
|
|
half _ThicknessScale;
|
|
half3 _SubColor;
|
|
half _Power;
|
|
half _Distortion;
|
|
|
|
|
|
struct Input
|
|
{
|
|
float2 uv_MainTex;
|
|
};
|
|
|
|
half _Glossiness;
|
|
half _Metallic;
|
|
fixed4 _Color;
|
|
|
|
struct SurfaceOutputStandard
|
|
{
|
|
fixed3 Albedo; // base (diffuse or specular) color
|
|
float3 Normal; // tangent space normal, if written
|
|
half3 Emission;
|
|
half Metallic; // 0=non-metal, 1=metal
|
|
// Smoothness is the user facing name, it should be perceptual smoothness but user should not have to deal with it.
|
|
// Everywhere in the code you meet smoothness it is perceptual smoothness
|
|
half Smoothness; // 0=rough, 1=smooth
|
|
half Occlusion; // occlusion (default 1)
|
|
fixed Alpha; // alpha for transparencies
|
|
|
|
fixed4 sssTex;
|
|
};
|
|
|
|
#define _SKIN
|
|
// Skin
|
|
#ifdef _SKIN
|
|
inline fixed4 SKIN_BRDF_PBS(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
|
|
float3 normal, float3 viewDir,
|
|
UnityLight light, UnityIndirect gi,
|
|
half4 sssTex)
|
|
{
|
|
half curvature = sssTex.r*_CurvatureScale;
|
|
half thickness = 1 - sssTex.g;
|
|
|
|
#define OneOnLN2_x6 8.656170
|
|
|
|
half dotNL = max(0, dot(normal, light.dir));
|
|
half dotNV = max(0, dot(normal, viewDir)); // UNITY BRDF does not normalize(viewDir) ) );
|
|
half3 halfDir = normalize(light.dir + viewDir);
|
|
half dotNH = max(0, dot(normal, halfDir));
|
|
half dotLH = max(0, dot(light.dir, halfDir));
|
|
|
|
// ////////////////////////////////////////////////////////////
|
|
// Cook Torrrance
|
|
// from The Order 1886 // http://blog.selfshadow.com/publications/s2013-shading-course/rad/s2013_pbs_rad_notes.pdf
|
|
half alpha = 1 - smoothness; // alpha is roughness
|
|
alpha *= alpha;
|
|
half alpha2 = alpha * alpha;
|
|
|
|
// Specular Normal Distribution Function: GGX Trowbridge Reitz
|
|
half denominator = (dotNH * dotNH) * (alpha2 - 1.f) + 1.f;
|
|
half D = alpha2 / (UNITY_PI * denominator * denominator);
|
|
// Geometric Shadowing: Smith
|
|
// B. Karis, http://graphicrants.blogspot.se/2013/08/specular-brdf-reference.html
|
|
half G_L = dotNL + sqrt((dotNL - dotNL * alpha) * dotNL + alpha);
|
|
half G_V = dotNV + sqrt((dotNV - dotNV * alpha) * dotNV + alpha);
|
|
half G = 1.0 / (G_V * G_L);
|
|
// Fresnel: Schlick / fast fresnel approximation
|
|
half F = 1 - oneMinusReflectivity + (oneMinusReflectivity)* exp2(-OneOnLN2_x6 * dotNH);
|
|
|
|
// half3 FresnelSchlickWithRoughness = s.Specular + ( max(s.Specular, oneMinusRoughness) - s.Specular) * exp2(-OneOnLN2_x6 * dotNV );
|
|
|
|
// Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II", changed by EPIC
|
|
const half4 c0 = { -1, -0.0275, -0.572, 0.022 };
|
|
const half4 c1 = { 1, 0.0425, 1.04, -0.04 };
|
|
half4 r = (1 - smoothness) * c0 + c1;
|
|
half a004 = min(r.x * r.x, exp2(-9.28 * dotNV)) * r.x + r.y;
|
|
half2 AB = half2(-1.04, 1.04) * a004 + r.zw;
|
|
half3 F_L = specColor * AB.x + AB.y;
|
|
|
|
// Skin Lighting
|
|
float2 brdfUV;
|
|
// Half-Lambert lighting value based on blurred normals.
|
|
brdfUV.x = dotNL * 0.5 + 0.5;
|
|
// Curvature amount. Multiplied by light's luminosity so brighter light = more scattering.
|
|
// Pleae note: gi.light.color already contains light attenuation
|
|
brdfUV.y = curvature * dot(light.color, fixed3(0.22, 0.707, 0.071));
|
|
half3 brdf = tex2D(_BRDFTex, brdfUV).rgb;
|
|
|
|
// Translucency
|
|
// #if defined (DIRECTIONAL) && defined (LUX_DIRECTIONAL_SSS) || defined (DIRECTIONAL_COOKIE) && defined (LUX_DIRECTIONAL_SSS) || defined (POINT) && defined (LUX_POINT_SSS) || defined (POINT_COOKIE) && defined (LUX_POINT_SSS) || defined (SPOT) && defined (LUX_SPOT_SSS)
|
|
float3 H = normalize(light.dir + normal * _Distortion);
|
|
float transDot = pow(saturate(dot(viewDir, -H)), _Power) * thickness * _ThicknessScale;
|
|
half3 lightScattering = transDot * _SubColor;
|
|
|
|
// #endif
|
|
// Final composition
|
|
half4 c = 0;
|
|
c.rgb = diffColor * light.color * lerp(dotNL.xxx, brdf, thickness) // diffuse
|
|
+ gi.diffuse * diffColor
|
|
// #if defined (DIRECTIONAL) && defined (LUX_DIRECTIONAL_SSS) || defined (DIRECTIONAL_COOKIE) && defined (LUX_DIRECTIONAL_SSS) || defined (POINT) && defined (LUX_POINT_SSS) || defined (POINT_COOKIE) && defined (LUX_POINT_SSS) || defined (SPOT) && defined (LUX_SPOT_SSS)
|
|
+ lightScattering
|
|
// #endif // translucency
|
|
+ D * G * F * light.color * dotNL // direct specular
|
|
+ gi.specular * F_L; // * FresnelSchlickWithRoughness; // indirect specular
|
|
|
|
return c;
|
|
|
|
}
|
|
#endif
|
|
|
|
inline half4 LightingMYStandard(SurfaceOutputStandard s, float3 viewDir, UnityGI gi)
|
|
{
|
|
s.Normal = normalize(s.Normal);
|
|
|
|
half oneMinusReflectivity;
|
|
half3 specColor;
|
|
s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, /*out*/ specColor, /*out*/ oneMinusReflectivity);
|
|
|
|
// shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
|
|
// this is necessary to handle transparency in physically correct way - only diffuse component gets affected by alpha
|
|
half outputAlpha;
|
|
s.Albedo = PreMultiplyAlpha(s.Albedo, s.Alpha, oneMinusReflectivity, /*out*/ outputAlpha);
|
|
|
|
|
|
half4 c = SKIN_BRDF_PBS(s.Albedo, specColor, oneMinusReflectivity, s.Smoothness, s.Normal, viewDir, gi.light, gi.indirect, s.sssTex);
|
|
c.a = outputAlpha;
|
|
return c;
|
|
}
|
|
|
|
inline void LightingMYStandard_GI(
|
|
SurfaceOutputStandard s,
|
|
UnityGIInput data,
|
|
inout UnityGI gi)
|
|
{
|
|
#if defined(UNITY_PASS_DEFERRED) && UNITY_ENABLE_REFLECTION_BUFFERS
|
|
gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal);
|
|
#else
|
|
Unity_GlossyEnvironmentData g = UnityGlossyEnvironmentSetup(s.Smoothness, data.worldViewDir, s.Normal, lerp(unity_ColorSpaceDielectricSpec.rgb, s.Albedo, s.Metallic));
|
|
gi = UnityGlobalIllumination(data, s.Occlusion, s.Normal, g);
|
|
#endif
|
|
}
|
|
|
|
void surf(Input IN, inout SurfaceOutputStandard o)
|
|
{
|
|
// Albedo comes from a texture tinted by color
|
|
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
|
|
o.Albedo = c.rgb;
|
|
// Metallic and smoothness come from slider variables
|
|
o.Metallic = _Metallic;
|
|
o.Smoothness = _Glossiness;
|
|
o.Alpha = c.a;
|
|
half4 sssTex = tex2D(_SSSTex, TRANSFORM_TEX(IN.uv_MainTex, _SSSTex));
|
|
o.sssTex = sssTex;
|
|
}
|
|
ENDCG
|
|
}
|
|
FallBack "Diffuse"
|
|
}
|