| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- // Implements correct triplanar normals in a Surface Shader with out computing or passing additional information from the
- // vertex shader. Instead works around some oddities with how Surface Shaders handle the tangent space vectors. Attempting
- // to directly access the tangent matrix data results in a shader generation error. This works around the issue by tricking
- // the surface shader into not using those vectors until actually in the generated shader code. - Ben Golus 2017
- Shader "Custom/Rock" {
- Properties {
- _MainTex ("Albedo", 2D) = "white" {}
- [NoScaleOffset]_BumpMap("Normal", 2D) = "bump" {}
- [NoScaleOffset]_DetailBump("Detail Normal", 2D) = "bump" {}
- _DetailScale("Detail Scale", Float) = 1.0
- [NoScaleOffset]_OcclusionMap("Occlusion", 2D) = "white" {}
- _OcclusionStrength("Occlusion Strength", Range(0.0, 1.0)) = 1.0
- [NoScaleOffset]_MetallicRough ("Metallic/Roughness (RGBA)", 2D) = "white" {}
- [Gamma] _Metallic("Metallic", Range(0, 1)) = 0
- _Glossiness("Smoothness", Range(0, 1)) = 0.5
- [NoScaleOffset]_TopAlbedo ("Top Albedo", 2D) = "white" {}
- [NoScaleOffset]_TopNormal("Top Normal", 2D) = "bump" {}
- [NoScaleOffset]_TopMetallicRough ("Metallic/Roughness (RGBA)", 2D) = "white" {}
- [Gamma] _TopMetallic("Metallic", Range(0, 1)) = 0
- _TopGlossiness("Smoothness", Range(0, 1)) = 0.5
- [NoScaleOffset]_Noise ("Noise", 2D) = "white" {}
- }
- SubShader {
- Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" }
- LOD 200
-
- CGPROGRAM
- #pragma multi_compile _ LOD_FADE_CROSSFADE
- #pragma surface surf Standard fullforwardshadows
- #pragma target 5.0
- #include "UnityStandardUtils.cginc"
- #include "UnityCG.cginc"
- #include "AutoLight.cginc"
-
- // #define TRIPLANAR_UV_OFFSET
- // hack to work around the way Unity passes the tangent to world matrix to surface shaders to prevent compiler errors
- #if defined(INTERNAL_DATA) && (defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_FORWARDADD) || defined(UNITY_PASS_DEFERRED) || defined(UNITY_PASS_META))
- #define WorldToTangentNormalVector(data,normal) mul(normal, half3x3(data.internalSurfaceTtoW0, data.internalSurfaceTtoW1, data.internalSurfaceTtoW2))
- #else
- #define WorldToTangentNormalVector(data,normal) normal
- #endif
- // Reoriented Normal Mapping
- // http://blog.selfshadow.com/publications/blending-in-detail/
- // Altered to take normals (-1 to 1 ranges) rather than unsigned normal maps (0 to 1 ranges)
- half3 blend_rnm(half3 n1, half3 n2)
- {
- n1.z += 1;
- n2.xy = -n2.xy;
- return n1 * dot(n1, n2) / n1.z - n2;
- }
- sampler2D _MainTex, _TopAlbedo, _BumpMap, _TopNormal, _Noise, _OcclusionMap, _MetallicRough, _TopMetallicRough, _DetailBump;
- float4 _Top_ST;
- float4 _UVOffset;
- half _Glossiness, _FresnelAmount, _FresnelPower, _TopScale, _NoiseAmount, _NoiseFallOff, _Metallic, _TopMetallic, _TopGlossiness, _OcclusionStrength, _noiseScale;
- half _DetailScale;
- struct Input {
- float4 screenPos;
- float3 worldPos;
- float3 viewDir;
- float3 worldNormal;
- float2 uv_MainTex;
- INTERNAL_DATA
- };
-
- void surf (Input IN, inout SurfaceOutputStandard o) {
- IN.worldNormal = WorldNormalVector(IN, float3(0,0,1));
- // top down UVs
- float2 uvY = IN.worldPos.xz * _TopScale;
- fixed4 noisetex = tex2D(_Noise, uvY * _noiseScale);
- half blend = clamp(0 , 1, IN.worldNormal.y);
- blend = smoothstep(noisetex.r, 1, blend);
- half noiseBlend = smoothstep(0.1, 0.2, blend);
- // tangent space normal map
- half3 tnormalY = UnpackNormal(tex2D(_TopNormal, uvY));
- half3 normalMain = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
- half3 detailNormal = UnpackNormal(tex2D(_DetailBump, IN.uv_MainTex * _DetailScale));
- normalMain = blend_rnm(normalMain, detailNormal);
- // flip normal maps' x axis to account for flipped UVs
- half3 absVertNormal = abs(IN.worldNormal);
- // swizzle world normals to match tangent space and apply reoriented normal mapping blend
- tnormalY = blend_rnm(half3(IN.worldNormal.xz, absVertNormal.y), tnormalY);
- // sizzle tangent normals to match world normal and blend together
- half3 worldNormal = normalize(tnormalY.xzy);
- // convert world space normals into tangent normals
- float3 tangentNormal = WorldToTangentNormalVector(IN, worldNormal);
- //Albedo
- //float fresnel = (dot(tangentNormal, IN.viewDir));
- //fresnel = clamp(pow(1-fresnel, _FresnelPower), 0, 6);
- fixed4 colY = tex2D(_TopAlbedo, uvY);
- fixed4 colMain = tex2D(_MainTex, IN.uv_MainTex);
- //Occlusion
- half occ = lerp(1, tex2D(_OcclusionMap, IN.uv_MainTex), _OcclusionStrength);
- //Metallic/Smoothness
- half4 metallicSmoothness = tex2D(_MetallicRough, IN.uv_MainTex);
- half4 TopMetallicSmoothness = tex2D(_TopMetallicRough, uvY);
- half m = lerp(metallicSmoothness.r * _Metallic, noisetex.r * _TopMetallic, noiseBlend);
- half s = lerp(metallicSmoothness.a * _Glossiness, TopMetallicSmoothness.a * _TopGlossiness, noiseBlend);
- #ifdef LOD_FADE_CROSSFADE
- float2 vpos = IN.screenPos.xy / IN.screenPos.w * _ScreenParams.xy;
- UnityApplyDitherCrossFade(vpos);
- #endif
- // set surface ouput properties
- o.Albedo = lerp(colMain, colY, noiseBlend);
- o.Occlusion = occ;
- o.Metallic = m;
- o.Smoothness = s;
- o.Normal = lerp(normalMain, tangentNormal, noiseBlend);
-
- }
- ENDCG
- }
- FallBack "Diffuse"
- }
|