Advertisement
SarahNorthway

TerrainTriplanar

Feb 24th, 2021
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.11 KB | None | 0 0
  1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  2.  
  3. Shader "Northway/TerrainTriplanar" {
  4. Properties {
  5. // sarah added (set by terrain engine)
  6. _WorldS ("World Scale", Vector) = (0.002,0.002,0.002,0)
  7. _WorldT ("World Translate", Vector) = (0,0,0,0)
  8. [HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
  9. [HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
  10. [HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
  11. [HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
  12. [HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
  13. [HideInInspector] _Normal3 ("Normal 3 (A)", 2D) = "bump" {}
  14. [HideInInspector] _Normal2 ("Normal 2 (B)", 2D) = "bump" {}
  15. [HideInInspector] _Normal1 ("Normal 1 (G)", 2D) = "bump" {}
  16. [HideInInspector] _Normal0 ("Normal 0 (R)", 2D) = "bump" {}
  17.  
  18. // used in fallback on old cards & base map
  19. [HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
  20. [HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
  21. [HideInInspector] _TerrainHolesTexture("Holes Map (RGB)", 2D) = "white" {}
  22. }
  23.  
  24. CGINCLUDE
  25. // terrains have no shadows, but addshadow required or particles will flash when postprocess enabled in pollen
  26. #pragma surface surf SimpleLambert vertex:SplatmapVert finalcolor:SplatmapFinalColor finalprepass:SplatmapFinalPrepass finalgbuffer:SplatmapFinalGBuffer addshadow
  27. #pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap forwardadd
  28. #pragma multi_compile_fog
  29.  
  30. //#include "TerrainSplatmapCommon.cginc"
  31.  
  32. float4 _WorldS, _WorldT;
  33.  
  34. // runs for every (nearby?) light on the scene
  35. half4 LightingSimpleLambert(SurfaceOutput s, half3 lightDir, half atten) {
  36. half4 color;
  37. // terrain needs extra light
  38. color.rgb = s.Albedo * _LightColor0.rgb * atten * 2;
  39. color.a = s.Alpha;
  40. return color;
  41. }
  42.  
  43. inline half4 Triplanar(float3 worldPos, float3 normal, float4 st, sampler2D splat) {
  44. return normal.x * tex2D(splat, st.xy * worldPos.zy + st.zw) +
  45. normal.y * tex2D(splat, st.xy * worldPos.xz + st.zw) +
  46. normal.z * tex2D(splat, st.xy * worldPos.xy + st.zw);
  47. }
  48.  
  49.  
  50.  
  51.  
  52.  
  53. // ================ begin sarah-modified TerrainSplatmapCommon.cginc
  54.  
  55. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
  56.  
  57. #ifndef TERRAIN_SPLATMAP_COMMON_CGINC_INCLUDED
  58. #define TERRAIN_SPLATMAP_COMMON_CGINC_INCLUDED
  59.  
  60. // Since 2018.3 we changed from _TERRAIN_NORMAL_MAP to _NORMALMAP to save 1 keyword.
  61. // Since 2019.2 terrain keywords are changed to local keywords so it doesn't really matter. You can use both.
  62. #if defined(_NORMALMAP) && !defined(_TERRAIN_NORMAL_MAP)
  63. #define _TERRAIN_NORMAL_MAP
  64. #elif !defined(_NORMALMAP) && defined(_TERRAIN_NORMAL_MAP)
  65. #define _NORMALMAP
  66. #endif
  67.  
  68. struct Input
  69. {
  70. float4 tc;
  71. #ifndef TERRAIN_BASE_PASS
  72. UNITY_FOG_COORDS(0) // needed because finalcolor oppresses fog code generation.
  73. #endif
  74.  
  75. // sarah added - worldPos set automagically
  76. float3 worldPos;
  77. };
  78.  
  79. sampler2D _Control;
  80. float4 _Control_ST;
  81. float4 _Control_TexelSize;
  82. sampler2D _Splat0, _Splat1, _Splat2, _Splat3;
  83. float4 _Splat0_ST, _Splat1_ST, _Splat2_ST, _Splat3_ST;
  84.  
  85. #if defined(UNITY_INSTANCING_ENABLED) && !defined(SHADER_API_D3D11_9X)
  86. sampler2D _TerrainHeightmapTexture;
  87. sampler2D _TerrainNormalmapTexture;
  88. float4 _TerrainHeightmapRecipSize; // float4(1.0f/width, 1.0f/height, 1.0f/(width-1), 1.0f/(height-1))
  89. float4 _TerrainHeightmapScale; // float4(hmScale.x, hmScale.y / (float)(kMaxHeight), hmScale.z, 0.0f)
  90. #endif
  91.  
  92. UNITY_INSTANCING_BUFFER_START(Terrain)
  93. UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) // float4(xBase, yBase, skipScale, ~)
  94. UNITY_INSTANCING_BUFFER_END(Terrain)
  95.  
  96. #ifdef _NORMALMAP
  97. sampler2D _Normal0, _Normal1, _Normal2, _Normal3;
  98. float _NormalScale0, _NormalScale1, _NormalScale2, _NormalScale3;
  99. #endif
  100.  
  101. #ifdef _ALPHATEST_ON
  102. sampler2D _TerrainHolesTexture;
  103.  
  104. void ClipHoles(float2 uv)
  105. {
  106. float hole = tex2D(_TerrainHolesTexture, uv).r;
  107. clip(hole == 0.0f ? -1 : 1);
  108. }
  109. #endif
  110.  
  111. #if defined(TERRAIN_BASE_PASS) && defined(UNITY_PASS_META)
  112. // When we render albedo for GI baking, we actually need to take the ST
  113. float4 _MainTex_ST;
  114. #endif
  115.  
  116. void SplatmapVert(inout appdata_full v, out Input data)
  117. {
  118. UNITY_INITIALIZE_OUTPUT(Input, data);
  119.  
  120. #if defined(UNITY_INSTANCING_ENABLED) && !defined(SHADER_API_D3D11_9X)
  121.  
  122. float2 patchVertex = v.vertex.xy;
  123. float4 instanceData = UNITY_ACCESS_INSTANCED_PROP(Terrain, _TerrainPatchInstanceData);
  124.  
  125. float4 uvscale = instanceData.z * _TerrainHeightmapRecipSize;
  126. float4 uvoffset = instanceData.xyxy * uvscale;
  127. uvoffset.xy += 0.5f * _TerrainHeightmapRecipSize.xy;
  128. float2 sampleCoords = (patchVertex.xy * uvscale.xy + uvoffset.xy);
  129.  
  130. float hm = UnpackHeightmap(tex2Dlod(_TerrainHeightmapTexture, float4(sampleCoords, 0, 0)));
  131. v.vertex.xz = (patchVertex.xy + instanceData.xy) * _TerrainHeightmapScale.xz * instanceData.z; //(x + xBase) * hmScale.x * skipScale;
  132. v.vertex.y = hm * _TerrainHeightmapScale.y;
  133. v.vertex.w = 1.0f;
  134.  
  135. v.texcoord.xy = (patchVertex.xy * uvscale.zw + uvoffset.zw);
  136. v.texcoord3 = v.texcoord2 = v.texcoord1 = v.texcoord;
  137.  
  138. #ifdef TERRAIN_INSTANCED_PERPIXEL_NORMAL
  139. v.normal = float3(0, 1, 0); // TODO: reconstruct the tangent space in the pixel shader. Seems to be hard with surface shader especially when other attributes are packed together with tSpace.
  140. data.tc.zw = sampleCoords;
  141. #else
  142. float3 nor = tex2Dlod(_TerrainNormalmapTexture, float4(sampleCoords, 0, 0)).xyz;
  143. v.normal = 2.0f * nor - 1.0f;
  144. #endif
  145. #endif
  146.  
  147. v.tangent.xyz = cross(v.normal, float3(0,0,1));
  148. v.tangent.w = -1;
  149.  
  150. data.tc.xy = v.texcoord.xy;
  151. #ifdef TERRAIN_BASE_PASS
  152. #ifdef UNITY_PASS_META
  153. data.tc.xy = TRANSFORM_TEX(v.texcoord.xy, _MainTex);
  154. #endif
  155. #else
  156. float4 pos = UnityObjectToClipPos(v.vertex);
  157. UNITY_TRANSFER_FOG(data, pos);
  158. #endif
  159. }
  160.  
  161. #ifndef TERRAIN_BASE_PASS
  162.  
  163. #ifdef TERRAIN_STANDARD_SHADER
  164. void SplatmapMix(Input IN, half4 defaultAlpha, out half4 splat_control, out half weight, out fixed4 mixedDiffuse, inout fixed3 mixedNormal)
  165. #else
  166. void SplatmapMix(Input IN, out half4 splat_control, out half weight, out fixed4 mixedDiffuse, inout fixed3 mixedNormal)
  167. #endif
  168. {
  169. #ifdef _ALPHATEST_ON
  170. ClipHoles(IN.tc.xy);
  171. #endif
  172.  
  173. // adjust splatUVs so the edges of the terrain tile lie on pixel centers
  174. float2 splatUV = (IN.tc.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
  175. splat_control = tex2D(_Control, splatUV);
  176. weight = dot(splat_control, half4(1,1,1,1));
  177.  
  178. #if !defined(SHADER_API_MOBILE) && defined(TERRAIN_SPLAT_ADDPASS)
  179. clip(weight == 0.0f ? -1 : 1);
  180. #endif
  181.  
  182. // Normalize weights before lighting and restore weights in final modifier functions so that the overal
  183. // lighting result can be correctly weighted.
  184. splat_control /= (weight + 1e-3f);
  185.  
  186. // sarah added
  187. float3 worldPos = IN.worldPos * _WorldS.xyz + _WorldT.xyz;
  188. float3 normal = abs(mixedNormal);
  189. normal = pow(normal, 20); // for crisp edges
  190. // 1e-5f is not enough and causes black spots; even 1e-7f causes black spots at extremes but without it divide by 0
  191. normal /= (normal.x + normal.y + normal.z + 1e-7f);
  192. mixedDiffuse = half4(0, 0, 0, 0);
  193. mixedDiffuse += splat_control.r * Triplanar(worldPos, normal, _Splat0_ST, _Splat0);
  194. mixedDiffuse += splat_control.g * Triplanar(worldPos, normal, _Splat1_ST, _Splat1);
  195. mixedDiffuse += splat_control.b * Triplanar(worldPos, normal, _Splat2_ST, _Splat2);
  196. mixedDiffuse += splat_control.a * Triplanar(worldPos, normal, _Splat3_ST, _Splat3);
  197.  
  198. // sarah removed
  199. // float2 uvSplat0 = TRANSFORM_TEX(IN.tc.xy, _Splat0);
  200. // float2 uvSplat1 = TRANSFORM_TEX(IN.tc.xy, _Splat1);
  201. // float2 uvSplat2 = TRANSFORM_TEX(IN.tc.xy, _Splat2);
  202. // float2 uvSplat3 = TRANSFORM_TEX(IN.tc.xy, _Splat3);
  203. //
  204. // mixedDiffuse = 0.0f;
  205. // #ifdef TERRAIN_STANDARD_SHADER
  206. // mixedDiffuse += splat_control.r * tex2D(_Splat0, uvSplat0) * half4(1.0, 1.0, 1.0, defaultAlpha.r);
  207. // mixedDiffuse += splat_control.g * tex2D(_Splat1, uvSplat1) * half4(1.0, 1.0, 1.0, defaultAlpha.g);
  208. // mixedDiffuse += splat_control.b * tex2D(_Splat2, uvSplat2) * half4(1.0, 1.0, 1.0, defaultAlpha.b);
  209. // mixedDiffuse += splat_control.a * tex2D(_Splat3, uvSplat3) * half4(1.0, 1.0, 1.0, defaultAlpha.a);
  210. // #else
  211. // mixedDiffuse += splat_control.r * tex2D(_Splat0, uvSplat0);
  212. // mixedDiffuse += splat_control.g * tex2D(_Splat1, uvSplat1);
  213. // mixedDiffuse += splat_control.b * tex2D(_Splat2, uvSplat2);
  214. // mixedDiffuse += splat_control.a * tex2D(_Splat3, uvSplat3);
  215. // #endif
  216. //
  217. // #ifdef _NORMALMAP
  218. // mixedNormal = UnpackNormalWithScale(tex2D(_Normal0, uvSplat0), _NormalScale0) * splat_control.r;
  219. // mixedNormal += UnpackNormalWithScale(tex2D(_Normal1, uvSplat1), _NormalScale1) * splat_control.g;
  220. // mixedNormal += UnpackNormalWithScale(tex2D(_Normal2, uvSplat2), _NormalScale2) * splat_control.b;
  221. // mixedNormal += UnpackNormalWithScale(tex2D(_Normal3, uvSplat3), _NormalScale3) * splat_control.a;
  222. // mixedNormal.z += 1e-5f; // to avoid nan after normalizing
  223. // #endif
  224.  
  225.  
  226. #if defined(INSTANCING_ON) && defined(SHADER_TARGET_SURFACE_ANALYSIS) && defined(TERRAIN_INSTANCED_PERPIXEL_NORMAL)
  227. mixedNormal = float3(0, 0, 1); // make sure that surface shader compiler realizes we write to normal, as UNITY_INSTANCING_ENABLED is not defined for SHADER_TARGET_SURFACE_ANALYSIS.
  228. #endif
  229.  
  230. #if defined(UNITY_INSTANCING_ENABLED) && !defined(SHADER_API_D3D11_9X) && defined(TERRAIN_INSTANCED_PERPIXEL_NORMAL)
  231. float3 geomNormal = normalize(tex2D(_TerrainNormalmapTexture, IN.tc.zw).xyz * 2 - 1);
  232. #ifdef _NORMALMAP
  233. float3 geomTangent = normalize(cross(geomNormal, float3(0, 0, 1)));
  234. float3 geomBitangent = normalize(cross(geomTangent, geomNormal));
  235. mixedNormal = mixedNormal.x * geomTangent
  236. + mixedNormal.y * geomBitangent
  237. + mixedNormal.z * geomNormal;
  238. #else
  239. mixedNormal = geomNormal;
  240. #endif
  241. mixedNormal = mixedNormal.xzy;
  242. #endif
  243. }
  244.  
  245. #ifndef TERRAIN_SURFACE_OUTPUT
  246. #define TERRAIN_SURFACE_OUTPUT SurfaceOutput
  247. #endif
  248.  
  249. void SplatmapFinalColor(Input IN, TERRAIN_SURFACE_OUTPUT o, inout fixed4 color)
  250. {
  251. color *= o.Alpha;
  252. #ifdef TERRAIN_SPLAT_ADDPASS
  253. UNITY_APPLY_FOG_COLOR(IN.fogCoord, color, fixed4(0,0,0,0));
  254. #else
  255. UNITY_APPLY_FOG(IN.fogCoord, color);
  256. #endif
  257. }
  258.  
  259. void SplatmapFinalPrepass(Input IN, TERRAIN_SURFACE_OUTPUT o, inout fixed4 normalSpec)
  260. {
  261. normalSpec *= o.Alpha;
  262. }
  263.  
  264. void SplatmapFinalGBuffer(Input IN, TERRAIN_SURFACE_OUTPUT o, inout half4 outGBuffer0, inout half4 outGBuffer1, inout half4 outGBuffer2, inout half4 emission)
  265. {
  266. UnityStandardDataApplyWeightToGbuffer(outGBuffer0, outGBuffer1, outGBuffer2, o.Alpha);
  267. emission *= o.Alpha;
  268. }
  269.  
  270. #endif // TERRAIN_BASE_PASS
  271.  
  272. #endif // TERRAIN_SPLATMAP_COMMON_CGINC_INCLUDED
  273.  
  274. // ================ end sarah-modified TerrainSplatmapCommon.cginc
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283. void surf (Input IN, inout SurfaceOutput o) {
  284. half4 splat_control;
  285. half weight;
  286. half4 mixedDiffuse;
  287. SplatmapMix(IN, splat_control, weight, mixedDiffuse, o.Normal);
  288. o.Albedo = mixedDiffuse.rgb;
  289. o.Alpha = weight;
  290. }
  291.  
  292. ENDCG
  293.  
  294. Category {
  295. Tags {
  296. "Queue" = "Geometry-99"
  297. "RenderType" = "Opaque"
  298. }
  299. // TODO: Seems like "#pragma target 3.0 _NORMALMAP" can't fallback correctly on less capable devices?
  300. // Use two sub-shaders to simulate different features for different targets and still fallback correctly.
  301. SubShader { // for sm3.0+ targets
  302. CGPROGRAM
  303. #pragma target 3.0
  304. #pragma multi_compile_local __ _ALPHATEST_ON
  305. #pragma multi_compile_local __ _NORMALMAP
  306. ENDCG
  307.  
  308. UsePass "Hidden/Nature/Terrain/Utilities/PICKING"
  309. UsePass "Hidden/Nature/Terrain/Utilities/SELECTION"
  310. }
  311. SubShader { // for sm2.0 targets
  312. CGPROGRAM
  313. ENDCG
  314. }
  315. }
  316.  
  317. // sarah could remove these but doesn't know what they are for, maybe fallback stuff?
  318. Dependency "AddPassShader" = "Hidden/TerrainEngine/Splatmap/Diffuse-AddPass"
  319. Dependency "BaseMapShader" = "Hidden/TerrainEngine/Splatmap/Diffuse-Base"
  320. Dependency "BaseMapGenShader" = "Hidden/TerrainEngine/Splatmap/Diffuse-BaseGen"
  321. Dependency "Details0" = "Hidden/TerrainEngine/Details/Vertexlit"
  322. Dependency "Details1" = "Hidden/TerrainEngine/Details/WavingDoublePass"
  323. Dependency "Details2" = "Hidden/TerrainEngine/Details/BillboardWavingDoublePass"
  324. Dependency "Tree0" = "Hidden/TerrainEngine/BillboardTree"
  325.  
  326. Fallback "Diffuse"
  327. }
  328.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement