HardSurfaceProScreenSpaceReflection.cginc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  3. //Hard Surface Shader Package, Written for the Unity engine by Bruno Rime: http://www.behance.net/brunorime brunorime@gmail.com
  4. #ifndef HARD_SURFACE_PRO_SCREEN_SPACE_REFELCTION_INCLUDED
  5. #define HARD_SURFACE_PRO_SCREEN_SPACE_REFELCTION_INCLUDED
  6. struct v2f
  7. {
  8. float4 pos : SV_POSITION;
  9. float3 viewDir : TEXCOORD0;
  10. float2 uv_BumpMap : TEXCOORD1;
  11. float3 TtoV0 : TEXCOORD2;
  12. float3 TtoV1 : TEXCOORD3;
  13. float4 GPscreenPos : TEXCOORD4;
  14. float3 vertworldpos : TEXCOORD5;
  15. };
  16. // define variables
  17. sampler2D _BumpMap;
  18. sampler2D _GrabTexture;
  19. sampler2D _Spec_Gloss_Reflec_Masks;
  20. float4 _BumpMap_ST;
  21. fixed _FrezPow;
  22. fixed _FrezFalloff;
  23. fixed _Metalics;
  24. fixed4 _Color;
  25. fixed _Reflection;
  26. fixed _RefScale;
  27. v2f vert (appdata_tan v)
  28. {
  29. v2f o;
  30. o.pos = UnityObjectToClipPos (v.vertex);
  31. o.vertworldpos = mul(unity_ObjectToWorld, v.vertex).xyz;
  32. //o.viewDir.xzy = ObjSpaceViewDir(v.vertex);
  33. o.uv_BumpMap = TRANSFORM_TEX( v.texcoord, _BumpMap );
  34. o.GPscreenPos.xy = (float2(o.pos.x, o.pos.y) + o.pos.w) * 0.5;
  35. o.GPscreenPos.zw = o.pos.zw;
  36. TANGENT_SPACE_ROTATION;
  37. o.viewDir.xyz = mul( rotation, ObjSpaceViewDir( v.vertex ) );
  38. o.TtoV0 = mul(rotation, UNITY_MATRIX_IT_MV[0].xyz);
  39. o.TtoV1 = mul(rotation, UNITY_MATRIX_IT_MV[1].xyz);
  40. return o;
  41. }
  42. half4 frag( v2f IN ) : COLOR
  43. {
  44. #ifdef HardsurfaceNormal
  45. fixed3 Bumpnormal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
  46. #else
  47. fixed3 Bumpnormal = fixed3(0,0,1);
  48. #endif
  49. #ifdef HardsurfaceSpecular
  50. #ifdef ShaderModel3
  51. fixed ReflecMask = tex2D(_Spec_Gloss_Reflec_Masks, IN.uv_BumpMap).g;
  52. #endif
  53. #endif
  54. //screenspaced normal direction
  55. half2 vn;
  56. vn.x = dot(IN.TtoV0, Bumpnormal);
  57. vn.y = dot(IN.TtoV1, Bumpnormal);
  58. // lays over the normal in the direction its biased to.
  59. half2 absvn = abs(vn);
  60. half maxvn = max(absvn.x,absvn.y);
  61. maxvn = 1 / maxvn;
  62. vn = vn * maxvn;
  63. #ifdef SHADER_API_D3D9
  64. vn.y *= _ProjectionParams.x;
  65. #endif
  66. // calculates VeiwAngle falloff, distance to vert, and base blend for realtime relection
  67. float3 viewVect = _WorldSpaceCameraPos - IN.vertworldpos;
  68. half dist = length (viewVect);
  69. half refscale =min (1/dist,dist/1);
  70. //half refscale =1/dist;
  71. IN.viewDir = normalize(IN.viewDir);
  72. half SurfAngle= dot(IN.viewDir,Bumpnormal);
  73. SurfAngle = pow(SurfAngle,2 * (1-refscale));
  74. // hard coded falloff for RefCapture to mask some screenspace artifacts
  75. fixed blend = 1 - saturate(SurfAngle * 1.1 );
  76. // screen space coords for capture
  77. fixed2 grabTexcoord = IN.GPscreenPos.xy / IN.GPscreenPos.w;
  78. // warps the screensapce coords by the screenspace normals, wich are tweeked by distance and viewangle
  79. fixed2 screenuv;
  80. screenuv = grabTexcoord + (vn * SurfAngle * (1-SurfAngle * refscale ));
  81. fixed2 screenedges = abs(screenuv * 2 - 1);
  82. screenedges = 1 - (screenedges * screenedges) ;
  83. // fresnal RefCapture falloff
  84. fixed frez = pow(1-SurfAngle,_FrezFalloff)*_FrezPow * 0.0009765625 ;
  85. #ifdef SHADER_API_D3D9
  86. screenuv.y = 1 - screenuv.y;
  87. #endif
  88. half3 RefCapture = tex2D(_GrabTexture,screenuv).rgb;
  89. // uses the lowest falloff value available
  90. #ifdef HardsurfaceSpecular
  91. #ifdef ShaderModel3
  92. fixed RefCaptureblend = min((_Reflection + frez),blend) * ReflecMask;
  93. #else
  94. fixed RefCaptureblend = min((_Reflection + frez),blend);
  95. #endif
  96. #else
  97. fixed RefCaptureblend = min((_Reflection + frez),blend);
  98. #endif
  99. RefCapture.rgb *= RefCaptureblend;
  100. fixed ReflectiveLum = Luminance(RefCapture);
  101. ReflectiveLum *= ReflectiveLum;
  102. // based on metalics value use a tinted or untinted RefCapture
  103. fixed3 reflectionColor = lerp ( RefCapture , RefCapture*lerp(_Color.rgb ,1,ReflectiveLum*ReflectiveLum),_Metalics);
  104. fixed reflectionOpacity = RefCaptureblend * min(screenedges.x,screenedges.y);
  105. return float4 (reflectionColor,reflectionOpacity);
  106. }
  107. #endif