| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- // 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/Terrain" {
- Properties {
-
-
- _WaterColor ("Water Color", Color) = (1,1,1,1)
- _WaterEdge("Water Edge Hardness", Range(0, 1)) = 0.2
- [NoScaleOffset]_WaterRoughness ("Water Roughness", 2D) = "white" {}
- _ParallaxStrength("Parallax Strength", Range(0, 0.1)) = 0.05
- //01
- [NoScaleOffset]_Albedo01 ("Albedo 01", 2D) = "white" {}
- [NoScaleOffset]_Normal01("Normal 01", 2D) = "bump" {}
- [NoScaleOffset]_MRHAO01 ("Metal/Rough/Height/AO 01", 2D) = "white" {}
- _TextureScale01("Texture Scale 01", Float) = 1.0
- _Falloff01("Blend Falloff 01", Range(0, 1)) = 0.2
- //02
- [NoScaleOffset]_Albedo02 ("Albedo 02", 2D) = "white" {}
- [NoScaleOffset]_Normal02("Normal 02", 2D) = "bump" {}
- [NoScaleOffset]_Normal02Detail("Normal 02 Detail", 2D) = "bump" {}
- [NoScaleOffset]_MRHAO02 ("Metal/Rough/Height/AO 02", 2D) = "white" {}
- _TextureScale02("Texture Scale 01", Float) = 1.0
- _Falloff02("Blend Falloff 01", Range(0, 1)) = 0.2
- //03
- [NoScaleOffset]_Albedo03 ("Albedo 03", 2D) = "white" {}
- [NoScaleOffset]_Normal03("Normal 03", 2D) = "bump" {}
- [NoScaleOffset]_MRHAO03 ("Metal/Rough/Height/AO 03", 2D) = "white" {}
- _TextureScale03("Texture Scale 01", Float) = 1.0
- _Falloff03("Blend Falloff 01", Range(0, 1)) = 0.2
- //04
- //[NoScaleOffset]_Albedo04 ("Albedo 04", 2D) = "white" {}
- //[NoScaleOffset]_Normal04("Normal 04", 2D) = "bump" {}
- //[NoScaleOffset]_MRHAO04 ("Metal/Rough/Height/AO 04", 2D) = "white" {}
- //_TextureScale04("Texture Scale 01", Float) = 1.0
- //_Falloff04("Blend Falloff 01", Range(0, 1)) = 0.2
- }
- SubShader {
- Tags { "RenderType"="Opaque" }
- LOD 200
-
- CGPROGRAM
- #pragma surface surf Standard fullforwardshadows vertex:vert addshadow
- #pragma target 5.0
- #include "UnityStandardUtils.cginc"
- #include "UnityCG.cginc"
- #include "AutoLight.cginc"
- #include "Tessellation.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 _Albedo01, _Normal01, _MRHAO01;
- sampler2D _Albedo02, _Normal02, _MRHAO02;
- sampler2D _Albedo03, _Normal03, _MRHAO03;
- sampler2D _Normal02Detail;
- sampler2D _WaterRoughness;
- half _WaterEdge, _ParallaxStrength;
- half _Falloff01, _Falloff02, _Falloff03, _Falloff04;
- half _TextureScale01, _TextureScale02, _TextureScale03;
- half4 _WaterColor;
- struct vertdata {
- float4 vertex : POSITION;
- float4 tangent : TANGENT;
- float3 normal : NORMAL;
- float4 texcoord : TEXCOORD0;
- float4 texcoord1 : TEXCOORD1;
- float4 texcoord2 : TEXCOORD2;
- fixed4 color : COLOR;
- float3 tangentViewDir : TEXCOORD3;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct Input {
- float3 worldPos;
- float3 viewDir;
- float3 worldNormal;
- float2 uv_MainTex;
- float4 color : COLOR;
- float3 tangentViewDir : TEXCOORD3;
- INTERNAL_DATA
- };
- void vert (inout vertdata v, out Input o) {
- UNITY_INITIALIZE_OUTPUT(Input,o);
- float3 worldPos = mul (unity_ObjectToWorld, v.vertex).xyz;
- float3x3 objectToTangent = float3x3(v.tangent.xyz,cross(v.normal, v.tangent.xyz) * v.tangent.w,v.normal);
- v.tangentViewDir = mul(objectToTangent, ObjSpaceViewDir(v.vertex));
- o.tangentViewDir = normalize(v.tangentViewDir);
- o.tangentViewDir.xy /= o.tangentViewDir.z;
- }
-
- void surf (Input IN, inout SurfaceOutputStandard o) {
- IN.worldNormal = WorldNormalVector(IN, float3(0,0,1));
- // top down UVs
- float2 UVY = IN.worldPos.xz;
- fixed4 vertCol = IN.color;
- //Albedo
- fixed4 Albedo01 = tex2D(_Albedo01, UVY * _TextureScale01);
- fixed4 Albedo02 = tex2D(_Albedo02, UVY * _TextureScale02);
- fixed4 Albedo03 = tex2D(_Albedo03, UVY * _TextureScale03);
- //fixed4 Albedo04 = tex2D(_Albedo04, UVY * _TextureScale04);
-
- half blend01 = smoothstep(vertCol.r, vertCol.r-_Falloff01, 1-Albedo01.a);
- half blend02 = smoothstep(vertCol.g, vertCol.g-_Falloff02, 1-Albedo03.a);
- float2 UVY2 = IN.worldPos.xz;
- UVY2 += IN.tangentViewDir * _ParallaxStrength * blend01;
- Albedo02 = tex2D(_Albedo02, UVY2 * _TextureScale02);
- Albedo03 = tex2D(_Albedo03, UVY * _TextureScale03);
-
- fixed4 AlbedoFinal = Albedo01;
- AlbedoFinal = lerp(AlbedoFinal, Albedo02, blend01);
- AlbedoFinal = lerp(AlbedoFinal, Albedo01, blend02);
- //AlbedoFinal = lerp(AlbedoFinal, Albedo04, blend03);
- // tangent space normal map
- half3 Normal01 = UnpackNormal(tex2D(_Normal01, UVY * _TextureScale01));
- half3 Normal02 = UnpackNormal(tex2D(_Normal02, UVY2 * _TextureScale02));
- half3 Normal03 = UnpackNormal(tex2D(_Normal03, UVY * _TextureScale03));
- //half3 Normal04 = UnpackNormal(tex2D(_Normal04, UVY * _TextureScale04));
- half3 Normal02Detail = UnpackNormal(tex2D(_Normal02Detail, UVY*0.1));
- // 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
- half3 tangentNormal = lerp(Normal01,Normal02, blend01);
- tangentNormal = lerp(tangentNormal, Normal03, blend02);
- //tangentNormal = lerp(tangentNormal, Normal04, blend03);
- tangentNormal = blend_rnm(half3(IN.worldNormal.xz, absVertNormal.y), tangentNormal);
- // sizzle tangent normals to match world normal and blend together
- half3 worldNormal = normalize(tangentNormal.xzy);
- // convert world space normals into tangent normals
- float3 NormalFinal = WorldToTangentNormalVector(IN, worldNormal);
- //Roughness
- half Roughness01 = tex2D(_MRHAO01, UVY * _TextureScale01).a;
- half Roughness02 = tex2D(_MRHAO02, UVY2 * _TextureScale02).a;
- half Roughness03 = tex2D(_MRHAO03, UVY * _TextureScale03).a;
- //half Roughness04 = tex2D(_MRHAO04, UVY * _TextureScale04).a;
- fixed4 RoughnessFinal = lerp(0.3, Roughness02, blend01);
- RoughnessFinal = lerp(RoughnessFinal, Roughness03, blend02);
- //RoughnessFinal = lerp(RoughnessFinal, Roughness04, blend03);
-
- /*
- //waterLevel
- half blendY = 1-smoothstep(0.96, 1, absVertNormal.y);
- half waterLevel = smoothstep(IN.color.r, IN.color.r - 0.3, clamp(0, 1, colY.a + blendY));
- half waterLevel2 = smoothstep(0, 0.1, waterLevel);
- //half waterLevel = blendY;
- */
-
- //water
- float blend = 1-Albedo01.a;
- half3 upNormal = WorldToTangentNormalVector(IN, float3(0,1,0));
- AlbedoFinal = lerp(AlbedoFinal*_WaterColor, AlbedoFinal, smoothstep(IN.color.a+_WaterEdge, IN.color.a+1, blend));
- NormalFinal = lerp(upNormal, NormalFinal, smoothstep(IN.color.a+_WaterEdge, IN.color.a, blend));
- RoughnessFinal = lerp( tex2D(_WaterRoughness, UVY * 0.3).a * 0.95, RoughnessFinal, smoothstep(IN.color.a+_WaterEdge, IN.color.a, blend));
-
- // set surface ouput properties
- o.Albedo = AlbedoFinal;
- //o.Occlusion = occ;
- o.Metallic = 0;
- o.Smoothness = RoughnessFinal;
- o.Normal = NormalFinal;
-
- }
- ENDCG
- }
- FallBack "Diffuse"
- }
|