CharaMain.cg 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  3. // Character shader
  4. // Includes falloff shadow and highlight, specular, reflection, and normal mapping
  5. #define ENABLE_CAST_SHADOWS
  6. // Material parameters
  7. float4 _Color;
  8. float4 _ShadowColor;
  9. float4 _LightColor0;
  10. float _SpecularPower;
  11. float4 _MainTex_ST;
  12. // Textures
  13. sampler2D _MainTex;
  14. sampler2D _FalloffSampler;
  15. sampler2D _RimLightSampler;
  16. sampler2D _SpecularReflectionSampler;
  17. sampler2D _EnvMapSampler;
  18. sampler2D _NormalMapSampler;
  19. // Constants
  20. #define FALLOFF_POWER 0.3
  21. #ifdef ENABLE_CAST_SHADOWS
  22. // Structure from vertex shader to fragment shader
  23. struct v2f
  24. {
  25. float4 pos : SV_POSITION;
  26. LIGHTING_COORDS( 0, 1 )
  27. float2 uv : TEXCOORD2;
  28. float3 eyeDir : TEXCOORD3;
  29. float3 lightDir : TEXCOORD4;
  30. float3 normal : TEXCOORD5;
  31. #ifdef ENABLE_NORMAL_MAP
  32. float3 tangent : TEXCOORD6;
  33. float3 binormal : TEXCOORD7;
  34. #endif
  35. };
  36. #else
  37. // Structure from vertex shader to fragment shader
  38. struct v2f
  39. {
  40. float4 pos : SV_POSITION;
  41. float2 uv : TEXCOORD0;
  42. float3 eyeDir : TEXCOORD1;
  43. float3 lightDir : TEXCOORD2;
  44. float3 normal : TEXCOORD3;
  45. #ifdef ENABLE_NORMAL_MAP
  46. float3 tangent : TEXCOORD4;
  47. float3 binormal : TEXCOORD5;
  48. #endif
  49. };
  50. #endif
  51. // Float types
  52. #define float_t half
  53. #define float2_t half2
  54. #define float3_t half3
  55. #define float4_t half4
  56. #define float3x3_t half3x3
  57. // Vertex shader
  58. v2f vert( appdata_tan v )
  59. {
  60. v2f o;
  61. o.pos = UnityObjectToClipPos( v.vertex );
  62. o.uv.xy = TRANSFORM_TEX( v.texcoord.xy, _MainTex );
  63. o.normal = normalize( mul( unity_ObjectToWorld, float4_t( v.normal, 0 ) ).xyz );
  64. // Eye direction vector
  65. half4 worldPos = mul( unity_ObjectToWorld, v.vertex );
  66. o.eyeDir.xyz = normalize( _WorldSpaceCameraPos.xyz - worldPos.xyz ).xyz;
  67. o.lightDir = WorldSpaceLightDir( v.vertex );
  68. #ifdef ENABLE_NORMAL_MAP
  69. // Binormal and tangent (for normal map)
  70. o.tangent = normalize( mul( unity_ObjectToWorld, float4_t( v.tangent.xyz, 0 ) ).xyz );
  71. o.binormal = normalize( cross( o.normal, o.tangent ) * v.tangent.w );
  72. #endif
  73. #ifdef ENABLE_CAST_SHADOWS
  74. TRANSFER_VERTEX_TO_FRAGMENT( o );
  75. #endif
  76. return o;
  77. }
  78. // Overlay blend
  79. inline float3_t GetOverlayColor( float3_t inUpper, float3_t inLower )
  80. {
  81. float3_t oneMinusLower = float3_t( 1.0, 1.0, 1.0 ) - inLower;
  82. float3_t valUnit = 2.0 * oneMinusLower;
  83. float3_t minValue = 2.0 * inLower - float3_t( 1.0, 1.0, 1.0 );
  84. float3_t greaterResult = inUpper * valUnit + minValue;
  85. float3_t lowerResult = 2.0 * inLower * inUpper;
  86. half3 lerpVals = round(inLower);
  87. return lerp(lowerResult, greaterResult, lerpVals);
  88. }
  89. #ifdef ENABLE_NORMAL_MAP
  90. // Compute normal from normal map
  91. inline float3_t GetNormalFromMap( v2f input )
  92. {
  93. float3_t normalVec = normalize( tex2D( _NormalMapSampler, input.uv ).xyz * 2.0 - 1.0 );
  94. float3x3_t localToWorldTranspose = float3x3_t(
  95. input.tangent,
  96. input.binormal,
  97. input.normal
  98. );
  99. normalVec = normalize( mul( normalVec, localToWorldTranspose ) );
  100. return normalVec;
  101. }
  102. #endif
  103. // Fragment shader
  104. float4 frag( v2f i ) : COLOR
  105. {
  106. float4_t diffSamplerColor = tex2D( _MainTex, i.uv.xy );
  107. #ifdef ENABLE_NORMAL_MAP
  108. float3_t normalVec = GetNormalFromMap( i );
  109. #else
  110. float3_t normalVec = i.normal;
  111. #endif
  112. // Falloff. Convert the angle between the normal and the camera direction into a lookup for the gradient
  113. float_t normalDotEye = dot( normalVec, i.eyeDir.xyz );
  114. float_t falloffU = clamp( 1.0 - abs( normalDotEye ), 0.02, 0.98 );
  115. float4_t falloffSamplerColor = FALLOFF_POWER * tex2D( _FalloffSampler, float2( falloffU, 0.25f ) );
  116. float3_t shadowColor = diffSamplerColor.rgb * diffSamplerColor.rgb;
  117. float3_t combinedColor = lerp( diffSamplerColor.rgb, shadowColor, falloffSamplerColor.r );
  118. combinedColor *= ( 1.0 + falloffSamplerColor.rgb * falloffSamplerColor.a );
  119. // Specular
  120. // Use the eye vector as the light vector
  121. float4_t reflectionMaskColor = tex2D( _SpecularReflectionSampler, i.uv.xy );
  122. float_t specularDot = dot( normalVec, i.eyeDir.xyz );
  123. float4_t lighting = lit( normalDotEye, specularDot, _SpecularPower );
  124. float3_t specularColor = saturate( lighting.z ) * reflectionMaskColor.rgb * diffSamplerColor.rgb;
  125. combinedColor += specularColor;
  126. // Reflection
  127. float3_t reflectVector = reflect( -i.eyeDir.xyz, normalVec ).xzy;
  128. float2_t sphereMapCoords = 0.5 * ( float2_t( 1.0, 1.0 ) + reflectVector.xy );
  129. float3_t reflectColor = tex2D( _EnvMapSampler, sphereMapCoords ).rgb;
  130. reflectColor = GetOverlayColor( reflectColor, combinedColor );
  131. combinedColor = lerp( combinedColor, reflectColor, reflectionMaskColor.a );
  132. combinedColor *= _Color.rgb * _LightColor0.rgb;
  133. float opacity = diffSamplerColor.a * _Color.a * _LightColor0.a;
  134. #ifdef ENABLE_CAST_SHADOWS
  135. // Cast shadows
  136. shadowColor = _ShadowColor.rgb * combinedColor;
  137. float_t attenuation = saturate( 2.0 * LIGHT_ATTENUATION( i ) - 1.0 );
  138. combinedColor = lerp( shadowColor, combinedColor, attenuation );
  139. #endif
  140. // Rimlight
  141. float_t rimlightDot = saturate( 0.5 * ( dot( normalVec, i.lightDir ) + 1.0 ) );
  142. falloffU = saturate( rimlightDot * falloffU );
  143. falloffU = tex2D( _RimLightSampler, float2( falloffU, 0.25f ) ).r;
  144. float3_t lightColor = diffSamplerColor.rgb; // * 2.0;
  145. combinedColor += falloffU * lightColor;
  146. return float4( combinedColor, opacity );
  147. }