Rock.shader 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Implements correct triplanar normals in a Surface Shader with out computing or passing additional information from the
  2. // vertex shader. Instead works around some oddities with how Surface Shaders handle the tangent space vectors. Attempting
  3. // to directly access the tangent matrix data results in a shader generation error. This works around the issue by tricking
  4. // the surface shader into not using those vectors until actually in the generated shader code. - Ben Golus 2017
  5. Shader "Custom/Rock" {
  6. Properties {
  7. _MainTex ("Albedo", 2D) = "white" {}
  8. [NoScaleOffset]_BumpMap("Normal", 2D) = "bump" {}
  9. [NoScaleOffset]_DetailBump("Detail Normal", 2D) = "bump" {}
  10. _DetailScale("Detail Scale", Float) = 1.0
  11. [NoScaleOffset]_OcclusionMap("Occlusion", 2D) = "white" {}
  12. _OcclusionStrength("Occlusion Strength", Range(0.0, 1.0)) = 1.0
  13. [NoScaleOffset]_MetallicRough ("Metallic/Roughness (RGBA)", 2D) = "white" {}
  14. [Gamma] _Metallic("Metallic", Range(0, 1)) = 0
  15. _Glossiness("Smoothness", Range(0, 1)) = 0.5
  16. [NoScaleOffset]_TopAlbedo ("Top Albedo", 2D) = "white" {}
  17. [NoScaleOffset]_TopNormal("Top Normal", 2D) = "bump" {}
  18. [NoScaleOffset]_TopMetallicRough ("Metallic/Roughness (RGBA)", 2D) = "white" {}
  19. [Gamma] _TopMetallic("Metallic", Range(0, 1)) = 0
  20. _TopGlossiness("Smoothness", Range(0, 1)) = 0.5
  21. [NoScaleOffset]_Noise ("Noise", 2D) = "white" {}
  22. }
  23. SubShader {
  24. Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" }
  25. LOD 200
  26. CGPROGRAM
  27. #pragma multi_compile _ LOD_FADE_CROSSFADE
  28. #pragma surface surf Standard fullforwardshadows
  29. #pragma target 5.0
  30. #include "UnityStandardUtils.cginc"
  31. #include "UnityCG.cginc"
  32. #include "AutoLight.cginc"
  33. // #define TRIPLANAR_UV_OFFSET
  34. // hack to work around the way Unity passes the tangent to world matrix to surface shaders to prevent compiler errors
  35. #if defined(INTERNAL_DATA) && (defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_META))
  36. #define WorldToTangentNormalVector(data,normal) mul(normal, half3x3(data.internalSurfaceTtoW0, data.internalSurfaceTtoW1, data.internalSurfaceTtoW2))
  37. #else
  38. #define WorldToTangentNormalVector(data,normal) normal
  39. #endif
  40. // Reoriented Normal Mapping
  41. // http://blog.selfshadow.com/publications/blending-in-detail/
  42. // Altered to take normals (-1 to 1 ranges) rather than unsigned normal maps (0 to 1 ranges)
  43. half3 blend_rnm(half3 n1, half3 n2)
  44. {
  45. n1.z += 1;
  46. n2.xy = -n2.xy;
  47. return n1 * dot(n1, n2) / n1.z - n2;
  48. }
  49. sampler2D _MainTex, _TopAlbedo, _BumpMap, _TopNormal, _Noise, _OcclusionMap, _MetallicRough, _TopMetallicRough, _DetailBump;
  50. float4 _Top_ST;
  51. float4 _UVOffset;
  52. half _Glossiness, _FresnelAmount, _FresnelPower, _TopScale, _NoiseAmount, _NoiseFallOff, _Metallic, _TopMetallic, _TopGlossiness, _OcclusionStrength, _noiseScale;
  53. half _DetailScale;
  54. struct Input {
  55. float4 screenPos;
  56. float3 worldPos;
  57. float3 viewDir;
  58. float3 worldNormal;
  59. float2 uv_MainTex;
  60. INTERNAL_DATA
  61. };
  62. void surf (Input IN, inout SurfaceOutputStandard o) {
  63. IN.worldNormal = WorldNormalVector(IN, float3(0,0,1));
  64. // top down UVs
  65. float2 uvY = IN.worldPos.xz * _TopScale;
  66. fixed4 noisetex = tex2D(_Noise, uvY * _noiseScale);
  67. half blend = clamp(0 , 1, IN.worldNormal.y);
  68. blend = smoothstep(noisetex.r, 1, blend);
  69. half noiseBlend = smoothstep(0.1, 0.2, blend);
  70. // tangent space normal map
  71. half3 tnormalY = UnpackNormal(tex2D(_TopNormal, uvY));
  72. half3 normalMain = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
  73. half3 detailNormal = UnpackNormal(tex2D(_DetailBump, IN.uv_MainTex * _DetailScale));
  74. normalMain = blend_rnm(normalMain, detailNormal);
  75. // flip normal maps' x axis to account for flipped UVs
  76. half3 absVertNormal = abs(IN.worldNormal);
  77. // swizzle world normals to match tangent space and apply reoriented normal mapping blend
  78. tnormalY = blend_rnm(half3(IN.worldNormal.xz, absVertNormal.y), tnormalY);
  79. // sizzle tangent normals to match world normal and blend together
  80. half3 worldNormal = normalize(tnormalY.xzy);
  81. // convert world space normals into tangent normals
  82. float3 tangentNormal = WorldToTangentNormalVector(IN, worldNormal);
  83. //Albedo
  84. //float fresnel = (dot(tangentNormal, IN.viewDir));
  85. //fresnel = clamp(pow(1-fresnel, _FresnelPower), 0, 6);
  86. fixed4 colY = tex2D(_TopAlbedo, uvY);
  87. fixed4 colMain = tex2D(_MainTex, IN.uv_MainTex);
  88. //Occlusion
  89. half occ = lerp(1, tex2D(_OcclusionMap, IN.uv_MainTex), _OcclusionStrength);
  90. //Metallic/Smoothness
  91. half4 metallicSmoothness = tex2D(_MetallicRough, IN.uv_MainTex);
  92. half4 TopMetallicSmoothness = tex2D(_TopMetallicRough, uvY);
  93. half m = lerp(metallicSmoothness.r * _Metallic, noisetex.r * _TopMetallic, noiseBlend);
  94. half s = lerp(metallicSmoothness.a * _Glossiness, TopMetallicSmoothness.a * _TopGlossiness, noiseBlend);
  95. #ifdef LOD_FADE_CROSSFADE
  96. float2 vpos = IN.screenPos.xy / IN.screenPos.w * _ScreenParams.xy;
  97. UnityApplyDitherCrossFade(vpos);
  98. #endif
  99. // set surface ouput properties
  100. o.Albedo = lerp(colMain, colY, noiseBlend);
  101. o.Occlusion = occ;
  102. o.Metallic = m;
  103. o.Smoothness = s;
  104. o.Normal = lerp(normalMain, tangentNormal, noiseBlend);
  105. }
  106. ENDCG
  107. }
  108. FallBack "Diffuse"
  109. }