// *********************************************************************** // Author : Kimch // Created : 2018-7-1 // Description : 角色Shader // Last Modified By : Kimch // Last Modified On : 2019-7-1 // *********************************************************************** // // *********************************************************************** Shader "MY/Skin(SSS)" { Properties { _Color("Main Color", Color) = (1,1,1,1) _MainTex("Albedo", 2D) = "white" {} [Toggle]NORMAL("法线开关",Float) = 0 _BumpMap("Normalmap", 2D) = "bump" {} [Toggle]Spec("Specular Mode",Float) = 1 _Glossiness("Smoothness", Range(0.0, 5.0)) = 0.5 [Toggle]SSS("SSS 开关",Float) = 0 _BRDFTex("BRDF Lookup (RGB)", 2D) = "white" {} _SubColor("Subsurface Color", Color) = (1, .4, .25, 1) _SubFactor("Subsurface Factor",Range(0,5)) = 1 [KeywordEnum(Const,Calc,Tex)] Curve("Curve Mode",Float) = 1 _CurveTex("CurveTex", 2D) = "white" {} _CurveFactor("CurveFactor",Range(0,5)) = 1 //[KeywordEnum(None, Curve, Specular)] Debug("Debug Mode", Float) = 0 } SubShader { Tags{"RenderType" = "Opaque"} Pass { Tags { "LightMode" = "ForwardBase"} CGPROGRAM #pragma target 3.0 #pragma vertex myvert #pragma fragment myfrag #pragma multi_compile_fwdbase #pragma shader_feature NORMAL_ON #pragma shader_feature SSS_ON #pragma shader_feature SPEC_ON #pragma shader_feature CURVE_CONST CURVE_CALC CURVE_TEX //#pragma multi_compile DEBUG_NONE DEBUG_CURVE DEBUG_SPECULAR #include "UnityCG.cginc" #include "AutoLight.cginc" sampler2D _MainTex; fixed4 _MainTex_ST; fixed4 _Color; sampler2D _BumpMap; fixed4 _BumpMap_ST; fixed _Glossiness; sampler2D _CurveTex; fixed _CurveFactor; sampler2D _BRDFTex; fixed _SubFactor; fixed3 _SubColor; fixed4 _LightColor0; struct v2f_my { float4 pos : SV_POSITION; float4 uv : TEXCOORD0; float4 T2W0 :TEXCOORD1; float4 T2W1 :TEXCOORD2; float4 T2W2 :TEXCOORD3; LIGHTING_COORDS(4, 5) }; v2f_my myvert(appdata_full v) { v2f_my o; o.pos = UnityObjectToClipPos(v.vertex); o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex); o.uv.zw = TRANSFORM_TEX(v.texcoord,_BumpMap); float3 worldPos = mul(unity_ObjectToWorld,v.vertex); float3 worldNormal = UnityObjectToWorldNormal(v.normal); float3 worldTangent = UnityObjectToWorldDir(v.tangent); float3 worldBitangent = cross(worldNormal ,worldTangent) * v.tangent.w; o.T2W0 = float4 (worldTangent.x,worldBitangent.x,worldNormal.x,worldPos.x); o.T2W1 = float4 (worldTangent.y,worldBitangent.y,worldNormal.y,worldPos.y); o.T2W2 = float4 (worldTangent.z,worldBitangent.z,worldNormal.z,worldPos.z); TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } // inline float fresnelReflectance( float3 H, float3 V, float F0 ) // { // float base = 1.0 - dot( V, H ); // float exponential = pow( base, 5.0 ); // return exponential + F0 * ( 1.0 - exponential ); // } half4 myfrag(v2f_my i) : SV_Target { float3 albedo = tex2D(_MainTex,i.uv.xy).rgb * _Color; fixed4 ambient = UNITY_LIGHTMODEL_AMBIENT;//环境光 fixed attenuation = LIGHT_ATTENUATION(i);//投影 float3 worldPos = float3(i.T2W0.w,i.T2W1.w,i.T2W2.w); fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos)); fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos)); #if defined(NORMAL_ON) fixed4 tangentNormal = tex2D(_BumpMap,i.uv.zw); fixed3 bump = UnpackNormal(tangentNormal); fixed3 worldBump = normalize(half3(dot(i.T2W0.zzz,bump), dot(i.T2W1.zzz,bump), dot(i.T2W2.zzz,bump))); #else fixed3 worldBump = normalize(half3(i.T2W0.z, i.T2W1.z, i.T2W2.z)); #endif #if defined(CURVE_CONST) fixed curvature = _CurveFactor; #elif defined(CURVE_TEX) fixed curvature = tex2D(_CurveTex,i.uv.zw); #else fixed3 worldShapeBump = normalize(float3(i.T2W0.z,i.T2W1.z,i.T2W2.z)); fixed curvature = saturate(_CurveFactor * 0.01 * (length(fwidth(worldShapeBump)) / length(fwidth(worldPos)))); #endif fixed dotNL = dot(worldBump,lightDir); half3 H = normalize(lightDir + viewDir); fixed dotNH = dot(worldBump, H); #if defined(SPEC_ON) fixed3 specular = pow(max(0, dotNH), 10.0) * _Glossiness; #else fixed3 specular = 0; #endif #if defined(SSS_ON) // 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(_LightColor0.rgb, fixed3(0.22, 0.707, 0.071)); fixed3 diffuse = tex2D(_BRDFTex, brdfUV) + (dotNH * _SubFactor)*_SubColor.rgb; #else fixed3 diffuse = max(0, dotNL); #endif fixed3 finalColor = (ambient + (diffuse + specular) * _LightColor0.rgb * attenuation) * albedo; #if defined(DEBUG_CURVE) return fixed4(curvature, curvature, curvature,1); #elif defined (DEBUG_SPECULAR) return fixed4(specular,1); #else return fixed4(finalColor,1); #endif } ENDCG } } FallBack "Diffuse" }