InTerra_SplatmapMix.hlsl 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. #ifdef INTERRA_OBJECT
  2. void ObjectIntegration_float(float heightOffset, float3 worldPos, float3 tangentViewDirTerrain, float3 worldViewDir, float3 worldNormal, float3 worldTangent, float3 worldBitangent, float2 detailUV, float4 terrainNormals, float4 objectAlbedo, float3 objectNormal, float4 objectMask, half3 objectEmission, out half3 albedo, out half3 mixedNormal, out half smoothness, out half metallic, out half occlusion, out half3 emission)
  3. #else
  4. #ifdef INTERRA_MESH_TERRAIN
  5. void SplatmapMix_float(float3 tangentViewDirTerrain, float3 worldNormal, float3 worldPos,float3 worldTangent, float3 worldBitangent, out half3 albedo, out half3 mixedNormal, out half smoothness, out half metallic, out half occlusion)
  6. #else
  7. #include "InTerra_Functions.hlsl"
  8. void SplatmapMix(float4 uvMainAndLM, float2 uvS[_LAYER_COUNT], float3 worldNormal, float3 tangentViewDirTerrain, float3 worldPos, out half weight, out half4 mixedDiffuse, out half smoothness, out half metallic, out half occlusion, inout half3 mixedNormal)
  9. #endif
  10. #endif
  11. {
  12. half4 mixedMask = 0;
  13. half4 dMixedMask = 0;
  14. occlusion = 1;
  15. metallic = 0;
  16. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  17. half4 mixedDiffuse;
  18. #endif
  19. float2 uvSplat[_LAYER_COUNT];
  20. half4 mask[_LAYER_COUNT];
  21. #ifdef TRIPLANAR
  22. float2 uvSplat_front[_LAYER_COUNT], uvSplat_side[_LAYER_COUNT];
  23. half4 mask_front[_LAYER_COUNT], mask_side[_LAYER_COUNT];
  24. #endif
  25. #ifdef _TERRAIN_DISTANCEBLEND
  26. float2 distantUV[_LAYER_COUNT];
  27. half4 dMask[_LAYER_COUNT];
  28. #ifdef TRIPLANAR
  29. float2 distantUV_front[_LAYER_COUNT], distantUV_side[_LAYER_COUNT];
  30. half4 dMask_front[_LAYER_COUNT], dMask_side[_LAYER_COUNT];
  31. #endif
  32. #endif
  33. #ifdef _TRACKS
  34. float4 trackSplats[_LAYER_COUNT];
  35. float4 trackSplatsColor[_LAYER_COUNT];
  36. float4 trackDepth = 0;
  37. #endif
  38. //====================================================================================
  39. //--------------------------------- SPLAT MAP CONTROL --------------------------------
  40. //====================================================================================
  41. half4 blendMask[2];
  42. blendMask[0] = float4(1, 0, 0, 0);
  43. blendMask[1] = float4(0, 0, 0, 0);
  44. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  45. float2 terrainUV = (worldPos.xz - _TerrainPosition.xz) * (1 / _TerrainSize.xz);
  46. #ifndef _LAYERS_ONE
  47. float2 splatMapUV = (terrainUV * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
  48. blendMask[0] = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatMapUV);
  49. #ifdef _LAYERS_EIGHT
  50. blendMask[1] = SAMPLE_TEXTURE2D(_Control1, sampler_Control, splatMapUV);
  51. #endif
  52. #endif
  53. #else
  54. float2 terrainUV = uvMainAndLM.xy;
  55. blendMask[0] = SAMPLE_TEXTURE2D(_Control, sampler_Control, uvMainAndLM.xy);
  56. #ifdef _LAYERS_EIGHT
  57. blendMask[1] = SAMPLE_TEXTURE2D(_Control1, sampler_Control, uvMainAndLM.xy);
  58. #endif
  59. #ifdef _LAYERS_EIGHT
  60. #ifdef TERRAIN_SPLAT_ADDPASS
  61. weight = 0;
  62. #else
  63. weight = 1;
  64. #endif
  65. #else
  66. #if defined(_LAYERS_TWO) && defined(TERRAIN_SPLAT_ADDPASS)
  67. blendMask[0] = float4(0, 0, 0, 0);
  68. #endif
  69. weight = dot(blendMask[0], 1.0h);
  70. #ifdef TERRAIN_SPLAT_ADDPASS
  71. clip(weight <= 0.005h ? -1.0h : 1.0h);
  72. #endif
  73. #ifndef _TERRAIN_BASEMAP_GEN
  74. // Normalize weights before lighting and restore weights in final modifier functions so that the overal
  75. // lighting result can be correctly weighted.
  76. blendMask[0] /= (weight + HALF_MIN);
  77. #endif
  78. #endif
  79. #endif
  80. #if defined(_LAYERS_TWO) && !defined(INTERRA_MESH_TERRAIN)
  81. blendMask[0].r = _ControlNumber == 0 ? blendMask[0].r : _ControlNumber == 1 ? blendMask[0].g : _ControlNumber == 2 ? blendMask[0].b : blendMask[0].a;
  82. blendMask[0].g = 1 - blendMask[0].r;
  83. #endif
  84. float2 tintUV = terrainUV * _TerrainColorTintTexture_ST.xy + _TerrainColorTintTexture_ST.zw;
  85. float2 normalTintUV = terrainUV * _TerrainNormalTintTexture_ST.xy + _TerrainNormalTintTexture_ST.zw;
  86. float3 tint = SAMPLE_TEXTURE2D(_TerrainColorTintTexture, SamplerState_Linear_Repeat, tintUV).rgb;
  87. float3 normalTint = UnpackNormalScale(SAMPLE_TEXTURE2D(_TerrainNormalTintTexture, SamplerState_Linear_Repeat, normalTintUV), 1).xyz;
  88. #if defined(_TERRAIN_BLEND_HEIGHT) && !defined(_TERRAIN_BASEMAP_GEN) && !defined(_LAYERS_ONE) && !defined(_LAYERS_EIGHT)
  89. if (_HeightmapBlending == 1)
  90. {
  91. blendMask[0] = (blendMask[0].r + blendMask[0].g + blendMask[0].b + blendMask[0].a == 0.0f ? 1.000f : blendMask[0]); //this is preventing the black area when more than one pass
  92. }
  93. #endif
  94. #if !defined(_TERRAIN_BASEMAP_GEN)
  95. float3 flipUV = worldNormal.rgb < 0 ? -1 : 1;
  96. float3 triplanarWeights = abs(worldNormal.rgb);
  97. triplanarWeights = pow(triplanarWeights, _TriplanarSharpness);
  98. triplanarWeights = triplanarWeights / (triplanarWeights.x + triplanarWeights.y + triplanarWeights.z);
  99. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  100. float weight;
  101. #endif
  102. #if defined(INTERRA_OBJECT)
  103. TriplanarOneToAllSteep(blendMask, (1 - terrainNormals.w), weight);
  104. #else
  105. TriplanarOneToAllSteep(blendMask, (1 - triplanarWeights.y), weight);
  106. #endif
  107. #endif
  108. half4 origBlendMask[2] = blendMask;
  109. #if defined(_TERRAIN_DISTANCEBLEND)
  110. half4 dBlendMask[2];
  111. half4 dOrigBlendMask[2] = blendMask;
  112. dBlendMask[0] = blendMask[0];
  113. dBlendMask[1] = blendMask[1];
  114. float dist = smoothstep(_HT_distance.x, _HT_distance.y, (distance(worldPos, _WorldSpaceCameraPos)));
  115. float sampleDistMask = dist < 0.001f ? 1 : 0;
  116. if(sampleDistMask)
  117. {
  118. dBlendMask[0] *= sampleDistMask;
  119. #ifdef _LAYERS_EIGHT
  120. dBlendMask[1] *= sampleDistMask;
  121. #endif
  122. }
  123. #endif
  124. float heightSum = 0.5f;
  125. float dHeightSum = 0.5f;
  126. #ifdef PARALLAX
  127. float lod = 0;
  128. #if defined(INTERRA_OBJECT)
  129. UNITY_BRANCH if ((_Terrain_Parallax == 1) || (_Object_Parallax == 1))
  130. #else
  131. UNITY_BRANCH if (_Terrain_Parallax == 1)
  132. #endif
  133. {
  134. lod = smoothstep(_MipMapFade.x, _MipMapFade.y, (distance(worldPos, _WorldSpaceCameraPos)));
  135. }
  136. #endif
  137. //================================================================================
  138. //-------------------------------------- UVs -------------------------------------
  139. //================================================================================
  140. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  141. #if defined(INTERRA_OBJECT)
  142. #ifndef _OBJECT_TRIPLANAR
  143. _SteepDistortion = worldNormal.y > 0.5 ? 0 : (1 - worldNormal.y) * _SteepDistortion;
  144. _SteepDistortion *= objectAlbedo.r;
  145. #else
  146. _SteepDistortion = 0;
  147. #endif
  148. #endif
  149. float3 positionOffset = _WorldMapping ? worldPos : (worldPos - _TerrainPosition);
  150. #ifndef TRIPLANAR
  151. UvSplat(uvSplat, positionOffset);
  152. #else
  153. float offsetZ = -flipUV.z * worldPos.y;
  154. float offsetX = -flipUV.x * worldPos.y;
  155. #if defined(INTERRA_OBJECT)
  156. offsetZ = _DisableOffsetY == 1 ? -flipUV.z * worldPos.y : heightOffset * -flipUV.z + (worldPos.z);
  157. offsetX = _DisableOffsetY == 1 ? -flipUV.x * worldPos.y : heightOffset * -flipUV.x + (worldPos.x);
  158. #endif
  159. offsetZ -= _TerrainPosition.z;
  160. offsetX -= _TerrainPosition.x;
  161. UvSplat(uvSplat, uvSplat_front, uvSplat_side, positionOffset, offsetZ, offsetX, flipUV);
  162. #endif
  163. #else
  164. #ifndef TRIPLANAR
  165. UvSplat(uvSplat, uvS, uvMainAndLM.xy);
  166. #else
  167. UvSplat(uvSplat, uvSplat_front, uvSplat_side, worldPos, uvS, uvMainAndLM.xy, flipUV);
  168. #endif
  169. #endif
  170. //-------------------- PARALLAX OFFSET -------------------------
  171. #if defined(_TERRAIN_PARALLAX) && !defined(_TERRAIN_BASEMAP_GEN)
  172. float3 viewDirTerrain = float3(0.0f, 0.0f, 0.0f);
  173. UNITY_BRANCH if (_Terrain_Parallax == 1)
  174. {
  175. viewDirTerrain = tangentViewDirTerrain;
  176. ParallaxUV(uvSplat, viewDirTerrain, blendMask, triplanarWeights.y, lod);
  177. }
  178. #endif
  179. //--------------------- DISTANCE UV ------------------------
  180. #ifdef _TERRAIN_DISTANCEBLEND
  181. DistantUV(distantUV, uvSplat);
  182. #ifdef TRIPLANAR
  183. #ifdef _TERRAIN_TRIPLANAR_ONE
  184. distantUV_front[0] = uvSplat_front[0] * (_DiffuseRemapOffset0.r + 1) * _HT_distance_scale;
  185. distantUV_side[0] = uvSplat_side[0] * (_DiffuseRemapOffset0.r + 1) * _HT_distance_scale;
  186. #else
  187. DistantUV(distantUV_front, uvSplat_front);
  188. DistantUV(distantUV_side, uvSplat_side);
  189. #endif
  190. #endif
  191. #endif
  192. //======================================================================
  193. //------------------------- OBJECT INTERSECTION ----------------------
  194. //======================================================================
  195. #ifdef INTERRA_OBJECT
  196. float steeptriplanarWeights = _SteepIntersection == 1 ? saturate(worldNormal.y + _Steepness) : 1;
  197. float intersect1 = smoothstep(_Intersection.y, _Intersection.x, heightOffset) * steeptriplanarWeights;
  198. float intersect2 = smoothstep(_Intersection2.y, _Intersection2.x, heightOffset) * (1 - steeptriplanarWeights);
  199. float intersection = intersect1 + intersect2;
  200. float intersectNormal = smoothstep(_NormIntersect.y, _NormIntersect.x, heightOffset);
  201. if (intersection < 1e-5f)
  202. {
  203. blendMask[0] = 0.0f;
  204. blendMask[1] = 0.0f;
  205. #if defined(_TERRAIN_DISTANCEBLEND)
  206. dBlendMask[0] = 0.0f;
  207. dBlendMask[1] = 0.0f;
  208. #endif
  209. }
  210. #endif
  211. //====================================================================================
  212. //----------------------------------- MASK MAPS ------------------------------------
  213. //====================================================================================
  214. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  215. #ifdef _TERRAIN_TRIPLANAR_ONE
  216. SampleMask(mask, uvSplat, blendMask, triplanarWeights.y + (1 - blendMask[0].r));
  217. SampleMaskTOL(mask_front, mask, uvSplat_front, triplanarWeights.z);
  218. SampleMaskTOL(mask_side, mask, uvSplat_side, triplanarWeights.x);
  219. #else
  220. SampleMask(mask, uvSplat, blendMask, triplanarWeights.y);
  221. SampleMask(mask_front, uvSplat_front, blendMask, triplanarWeights.z);
  222. SampleMask(mask_side, uvSplat_side, blendMask, triplanarWeights.x);
  223. #endif
  224. MaskWeight(mask, mask_front, mask_side, blendMask, triplanarWeights, _HeightTransition);
  225. #else
  226. SampleMask(mask, uvSplat, blendMask, 1.0f);
  227. #endif
  228. #ifdef _TERRAIN_DISTANCEBLEND
  229. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  230. #ifdef _TERRAIN_TRIPLANAR_ONE
  231. SampleMask(dMask, distantUV, dBlendMask, saturate(triplanarWeights.y + (1 - dBlendMask[0].r)));
  232. SampleMaskTOL(dMask_front, dMask, distantUV_front, blendMask[0].r * triplanarWeights.z );
  233. SampleMaskTOL(dMask_side, dMask, distantUV_side, blendMask[0].r * triplanarWeights.x );
  234. #else
  235. SampleMask(dMask, distantUV, dBlendMask, triplanarWeights.y);
  236. SampleMask(dMask_front, distantUV_front, dBlendMask, triplanarWeights.z);
  237. SampleMask(dMask_side, distantUV_side, dBlendMask, triplanarWeights.x);
  238. #endif
  239. MaskWeight(dMask, dMask_front, dMask_side, dBlendMask, triplanarWeights, _Distance_HeightTransition);
  240. #else
  241. SampleMask(dMask, distantUV, dBlendMask, 1.0f);
  242. #endif
  243. dBlendMask = dOrigBlendMask;
  244. #endif
  245. blendMask = origBlendMask;
  246. //========================================================================================
  247. //------------------------------ HEIGHT MAP SPLAT BLENDINGS ------------------------------
  248. //========================================================================================
  249. #if defined(_TERRAIN_BLEND_HEIGHT) && !defined(_LAYERS_ONE) && !defined(TERRAIN_SPLAT_ADDPASS)
  250. #ifdef _TERRAIN_BASEMAP_GEN
  251. if (_NumLayersCount <= 4)
  252. #endif
  253. {
  254. if (_HeightmapBlending == 1)
  255. {
  256. HeightBlend(mask, blendMask, _HeightTransition);
  257. #ifdef _TERRAIN_DISTANCEBLEND
  258. HeightBlend(dMask, dBlendMask, _Distance_HeightTransition);
  259. #endif
  260. }
  261. }
  262. #endif
  263. MaskSplatWeight(mask, blendMask, mixedMask);
  264. #ifdef _TERRAIN_DISTANCEBLEND
  265. MaskSplatWeight(dMask, dBlendMask, dMixedMask);
  266. dMixedMask = lerp(mixedMask, dMixedMask, _HT_cover);
  267. mixedMask = lerp(mixedMask, dMixedMask, dist);
  268. #endif
  269. #if defined(_TERRAIN_MASK_MAPS) || defined(_TERRAIN_NORMAL_IN_MASK)
  270. occlusion = mixedMask.g;
  271. metallic = mixedMask.r;
  272. #endif
  273. #if defined(_TERRAIN_BLEND_HEIGHT) && !defined(_LAYERS_ONE) && !defined(TERRAIN_SPLAT_ADDPASS)
  274. if (_HeightmapBlending == 1)
  275. {
  276. heightSum = mixedMask.b;
  277. #ifdef _TERRAIN_DISTANCEBLEND
  278. if(sampleDistMask)
  279. {
  280. dBlendMask[0] *= sampleDistMask;
  281. #ifdef _LAYERS_EIGHT
  282. dBlendMask[1] *= sampleDistMask;
  283. #endif
  284. }
  285. #endif
  286. }
  287. #endif
  288. //-------------------- HEIGHTMAP OBJECT INTERSECTION ----------------
  289. #ifdef INTERRA_OBJECT
  290. objectMask.rgba = objectMask.rgba * _MaskMapRemapScale.rgba + _MaskMapRemapOffset.rgba;
  291. half height = objectMask.b;
  292. half terrainHeith = 0.5f;
  293. if (_HeightmapBlending == 1)
  294. {
  295. terrainHeith = lerp(HeightSum(mask, blendMask), 1, intersection);
  296. }
  297. float2 heightIntersect = (1 / (1 * pow(2, float2(((1 - intersection) * height), (intersection * terrainHeith)) * (-(_Sharpness)))) + 1) * 0.5;
  298. heightIntersect /= (heightIntersect.r + heightIntersect.g);
  299. heightSum = (heightSum * heightIntersect.g) + (height * heightIntersect.r);
  300. if (heightIntersect.g < 1e-3f)
  301. {
  302. blendMask[0] = 0.0f;
  303. blendMask[1] = 0.0f;
  304. #if defined(_TERRAIN_DISTANCEBLEND)
  305. dBlendMask[0] = 0.0f;
  306. dBlendMask[1] = 0.0f;
  307. #endif
  308. }
  309. #endif
  310. //=======================================================================
  311. //-------------------- PUDDLES & RAINDROPS NORMALS --------------------
  312. //=======================================================================
  313. #if !defined(_TERRAIN_BASEMAP_GEN) && defined(_PUDDLES)
  314. float2 puddlesHeight = float2(0.0f , 1.0f);
  315. float horizontalWeight = 0.0f;
  316. float3 ripNormal = float3(0, 0, 1);
  317. puddlesHeight = (1 / (1 * pow(2, float2(_InTerra_GlobalPuddles.x, heightSum) * (-(100)))) + 1) * 0.5;
  318. puddlesHeight /= (puddlesHeight.r + puddlesHeight.g);
  319. float3 puddleWeight = pow(abs(worldNormal.rgb), _TriplanarSharpness);
  320. puddleWeight = puddleWeight / (puddleWeight.x + puddleWeight.y + puddleWeight.z);
  321. horizontalWeight = smoothstep(0.9999f, 1.0f, saturate(puddleWeight.y - ((puddleWeight.x + puddleWeight.z) * 100000000.0f)));
  322. puddlesHeight.r *= horizontalWeight;
  323. _InTerra_GlobalRaindropRipples.z = 1.0f / _InTerra_GlobalRaindropRipples.z * 0.1f;
  324. if (_InTerra_GlobalRaindropRipples.x > 0.0f)
  325. {
  326. if (puddlesHeight.x > 0.5f && _InTerra_GlobalRaindropsDistance.y > 0.0f)
  327. {
  328. float raindropsDistance = smoothstep(_InTerra_GlobalRaindropsDistance.x, _InTerra_GlobalRaindropsDistance.y, distance(worldPos, _WorldSpaceCameraPos));
  329. float rainIndex = 1 / (min(5.0f, _InTerra_GlobalRaindropRipples.x) * 4.0f);
  330. for (float i = 5.0; i > 4.0; i -= rainIndex)
  331. {
  332. ripNormal = BlendNormal(ripNormal, RainRipples(worldPos.zx * _InTerra_GlobalRaindropRipples.z * i + i*0.24f , i, i * 0.25f));
  333. }
  334. ripNormal = lerp(ripNormal, float3(0, 0, 1), raindropsDistance);
  335. }
  336. float2 uvRefractOffset = ripNormal.xy * 0.01;
  337. for (int i = 0; i < _LAYER_COUNT; ++i)
  338. {
  339. uvSplat[i] += uvRefractOffset;
  340. }
  341. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  342. ripNormal = WorldTangent(worldTangent, worldBitangent, ripNormal);
  343. #endif
  344. }
  345. #endif
  346. //========================================================================================
  347. //------------------------------- ALBEDO, SMOOTHNESS & NORMAL ---------------------------
  348. //========================================================================================
  349. #if !(defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN))
  350. float3 worldTangent;
  351. float3 worldBitangent;
  352. #endif
  353. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  354. float4 frontDiffuse;
  355. float3 frontNormal;
  356. float4 sideDiffuse;
  357. float3 sideNormal;
  358. #ifdef _TERRAIN_TRIPLANAR_ONE
  359. #ifndef TERRAIN_SPLAT_ADDPASS
  360. float tolWeightY = saturate(triplanarWeights.y + (1 - blendMask[0].r));
  361. #else
  362. float tolWeightY = 1.0f;
  363. #endif
  364. SampleSplat(uvSplat, blendMask, tolWeightY, mask, mixedDiffuse, mixedNormal);
  365. SampleSplatTOL(frontDiffuse, frontNormal, uvSplat_front, blendMask, triplanarWeights.z, mask);
  366. SampleSplatTOL(sideDiffuse, sideNormal, uvSplat_side, blendMask, triplanarWeights.x, mask);
  367. #else
  368. SampleSplat(uvSplat, blendMask, triplanarWeights.y, mask, mixedDiffuse, mixedNormal);
  369. SampleSplat(uvSplat_front, blendMask, triplanarWeights.z, mask, frontDiffuse, frontNormal);
  370. SampleSplat(uvSplat_side, blendMask, triplanarWeights.x, mask, sideDiffuse, sideNormal);
  371. #endif
  372. #else
  373. SampleSplat(uvSplat, blendMask, 1.0f, mask, mixedDiffuse, mixedNormal);
  374. #endif
  375. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  376. mixedNormal = WorldTangent(worldTangent, worldBitangent, mixedNormal);
  377. #endif
  378. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  379. mixedDiffuse = mixedDiffuse + frontDiffuse + sideDiffuse;
  380. mixedNormal = TriplanarNormal(mixedNormal, worldTangent, worldBitangent, frontNormal, sideNormal, triplanarWeights, flipUV);
  381. #endif
  382. #ifdef _TERRAIN_DISTANCEBLEND
  383. float4 distantDiffuse;
  384. float3 distantNormal;
  385. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  386. float4 dFrontDiffuse;
  387. float3 dFontNormal;
  388. float4 dSideDiffuse;
  389. float3 dSideNormal;
  390. #ifdef _TERRAIN_TRIPLANAR_ONE
  391. #ifndef TERRAIN_SPLAT_ADDPASS
  392. tolWeightY = saturate(triplanarWeights.y + (1 - dBlendMask[0].r));
  393. #endif
  394. SampleSplat(distantUV, dBlendMask, tolWeightY, dMask, distantDiffuse, distantNormal);
  395. SampleSplatTOL(dFrontDiffuse, dFontNormal, distantUV_front, dBlendMask, triplanarWeights.z, dMask);
  396. SampleSplatTOL(dSideDiffuse, dSideNormal, distantUV_side, dBlendMask, triplanarWeights.x, dMask);
  397. #else
  398. SampleSplat(distantUV, dBlendMask, triplanarWeights.y, dMask, distantDiffuse, distantNormal);
  399. SampleSplat(distantUV_front, dBlendMask, triplanarWeights.z, dMask, dFrontDiffuse, dFontNormal);
  400. SampleSplat(distantUV_side, dBlendMask, triplanarWeights.x, dMask, dSideDiffuse, dSideNormal);
  401. #endif
  402. #else
  403. SampleSplat(distantUV, dBlendMask, 1.0f, dMask, distantDiffuse, distantNormal);
  404. #endif
  405. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  406. distantNormal = WorldTangent(worldTangent, worldBitangent, distantNormal);
  407. #endif
  408. #if defined(TRIPLANAR) && !defined(_TERRAIN_BASEMAP_GEN)
  409. distantDiffuse = distantDiffuse + dFrontDiffuse + dSideDiffuse;
  410. distantNormal = TriplanarNormal(distantNormal, worldTangent, worldBitangent, dFontNormal, dSideNormal, triplanarWeights, flipUV);
  411. #endif
  412. distantDiffuse = lerp(mixedDiffuse, distantDiffuse, _HT_cover);
  413. distantNormal = lerp(mixedNormal, distantNormal, _HT_cover);
  414. #ifdef _TERRAIN_BASEMAP_GEN
  415. mixedDiffuse = distantDiffuse;
  416. #else
  417. mixedDiffuse = lerp(mixedDiffuse, distantDiffuse, dist);
  418. mixedNormal = lerp(mixedNormal, distantNormal, dist);
  419. #endif
  420. #endif
  421. #if !defined(TRIPLANAR_TINT)
  422. mixedDiffuse.rgb = lerp(mixedDiffuse.rgb, (mixedDiffuse.rgb * tint), _TerrainColorTintStrenght).rgb;
  423. #endif
  424. float normalDist = smoothstep(_TerrainNormalTintDistance.x, _TerrainNormalTintDistance.y, (distance(worldPos, _WorldSpaceCameraPos)));
  425. #ifdef INTERRA_OBJECT
  426. normalTint = WorldTangent(worldTangent, worldBitangent, normalTint);
  427. #endif
  428. mixedNormal = lerp(mixedNormal, BlendNormals(mixedNormal, normalTint), _TerrainNormalTintStrenght * normalDist).rgb;
  429. //========================================================================================
  430. //--------------------------------------- TRACKS --------------------------------------
  431. //========================================================================================
  432. #if defined(_TRACKS) && !defined(_TERRAIN_BASEMAP_GEN)
  433. if (_Tracks)
  434. {
  435. float halfTrackArea = _InTerra_TrackArea * 0.5f;
  436. float _InTerra_TrackFading = 25;
  437. float2 trackUV = float2((worldPos.x - _InTerra_TrackPosition.x) + (halfTrackArea), -(worldPos.z - _InTerra_TrackPosition.z - (halfTrackArea))) * 1.0f / _InTerra_TrackArea;
  438. float trackDist = smoothstep(_InTerra_TrackArea - 1.0f, _InTerra_TrackArea - _InTerra_TrackFading, (distance(worldPos, float3(_WorldSpaceCameraPos.x, _WorldSpaceCameraPos.y, _WorldSpaceCameraPos.z))));
  439. float2 minDist = step(float2(0.0f, 0.0f), trackUV);
  440. float2 maxDist = step(float2(0.0f, 0.0f), 1.0 - trackUV);
  441. trackDist *= (minDist.x * minDist.y * maxDist.x * maxDist.y);
  442. UnpackTrackSplatValues(trackSplats);
  443. UnpackTrackSplatColor(trackSplatsColor);
  444. float4 trackColor = TrackSplatValues(blendMask, trackSplatsColor);
  445. float4 trackValues = TrackSplatValues(blendMask, trackSplats);
  446. #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
  447. float2 terrainSize = _TerrainSize.xz * 10;
  448. float2 tUV = terrainUV.xy;
  449. #else
  450. float2 terrainSize = _TerrainSizeXZPosY.xy;
  451. float2 tUV = uvMainAndLM.xy;
  452. #endif
  453. float2 trackDetailUV = float2(tUV.x, -tUV.y) * _TrackDetailTexture_ST.xy + _TrackDetailTexture_ST.zw;
  454. #ifdef _TERRAIN_PARALLAX
  455. float2 trackParallaxOffset = ParallaxOffset(_InTerra_TrackTexture, SamplerState_Linear_Repeat, _ParallaxTrackSteps, -trackValues.y, trackUV, float3( -viewDirTerrain.x, viewDirTerrain.y, -viewDirTerrain.z), _ParallaxTrackAffineSteps, _MipMapLevel + (lod * (log2(max(_InTerra_TrackTexture_TexelSize.z, _InTerra_TrackTexture_TexelSize.w)) + 1)), 1 );
  456. trackUV += trackParallaxOffset;
  457. trackDetailUV += (trackParallaxOffset ) * (_TrackDetailTexture_ST.xy );
  458. #endif
  459. float4 trackDetail = SAMPLE_TEXTURE2D(_TrackDetailTexture, SamplerState_Linear_Repeat, trackDetailUV);
  460. trackDepth = SAMPLE_TEXTURE2D_LOD(_InTerra_TrackTexture, SamplerState_Linear_Repeat, trackUV, 0);
  461. float normalsOffset = _InTerra_TrackTexture_TexelSize.x * 2.0f;
  462. float texelArea = _InTerra_TrackTexture_TexelSize.x * 100 * _InTerra_TrackArea;
  463. float normalStrenghts = _TrackNormalStrenght / texelArea;
  464. float normalEdgeStrenghts = _TrackEdgeNormals / texelArea;
  465. float4 heights[4];
  466. heights[0] = (SAMPLE_TEXTURE2D_LOD(_InTerra_TrackTexture, SamplerState_Linear_Repeat, trackUV + float2(0.0f, normalsOffset), 0.0f));
  467. heights[1] = (SAMPLE_TEXTURE2D_LOD(_InTerra_TrackTexture, SamplerState_Linear_Repeat, trackUV + float2(normalsOffset, 0.0f), 0.0f));
  468. heights[2] = (SAMPLE_TEXTURE2D_LOD(_InTerra_TrackTexture, SamplerState_Linear_Repeat, trackUV + float2(-normalsOffset, 0.0f), 0.0f));
  469. heights[3] = (SAMPLE_TEXTURE2D_LOD(_InTerra_TrackTexture, SamplerState_Linear_Repeat, trackUV + float2(0.0f, -normalsOffset), 0.0f));
  470. for (int i = 0; i < 4; ++i)
  471. {
  472. heights[i] *= float4(1.0f, 1.0f, normalStrenghts, normalEdgeStrenghts);
  473. }
  474. float3 edgeNormals = float3(float2(heights[1].a - heights[2].a, heights[3].a - heights[0].a), 1.0f);
  475. float3 trackNormal = float3(float2(heights[1].b - heights[2].b, heights[3].b - heights[0].b), 1.0f);
  476. float heightSum =HeightSum(mask, blendMask);
  477. float trackHeightMap = saturate(trackDepth.b + _TrackHeightOffset);
  478. float2 trackIntersect = float2(trackDepth.b, 1 - trackDepth.b);
  479. trackIntersect *= (1 / (pow(2, float2(trackHeightMap, heightSum) * (-(_TrackHeightTransition)))) + 1) * 0.5;
  480. trackIntersect /= (trackIntersect.r + trackIntersect.g);
  481. float track = trackIntersect.r * trackDist;
  482. float colorOpacity = saturate(track * trackColor.a);
  483. float3 trackDetailNormal = UnpackNormalScale(SAMPLE_TEXTURE2D(_TrackDetailNormalTexture, SamplerState_Linear_Repeat, trackDetailUV), _TrackDetailNormalStrenght);
  484. trackDetailNormal.y *= -1;
  485. trackDetailNormal.z += 1e-5f;
  486. trackNormal = lerp(trackNormal, normalize(lerp(trackDetailNormal.xyz, trackNormal, 0.5f)), trackValues.a) * trackIntersect.r;
  487. float trackEdge = saturate(pow(abs(trackDepth.a), _TrackEdgeSharpness));
  488. float normalOpacity = saturate(trackValues.z * (trackEdge + track)) * trackDist;
  489. trackNormal = normalize(lerp(edgeNormals, trackNormal, trackDepth.b));
  490. trackNormal.z += 1e-5f;
  491. trackColor = lerp(trackColor, (trackColor * trackDetail), trackValues.a);
  492. #ifdef INTERRA_OBJECT
  493. trackNormal = WorldTangent(worldTangent, worldBitangent, trackNormal);
  494. #endif
  495. mixedNormal = lerp(mixedNormal, trackNormal, normalOpacity);
  496. mixedDiffuse.rgb = lerp(mixedDiffuse.rgb, trackColor.rgb, colorOpacity);
  497. mixedDiffuse.a = lerp(mixedDiffuse.a, trackValues.x, track);
  498. occlusion = lerp(occlusion, _TrackAO, track);
  499. }
  500. #endif
  501. mixedDiffuse.a = lerp(mixedDiffuse.a, 1.0f, _InTerra_GlobalWetness);
  502. mixedNormal.xy = _InTerra_GlobalWetness > 0.4 ? mixedNormal.xy * (1 - min(0.8f, (_InTerra_GlobalWetness * 2.25f - 1))) : mixedNormal.xy;
  503. #if defined(INTERRA_MESH_TERRAIN)
  504. albedo = mixedDiffuse.rgb;
  505. if (_CheckHeight)
  506. {
  507. albedo *= float3(1.0f, 0.80f, 0.60f);
  508. }
  509. #endif
  510. //=======================================================================================
  511. //==============================| OBJECT INTEGRATION |===============================
  512. //=======================================================================================
  513. #if defined(INTERRA_OBJECT)
  514. objectAlbedo.a = _HasMask == 1 ? objectMask.a : _Smoothness;
  515. objectAlbedo.a = _GlobalWetnessDisabled ? objectAlbedo.a : lerp(objectAlbedo.a, 1.0f, _InTerra_GlobalWetness);
  516. half objectMetallic = _HasMask == 1 ? objectMask.r : _Metallic;
  517. half objectAo = _HasMask == 1 ? objectMask.g : _Ao;
  518. UNITY_BRANCH if (_Detail > 0)
  519. {
  520. UNITY_BRANCH if (_HasDetailAlbedo > 0)
  521. {
  522. half3 dt = SAMPLE_TEXTURE2D(_DetailAlbedoMap, SamplerState_Linear_Repeat, detailUV).rgb;
  523. objectAlbedo.rgb = lerp(objectAlbedo.rgb, half(2.0) * dt, _DetailStrenght).rgb;
  524. }
  525. half3 objectNormalD = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, SamplerState_Linear_Repeat, detailUV), _DetailNormalMapScale);
  526. objectNormal = (lerp(objectNormal, BlendNormalRNM(objectNormal, objectNormalD), _DetailStrenght));
  527. }
  528. if(!_GlobalWetnessDisabled)
  529. {
  530. objectNormal.xy = _InTerra_GlobalWetness > 0.4 ? objectNormal.xy * (1 - min(0.8f, (_InTerra_GlobalWetness * 2.25f - 1))) : objectNormal.xy;
  531. }
  532. mixedDiffuse = lerp(mixedDiffuse, objectAlbedo, heightIntersect.r);
  533. float3 terrainNormal = (mixedNormal.z * terrainNormals.xyz);
  534. terrainNormal.xy = mixedNormal.xy + terrainNormal.xy;
  535. mixedNormal = lerp(mixedNormal, terrainNormal, intersectNormal);
  536. mixedNormal = lerp(mixedNormal, objectNormal, heightIntersect.r);
  537. metallic = lerp(metallic, objectMetallic, heightIntersect.r);
  538. occlusion = lerp(occlusion, objectAo, heightIntersect.r);
  539. emission = 0;
  540. UNITY_BRANCH if (_EmissionEnabled > 0)
  541. {
  542. emission = lerp(0, objectEmission, heightIntersect.r);
  543. }
  544. albedo = mixedDiffuse.rgb;
  545. #endif
  546. //===============| PUDDLES & RAINDROPS FINAL MIX |======================
  547. #if !defined(_TERRAIN_BASEMAP_GEN) && defined(_PUDDLES)
  548. if (_InTerra_GlobalPuddles.y > 0.0f)
  549. {
  550. float wettnessAround = smoothstep(_InTerra_GlobalPuddles.y, _InTerra_GlobalPuddles.x, heightSum) * horizontalWeight;
  551. mixedNormal.xy = wettnessAround > 0.4 ? mixedNormal.xy * (1 - min(0.9f, (wettnessAround * 2.25f - 1))) : mixedNormal.xy;
  552. mixedDiffuse.a = lerp(mixedDiffuse.a, 1.0f, wettnessAround);
  553. mixedDiffuse.a = lerp(mixedDiffuse.a, 1.0f, puddlesHeight.r * horizontalWeight);
  554. mixedNormal = lerp(mixedNormal, ripNormal, puddlesHeight.r * horizontalWeight);
  555. }
  556. #endif
  557. smoothness = mixedDiffuse.a;
  558. }