| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038 |
- #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
- #ifdef _LAYERS_ONE
- #define _LAYER_COUNT 1
- #else
- #ifdef _LAYERS_TWO
- #define _LAYER_COUNT 2
- #else
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- #ifdef _LAYERS_EIGHT
- #define _LAYER_COUNT 8
- #endif
- #ifdef _LAYERS_SIXTEEN
- #define _LAYER_COUNT 16
- #endif
- #else
- #define _LAYER_COUNT 4
- #endif
- #endif
- #endif
- #ifdef INTERRA_MESH_TERRAIN
- SAMPLER(SamplerState_Linear_Repeat);
- #endif
- #else
- #include "InTerra_LayersDeclaration.hlsl"
- half4 _HT_distance;
- float _HT_distance_scale, _HT_cover;
- half _Distance_Height_blending, _Distance_HeightTransition, _TriplanarSharpness;
- half _ControlNumber;
- half _ParallaxAffineStepsTerrain;
- float _TerrainColorTintStrenght;
- float4 _TerrainColorTintTexture_ST;
- float4 _TerrainNormalTintDistance;
- float _TerrainNormalTintStrenght;
- float4 _TerrainNormalTintTexture_ST;
-
- half _TriplanarOneToAllSteep;
- float3 _TerrainSizeXZPosY;
- float4 _MipMapFade;
- float _MipMapLevel;
- TEXTURE2D(_TerrainColorTintTexture);
- TEXTURE2D(_TerrainNormalTintTexture); SAMPLER(SamplerState_Linear_Repeat);
- //-----Track Properties -----
- float _TrackTessallation;
- float _TrackDetailStrenght;
- float _TrackNormalStrenght;
- float _TrackEdgeNormals, _TrackEdgeSharpness;
- float _TrackDetailNormalStrenght;
- float _TrackHeightOffset;
- float _TrackTessallationHeightOffset;
- float _TrackTessallationHeightTransition;
- float _TrackAO;
- float4 _TrackDetailTexture_ST;
- float _ParallaxTrackAffineSteps;
- float _ParallaxTrackSteps;
- float _TrackHeightTransition;
- float _Gamma;
- float _WorldMapping;
-
- TEXTURE2D(_TrackDetailTexture);
- TEXTURE2D(_TrackDetailNormalTexture);
- float _HeightmapBlending;
- float _Tracks;
- float _Terrain_Parallax;
-
- TEXTURE2D_ARRAY(_SplatArray16);
- TEXTURE2D_ARRAY(_NormalArray16);
- float2 TerrainFrontUV(float3 wPos, float4 splatUV, float2 tc, float3 flip)
- {
- return float2(tc.x * -flip.z, (wPos.y - _TerrainSizeXZPosY.z) * (splatUV.y / _TerrainSizeXZPosY.y) + splatUV.w);
- }
- float2 TerrainSideUV(float3 wPos, float4 splatUV, float2 tc, float3 flip)
- {
- return float2(tc.y * flip.x, (wPos.y - _TerrainSizeXZPosY.z) * (splatUV.x / _TerrainSizeXZPosY.x) + splatUV.z);
- }
- #endif
- //----- Global Properties -----
- float _InTerra_TrackArea;
- float3 _InTerra_TrackPosition;
- TEXTURE2D(_InTerra_TrackTexture);
- float4 _InTerra_TrackTexture_TexelSize;
- float _InTerra_GlobalWetness;
- float _InTerra_TracksLayer;
- float _InTerra_TracksFading;
- float _InTerra_TracksFadingTime;
- float _InTerra_TrackTextureSize;
- float _InTerra_TrackLayer;
- float3 _InTerra_GlobalPuddles;
- float3 _InTerra_GlobalRaindropRipples;
- float4 _InTerra_GlobalRaindropsDistance;
- //------------------------------
- #ifndef _TERRAIN_BASEMAP
- //==========================================================================================
- //====================================== FUNCTIONS =====================================
- //==========================================================================================
- float2 ObjectFrontUV(float posOffset, float4 splatUV, float offsetZ)
- {
- return float2((posOffset + splatUV.z) / splatUV.x, (offsetZ + splatUV.w) / splatUV.y);
- }
- float2 ObjectSideUV(float posOffset, float4 splatUV, float offsetX)
- {
- return float2((offsetX + splatUV.z) / splatUV.x, (posOffset + splatUV.w) / splatUV.y);
- }
- float3 WorldTangent(float3 wTangent, float3 wBTangent, float3 mixedNormal)
- {
- mixedNormal.xy = mul(float2x2(wTangent.xz, wBTangent.xz), mixedNormal.xy);
- return half3(mixedNormal);
- }
- float2 HeightBlendTwoTextures(float2 splat, float2 heights, float sharpness)
- {
- splat *= (1 / (1 * pow(2, heights * (-(sharpness)))) + 1) * 0.5;
- splat /= (splat.r + splat.g);
- return splat;
- }
- void TriplanarOneToAllSteep(in out float4 blendMask[4], float weightY)
- {
- if (_TriplanarOneToAllSteep == 1)
- {
- blendMask[0] = float4(saturate(blendMask[0].r + weightY), saturate((blendMask[0].gba) - weightY));
- blendMask[1] = float4(saturate((blendMask[1].rgba) - weightY));
- #ifdef _LAYERS_SIXTEEN
- blendMask[2] = float4(saturate((blendMask[2].rgba) - weightY));
- blendMask[3] = float4(saturate((blendMask[3].rgba) - weightY));
- #endif
- }
- }
- float3 TriplanarNormal(float3 normal, float3 tangent, float3 bTangent, float3 normal_front, float3 normal_side, float3 triplanarWeights, half3 flipUV)
- {
- #ifdef INTERRA_OBJECT
- normal_front.y *= -flipUV.z;
- normal_front.xy = mul(float2x2(tangent.xy, bTangent.xy), normal_front.xy);
- normal_side.x *= -flipUV.x;
- normal_side.xy = mul(float2x2(tangent.yz, bTangent.yz), normal_side.xy);
- #else
- normal_side.xy = normal_side.yx; //this is needed because the uv was rotated
- normal_front.xy *= -flipUV.z;
- normal_side.x *= -flipUV.x;
- normal_side.y *= flipUV.x;
- #endif
- return half3 (normal + normal_front + normal_side);
- }
- #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
- #define DiffuseRemap(i) float4(_DiffuseRemapScale##i.xyzw)
- #else
- #define DiffuseRemap(i) float4(_DiffuseRemapScale##i.xyzw + _DiffuseRemapOffset##i.xyzw)
- #endif
- #ifndef _TERRAIN_BASEMAP_GEN
- #if defined(PARALLAX)
- float GetParallaxHeight(texture2D maskT, sampler maskS, float2 uv, float lod, float2 offset, int invert)
- {
- return abs(SAMPLE_TEXTURE2D_LOD(maskT, maskS, float2(uv + offset), lod).b -invert);
- }
- //this function is based on Parallax Occlusion Mapping from Shader Graph URP
- float2 ParallaxOffset(texture2D maskT, sampler maskS, int numSteps, float amplitude, float2 uv, float3 tangentViewDir, float affineSteps, float lod, int invert)
- {
- float2 offset = 0;
- if (numSteps > 0)
- {
- float3 viewDir = float3(tangentViewDir.xy * amplitude * -0.01, tangentViewDir.z);
- float stepSize = (1.0 / numSteps);
- float2 texOffsetPerStep = stepSize * viewDir.xy;
-
- // Do a first step before the loop to init all value correctly
- float2 texOffsetCurrent = float2(0.0, 0.0);
- float prevHeight = GetParallaxHeight(maskT, maskS, uv, lod, texOffsetCurrent, invert);
- texOffsetCurrent += texOffsetPerStep;
- float currHeight = GetParallaxHeight(maskT, maskS, uv, lod, texOffsetCurrent, invert);
- float rayHeight = 1.0 - stepSize; // Start at top less one sample
- for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
- {
- // Have we found a height below our ray height ? then we have an intersection
- if (currHeight > rayHeight)
- break; // end the loop
- prevHeight = currHeight;
- rayHeight -= stepSize;
- texOffsetCurrent += texOffsetPerStep;
- currHeight = GetParallaxHeight(maskT, maskS, uv, lod, texOffsetCurrent, invert);
- }
- if (affineSteps <= 1)
- {
- float delta0 = currHeight - rayHeight;
- float delta1 = (rayHeight + stepSize) - prevHeight;
- float ratio = delta0 / (delta0 + delta1);
- offset = texOffsetCurrent - ratio * texOffsetPerStep;
- currHeight = GetParallaxHeight(maskT, maskS, uv, lod, texOffsetCurrent, invert);
- }
- else
- {
- float pt0 = rayHeight + stepSize;
- float pt1 = rayHeight;
- float delta0 = pt0 - prevHeight;
- float delta1 = pt1 - currHeight;
- float delta;
- // Secant method to affine the search
- // Ref: Faster Relief Mapping Using the Secant Method - Eric Risser
- for (int i = 0; i < affineSteps; ++i)
- {
- // intersectionHeight is the height [0..1] for the intersection between view ray and heightfield line
- float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
- // Retrieve offset require to find this intersectionHeight
- offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
- currHeight = GetParallaxHeight(maskT, maskS, uv, lod, offset, invert);
- delta = intersectionHeight - currHeight;
- if (abs(delta) <= 0.01)
- break;
- // intersectionHeight < currHeight => new lower bounds
- if (delta < 0.0)
- {
- delta1 = delta;
- pt1 = intersectionHeight;
- }
- else
- {
- delta0 = delta;
- pt0 = intersectionHeight;
- }
- }
- }
- }
- return offset;
- }
- #if defined(_TERRAIN_PARALLAX) && !defined(_TERRAIN_BASEMAP_GEN) && !defined(TESSELLATION_ON)
- void ParallaxUV(inout float2 uv[_LAYER_COUNT], float3 tangentViewDir, float lod)
- {
- #define uvParallax(i) \
- uv[i] += ParallaxOffset(_Mask##i, sampler_Splat0, _DiffuseRemapOffset##i.w, DiffuseRemap(i).w, uv[i], tangentViewDir, _ParallaxAffineStepsTerrain, _MipMapLevel + (lod * (log2(max(_Mask##i##_TexelSize.z, _Mask##i##_TexelSize.w)) + 1)), 0); \
-
- uvParallax(0);
- #ifndef _LAYERS_ONE
- uvParallax(1);
- #ifndef _LAYERS_TWO
- uvParallax(2);
- uvParallax(3);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- uvParallax(4);
- uvParallax(5);
- uvParallax(6);
- uvParallax(7);
- #endif
- #ifdef _LAYERS_SIXTEEN
- uvParallax(8);
- uvParallax(9);
- uvParallax(10);
- uvParallax(11);
- uvParallax(12);
- uvParallax(13);
- uvParallax(14);
- uvParallax(15);
- #endif
- #endif
- #endif
- }
- #endif
- #endif
- #endif
- float3 UnpackNormals(float4 packednormal, float normalScale)
- {
- #ifdef SURFACE_GRADIENT
- #ifdef UNITY_NO_DXT5nm
- return float3(UnpackDerivativeNormalRGB(packednormal, normalScale), 0);
- #else
- return float3(UnpackDerivativeNormalRGorAG(packednormal, normalScale), 0);
- #endif
- #else
- #ifdef UNITY_NO_DXT5nm
- return UnpackNormalRGB(packednormal, normalScale);
- #else
- return UnpackNormalAG(packednormal, normalScale);
- #endif
- #endif
- }
- float3 UnpackNormalGAWithScale(float4 packednormal, float scale, half hasMask)
- {
- UNITY_BRANCH if (hasMask > 0)
- {
- #ifdef SURFACE_GRADIENT
- return float3(UnpackDerivativeNormalAG(packednormal, scale), 0);
- #else
- return UnpackNormalAG(packednormal, scale);
- #endif
- }
- else
- {
- return float3(0, 0, 1);
- }
- }
-
- float3 BlendNormals(float3 n1, float3 n2)
- {
- #ifdef INTERRA_OBJECT
- float3 t = n1.xyz + float3(0.0, 0.0, 1.0);
- float3 u = n2.xyz * float3(-1.0, -1.0, 1.0);
- float3 r = (t / t.z) * dot(t, u) - u;
- return r;
- #else
- return (float3(n1.xy + n2.xy, n1.z));
- #endif
- }
- #if defined(_NORMALMAPS) && !defined(_TERRAIN_NORMAL_IN_MASK)
- #if defined(_LAYERS_SIXTEEN) && (defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN))
- #define SampleNormals(i) (UnpackNormals(SAMPLE_TEXTURE2D_ARRAY(_NormalArray16, sampler_Splat0, uv[i], i), _NormalScale##i).xyz)
- #else
- #define SampleNormals(i) (UnpackNormals(SAMPLE_TEXTURE2D(_Normal##i, sampler_Splat0, uv[i]), _NormalScale##i).xyz)
- #endif
- #elif defined(_TERRAIN_NORMAL_IN_MASK)
- #define SampleNormals(i) float3(UnpackNormalGAWithScale(mask[i], _NormalScale##i, _LayerHasMask##i).xyz)
- #else
- #define SampleNormals(i) float3(0, 0, 1)
- #endif
- float3 SmoothMaskOrAlbedo(half mask, half albedo, float hasMask, float smoothness)
- {
- UNITY_BRANCH if (hasMask > 0)
- {
- albedo = mask;
- }
- else
- {
- albedo *= smoothness;
- }
- return albedo;
- }
- #ifdef _TERRAIN_MASK_MAPS
- #define Smoothness(i) SmoothMaskOrAlbedo(mask[i].a, albedo[i].a, _LayerHasMask##i, _Smoothness##i)
- #else
- #define Smoothness(i) albedo[i].a *= _Smoothness##i
- #endif
- #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
- #if defined(INTERRA_OBJECT) && !defined(TESSELLATION_SAMPLING) && !defined(_OBJECT_TRIPLANAR)
- #define UV(i) (posOffset.xz + _SplatUV##i.zw + distortion) / _SplatUV##i.xy;
- #else
- #define UV(i) (posOffset.xz + _SplatUV##i.zw) / _SplatUV##i.xy;
- #endif
- #ifdef PARALLAX
- #define fUV(i) ObjectFrontUV(posOffset.x, _SplatUV##i, offsetZ + (_DiffuseRemapScale##i.w * 0.004 * _SplatUV##i.x) * -flip.z);
- #define sUV(i) ObjectSideUV(posOffset.z, _SplatUV##i, offsetX + (_DiffuseRemapScale##i.w * 0.004 * _SplatUV##i.y) * -flip.x);
- #else
- #if defined(TESSELLATION_ON)
- #define fUV(i) ObjectFrontUV(posOffset.x, _SplatUV##i, offsetZ + (-_DiffuseRemapOffset##i.y * 0.005 - _TerrainTessOffset) * -flip.z);
- #define sUV(i) ObjectSideUV(posOffset.z, _SplatUV##i, offsetX + (-_DiffuseRemapOffset##i.y * 0.005 - _TerrainTessOffset) * -flip.x);
- #else
- #define fUV(i) ObjectFrontUV(posOffset.x, _SplatUV##i, offsetZ);
- #define sUV(i) ObjectSideUV(posOffset.z, _SplatUV##i, offsetX);
- #endif
- #endif
- #else
- #define UV(i) splatBaseUV * _Splat##i##_ST.xy + _Splat##i##_ST.zw;
- #define fUV(i) TerrainFrontUV(worldPos, _Splat##i##_ST, uvSplat[i], flip);
- #define sUV(i) TerrainSideUV(worldPos, _Splat##i##_ST, uvSplat[i], flip);
- #endif
- #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
- #ifndef TRIPLANAR
- void UvSplat(out float2 uvSplat[_LAYER_COUNT], float3 posOffset, float distortion)
- #else
- void UvSplat(out float2 uvSplat[_LAYER_COUNT], out float2 uvFront[_LAYER_COUNT], out float2 uvSide[_LAYER_COUNT], float3 posOffset, float offsetZ, float offsetX, float3 flip)
- #endif
- #else
- #ifndef TRIPLANAR
- void UvSplat(out float2 uvSplat[_LAYER_COUNT], float2 splatBaseUV)
- #else
- void UvSplat(out float2 uvSplat[_LAYER_COUNT], out float2 uvFront[_LAYER_COUNT], out float2 uvSide[_LAYER_COUNT], float3 worldPos, float2 splatBaseUV, float3 flip)
- #endif
- #endif
- {
- #ifndef TRIPLANAR
- #define SplatUV(i) \
- uvSplat[i] = UV(i);
- #else
- #define SplatUV(i) \
- uvSplat[i] = UV(i); \
- uvFront[i] = fUV(i); \
- uvSide[i] = sUV(i); \
- #endif
- SplatUV(0);
- #ifndef _LAYERS_ONE
- SplatUV(1);
- #ifndef _LAYERS_TWO
- SplatUV(2);
- SplatUV(3);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- SplatUV(4);
- SplatUV(5);
- SplatUV(6);
- SplatUV(7);
- #endif
- #ifdef _LAYERS_SIXTEEN
- SplatUV(8);
- SplatUV(9);
- SplatUV(10);
- SplatUV(11);
- SplatUV(12);
- SplatUV(13);
- SplatUV(14);
- SplatUV(15);
- #endif
- #endif
- #endif
- }
- void DistantUV(out float2 distantUV[_LAYER_COUNT], float2 uvSplat[_LAYER_COUNT])
- {
- #define uvDistant(i) \
- distantUV[i] = uvSplat[i] * (_DiffuseRemapOffset##i.r + 1) * _HT_distance_scale; \
-
- uvDistant(0);
- #ifndef _LAYERS_ONE
- uvDistant(1);
- #ifndef _LAYERS_TWO
- uvDistant(2);
- uvDistant(3);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- uvDistant(4);
- uvDistant(5);
- uvDistant(6);
- uvDistant(7);
- #endif
- #ifdef _LAYERS_SIXTEEN
- uvDistant(8);
- uvDistant(9);
- uvDistant(10);
- uvDistant(11);
- uvDistant(12);
- uvDistant(13);
- uvDistant(14);
- uvDistant(15);
- #endif
- #endif
- #endif
- }
- float4 RemapMasks(float4 mask, float4 remapScale, float4 remapOffset)
- {
- #ifdef _TERRAIN_NORMAL_IN_MASK
- mask.rb * remapScale.gb + remapOffset.gb;
- return mask;
- #else
- return mask * remapScale + remapOffset;
- #endif
- }
- #ifdef TERRAIN_MASK
- #define Mask(i) SAMPLE_TEXTURE2D(_Mask##i, sampler_Splat0, uv[i]);
- #ifdef _TERRAIN_NORMAL_IN_MASK
- #define RemapMask(i) mask[i] * float4(_MaskMapRemapScale##i.g, 1, _MaskMapRemapScale##i.b, 1) \
- + float4(_MaskMapRemapOffset##i.g, 0, _MaskMapRemapOffset##i.b, 0);
- #else
- #define RemapMask(i) mask[i] * _MaskMapRemapScale##i + _MaskMapRemapOffset##i;
- #endif
- #else
- #define Mask(i) float4(_Metallic##i, 1, 0.5, 0);
- #define RemapMask(i) mask[i];
- #endif
- void SampleMask(out float4 mask[_LAYER_COUNT], float2 uv[_LAYER_COUNT], float4 blendMask[4], float weight)
- {
- #define SampleMasks(i, blendMask) \
- UNITY_BRANCH if (blendMask * weight > 1e-5f ) \
- { \
- mask[i] = Mask(i); \
- mask[i] = RemapMask(i); \
- } \
- else \
- { \
- mask[i] = float4(_Metallic##i, 1, 0.5, 0); \
- } \
- SampleMasks(0, blendMask[0].r);
- #ifndef _LAYERS_ONE
- SampleMasks(1, blendMask[0].g);
- #ifndef _LAYERS_TWO
- SampleMasks(2, blendMask[0].b);
- SampleMasks(3, blendMask[0].a);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- SampleMasks(4, blendMask[1].r);
- SampleMasks(5, blendMask[1].g);
- SampleMasks(6, blendMask[1].b);
- SampleMasks(7, blendMask[1].a);
- #endif
- #ifdef _LAYERS_SIXTEEN
- SampleMasks(8, blendMask[2].r);
- SampleMasks(9, blendMask[2].g);
- SampleMasks(10, blendMask[2].b);
- SampleMasks(11, blendMask[2].a);
- SampleMasks(12, blendMask[3].r);
- SampleMasks(13, blendMask[3].g);
- SampleMasks(14, blendMask[3].b);
- SampleMasks(15, blendMask[3].a);
- #endif
- #endif
- #endif
- #undef SampleMasks
- }
- #if defined(_LAYERS_SIXTEEN) && (defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN))
- #define SampleSplats(i) SAMPLE_TEXTURE2D_ARRAY(_SplatArray16, sampler_Splat0, uv[i], i)
- #else
- #define SampleSplats(i) SAMPLE_TEXTURE2D(_Splat##i, sampler_Splat0, uv[i])
- #endif
- void SampleSplat(float2 uv[_LAYER_COUNT], float4 blendMask[4], float weight, inout float4 mask[_LAYER_COUNT], out float4 mixAlbedo, out float3 mixNormal)
- {
- float4 albedo[_LAYER_COUNT];
- float3 normal[_LAYER_COUNT];
- mixAlbedo = 0;
- mixNormal = 0;
- #define Samples(i, blendMask) blendMask *= weight; \
- UNITY_BRANCH if (blendMask > 1e-5f) \
- { \
- albedo[i] = SampleSplats(i); \
- albedo[i].rgb *= DiffuseRemap(i).xyz; \
- albedo[i].a = Smoothness(i).x; \
- normal[i] = SampleNormals(i).xyz; \
- mixAlbedo += albedo[i].xyzw * blendMask.x; \
- mixNormal += normal[i].xyz * blendMask.x; \
- } \
- else \
- { \
- albedo[i] = float4(0, 0, 0, 0); \
- normal[i] = float3(0, 1, 0); \
- } \
- Samples(0, blendMask[0].r);
- #ifndef _LAYERS_ONE
- Samples(1, blendMask[0].g);
- #ifndef _LAYERS_TWO
- Samples(2, blendMask[0].b);
- Samples(3, blendMask[0].a);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- Samples(4, blendMask[1].r);
- Samples(5, blendMask[1].g);
- Samples(6, blendMask[1].b);
- Samples(7, blendMask[1].a);
- #endif
- #ifdef _LAYERS_SIXTEEN
- Samples( 8, blendMask[2].r);
- Samples( 9, blendMask[2].g);
- Samples(10, blendMask[2].b);
- Samples(11, blendMask[2].a);
- Samples(12, blendMask[3].r);
- Samples(13, blendMask[3].g);
- Samples(14, blendMask[3].b);
- Samples(15, blendMask[3].a);
- #endif
- #endif
- #endif
- #undef Samples
- }
- half4 MaskSplatWeight(float4 mask[_LAYER_COUNT], float4 blendMask[4], out float4 mixedMask)
- {
- float splatWeight[_LAYER_COUNT];
- mixedMask = 0;
- #ifdef _TERRAIN_NORMAL_IN_MASK
- #define MixdMask(i, blendMask) float4(_Metallic##i, mask[i].r, mask[i].b, 0.0f) * blendMask
- #elif defined(_TERRAIN_MASK_HEIGHTMAP_ONLY)
- #define MixdMask(i, blendMask) float4(_Metallic##i, 1.0f, mask[i].b, 0.0f) * blendMask
- #else
- #define MixdMask(i, blendMask) mask[i] * blendMask
- #endif
- #define MixdMasks(i, blendMask) \
- UNITY_BRANCH if (blendMask > 0) \
- { \
- mixedMask += MixdMask(i, blendMask); \
- }
- MixdMasks(0, blendMask[0].r);
- #ifndef _LAYERS_ONE
- MixdMasks(1, blendMask[0].g);
- #ifndef _LAYERS_TWO
- MixdMasks(2, blendMask[0].b);
- MixdMasks(3, blendMask[0].a);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- MixdMasks(4, blendMask[1].r);
- MixdMasks(5, blendMask[1].g);
- MixdMasks(6, blendMask[1].b);
- MixdMasks(7, blendMask[1].a);
- #endif
- #ifdef _LAYERS_SIXTEEN
- MixdMasks( 8, blendMask[2].r);
- MixdMasks( 9, blendMask[2].g);
- MixdMasks(10, blendMask[2].b);
- MixdMasks(11, blendMask[2].a);
- MixdMasks(12, blendMask[3].r);
- MixdMasks(13, blendMask[3].g);
- MixdMasks(14, blendMask[3].b);
- MixdMasks(15, blendMask[3].a);
- #endif
- #endif
- #endif
- return mixedMask;
- }
- void MaskWeight(inout float4 mask[_LAYER_COUNT], float4 mask_front[_LAYER_COUNT], float4 mask_side[_LAYER_COUNT], float4 blendMask[4], inout float3 triplanarWeights, float heightBlendingSharpness)
- {
- float splatWeight[_LAYER_COUNT];
- float3 heights = 0;
- splatWeight[0] = blendMask[0].r;
- #ifndef _LAYERS_ONE
- splatWeight[1] = blendMask[0].g;
- #ifndef _LAYERS_TWO
- splatWeight[2] = blendMask[0].b;
- splatWeight[3] = blendMask[0].a;
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- splatWeight[4] = blendMask[1].r;
- splatWeight[5] = blendMask[1].g;
- splatWeight[6] = blendMask[1].b;
- splatWeight[7] = blendMask[1].a;
- #endif
- #ifdef _LAYERS_SIXTEEN
- splatWeight[8] = blendMask[2].r;
- splatWeight[9] = blendMask[2].g;
- splatWeight[10] = blendMask[2].b;
- splatWeight[11] = blendMask[2].a;
- splatWeight[12] = blendMask[3].r;
- splatWeight[13] = blendMask[3].g;
- splatWeight[14] = blendMask[3].b;
- splatWeight[15] = blendMask[3].a;
- #endif
- #endif
- #endif
-
- for (int i = 0; i < _LAYER_COUNT; ++i)
- {
- mask[i] = (mask[i] * triplanarWeights.y) + (mask_front[i] * triplanarWeights.z) + (mask_side[i] * triplanarWeights.x);
-
- #if defined(_TERRAIN_BLEND_HEIGHT)
- if (_HeightmapBlending == 1)
- {
- heights += float3(mask_side[i].b, mask[i].b, mask_front[i].b) * splatWeight[i];
- }
- #endif
- }
- #if defined(_TERRAIN_BLEND_HEIGHT)
- if (_HeightmapBlending == 1)
- {
- triplanarWeights.rgb *= (1 / (1 * pow(2, (heights + triplanarWeights) * (-(heightBlendingSharpness)))) + 1) * 0.5;
- triplanarWeights.rgb /= (triplanarWeights.r + triplanarWeights.g + triplanarWeights.b);
- }
- #endif
- }
- float HeightSum(float4 mask[_LAYER_COUNT], float4 blendMask[4])
- {
- #ifdef _LAYERS_ONE
- return float(mask[0].b);
- #else
- float heightSum = dot(blendMask[0].rg, float2(mask[0].b, mask[1].b));
- #ifndef _LAYERS_TWO
- heightSum += dot(blendMask[0].ba, float2(mask[2].b, mask[3].b));
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- heightSum += dot(blendMask[1], float4(mask[4].b, mask[5].b, mask[6].b, mask[7].b));
- #endif
- #endif
- return heightSum;
- #endif
- }
- float4 TrackSplatValues(float4 blendMask[4], float4 trackSplats[_LAYER_COUNT])
- {
- #ifdef _LAYERS_ONE
- return trackSplats[0];
- #else
- float4 color = (blendMask[0].r * trackSplats[0])
- + (blendMask[0].g * trackSplats[1]);
- #ifndef _LAYERS_TWO
- color += (blendMask[0].b * trackSplats[2])
- + (blendMask[0].a * trackSplats[3]);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- color += (blendMask[1].r * trackSplats[4])
- + (blendMask[1].g * trackSplats[5])
- + (blendMask[1].b * trackSplats[6])
- + (blendMask[1].a * trackSplats[7]);
- #endif
- #ifdef _LAYERS_SIXTEEN
- color += (blendMask[2].r * trackSplats[8])
- + (blendMask[2].g * trackSplats[9])
- + (blendMask[2].b * trackSplats[10])
- + (blendMask[2].a * trackSplats[11])
- + (blendMask[3].r * trackSplats[12])
- + (blendMask[3].g * trackSplats[13])
- + (blendMask[3].b * trackSplats[14])
- + (blendMask[3].a * trackSplats[15]);
- #endif
- #endif
- return color;
- #endif
- }
- #define SpecularValueR(i) _Gamma ? _Specular##i.r : pow(abs(_Specular##i.r),1/2.2f);
- #define SpecularValueG(i) _Gamma ? _Specular##i.g : pow(abs(_Specular##i.g),1/2.2f);
- #define SpecularValueB(i) _Gamma ? _Specular##i.b : pow(abs(_Specular##i.b),1/2.2f);
- void UnpackTrackSplatValues(out float4 trackSplats[_LAYER_COUNT])
- {
- float value;
- int precision = 1024;
-
- #define trackSplat(i) value = SpecularValueR(i); \
- trackSplats[i].z = value % precision; \
- value = floor(value / precision); \
- trackSplats[i].x = value; \
- trackSplats[i] /= (precision - 1); \
- \
- trackSplats[i].y = (_DiffuseRemapOffset##i.w * 10.0f) % 1 ; \
- trackSplats[i].w = floor((_DiffuseRemapOffset##i.w % 1 ) * 10.0f); \
-
- trackSplat(0);
- #ifndef _LAYERS_ONE
- trackSplat(1);
- #ifndef _LAYERS_TWO
- trackSplat(2);
- trackSplat(3);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- trackSplat(4);
- trackSplat(5);
- trackSplat(6);
- trackSplat(7);
- #endif
- #ifdef _LAYERS_SIXTEEN
- trackSplat(8);
- trackSplat(9);
- trackSplat(10);
- trackSplat(11);
- trackSplat(12);
- trackSplat(13);
- trackSplat(14);
- trackSplat(15);
- #endif
- #endif
- #endif
- }
- void UnpackTrackSplatColor(out float4 trackSplatsColor[_LAYER_COUNT])
- {
- float color;
- float value;
- int precision = 1024;
- #define trackSplatColor(i) color = SpecularValueG(i) \
- \
- trackSplatsColor[i].y = color % precision; \
- color = floor(color / precision); \
- trackSplatsColor[i].x = color; \
- value = SpecularValueB(i); \
- trackSplatsColor[i].w = value % precision; \
- value = floor(value / precision); \
- trackSplatsColor[i].z = value % precision; \
- trackSplatsColor[i] /= (precision - 1); \
-
- trackSplatColor(0);
- #ifndef _LAYERS_ONE
- trackSplatColor(1);
- #ifndef _LAYERS_TWO
- trackSplatColor(2);
- trackSplatColor(3);
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- trackSplatColor(4);
- trackSplatColor(5);
- trackSplatColor(6);
- trackSplatColor(7);
- #endif
- #ifdef _LAYERS_SIXTEEN
- trackSplatColor(8);
- trackSplatColor(9);
- trackSplatColor(10);
- trackSplatColor(11);
- trackSplatColor(12);
- trackSplatColor(13);
- trackSplatColor(14);
- trackSplatColor(15);
- #endif
- #endif
- #endif
- }
- #ifdef _TERRAIN_BLEND_HEIGHT
- void HeightBlend(float4 mask[_LAYER_COUNT], inout float4 blendMask[4], float sharpness)
- {
- #ifdef _LAYERS_TWO
- float2 height = float2(mask[0].b, mask[1].b);
- blendMask[0].rg *= (1 / (pow(2, (height + blendMask[0].rg) * (-(sharpness)))) + 1) * 0.5;
- blendMask[0].rg /= (blendMask[0].r + blendMask[0].g);
- #else
- float4 height = float4 (mask[0].b, mask[1].b, mask[2].b, mask[3].b);
- blendMask[0].rgba *= (1 / (pow(2, (height + blendMask[0].rgba) * (-(sharpness)))) + 1) * 0.5;
- float heightSum = blendMask[0].r + blendMask[0].g + blendMask[0].b + blendMask[0].a;
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- float4 height1 = float4 (mask[4].b, mask[5].b, mask[6].b, mask[7].b);
- blendMask[1].rgba *= (1 / (pow(2, (height1 + blendMask[1].rgba) * (-(sharpness)))) + 1) * 0.5;
- heightSum += blendMask[1].r + blendMask[1].g + blendMask[1].b + blendMask[1].a;
-
- #ifdef _LAYERS_SIXTEEN
- float4 height2 = float4 (mask[8].b, mask[9].b, mask[10].b, mask[11].b);
- blendMask[2].rgba *= (1 / (pow(2, (height2 + blendMask[2].rgba) * (-(sharpness)))) + 1) * 0.5;
- heightSum += blendMask[2].r + blendMask[2].g + blendMask[2].b + blendMask[2].a;
-
- float4 height3 = float4 (mask[12].b, mask[13].b, mask[14].b, mask[15].b);
- blendMask[3].rgba *= (1 / (pow(2, (height3 + blendMask[3].rgba) * (-(sharpness)))) + 1) * 0.5;
- heightSum += blendMask[3].r + blendMask[3].g + blendMask[3].b + blendMask[3].a;
- blendMask[2].rgba /= heightSum;
- blendMask[3].rgba /= heightSum;
- #endif
- blendMask[1].rgba /= heightSum;
- #endif
- blendMask[0].rgba /= heightSum;
- #endif
- }
- #endif
- #ifndef _TERRAIN_BASEMAP_GEN
- void SampleSplatTOL(in out float4 mixedAlbedo, in out float3 mixedNormal, float2 uv[_LAYER_COUNT], float4 blendMask[4], float weight, float4 mask[_LAYER_COUNT])
- {
- float4 albedo[1];
- float3 normal[1];
- albedo[0] = float4(0, 0, 0, 0);
- normal[0] = float3(0, 0, 1);
- blendMask[0].r *= weight;
- UNITY_BRANCH if (blendMask[0].r > 1e-5f)
- {
- albedo[0] = SAMPLE_TEXTURE2D(_Splat0, SamplerState_Linear_Repeat, uv[0]);
- albedo[0].rgb *= DiffuseRemap(0).rgb;
- albedo[0].a = Smoothness(0).x;
- normal[0] = SampleNormals(0);
- }
- mixedAlbedo = (albedo[0] * blendMask[0].r);
- mixedNormal = (normal[0] * blendMask[0].r);
- }
- void SampleMaskTOL(out float4 mask[_LAYER_COUNT], float4 noTriplanarMask[_LAYER_COUNT], float2 uv[_LAYER_COUNT], float weight)
- {
- UNITY_BRANCH if (weight > 1e-5f)
- {
- mask[0] = Mask(0);
- mask[0] = RemapMask(0);
- }
- else
- {
- mask[0] = float4(0, 0, 0.5, 0);
- }
-
- mask[1] = noTriplanarMask[1];
- #ifndef _LAYERS_TWO
- mask[2] = noTriplanarMask[2];
- mask[3] = noTriplanarMask[3];
- #if defined(_LAYERS_EIGHT) || defined(_LAYERS_SIXTEEN)
- mask[4] = noTriplanarMask[4];
- mask[5] = noTriplanarMask[5];
- mask[6] = noTriplanarMask[6];
- mask[7] = noTriplanarMask[7];
- #endif
- #ifdef _LAYERS_SIXTEEN
- mask[8] = noTriplanarMask[8];
- mask[9] = noTriplanarMask[9];
- mask[10] = noTriplanarMask[10];
- mask[11] = noTriplanarMask[11];
- mask[12] = noTriplanarMask[12];
- mask[13] = noTriplanarMask[13];
- mask[14] = noTriplanarMask[14];
- mask[15] = noTriplanarMask[15];
- #endif
- #endif
- }
- #define TAU 6.283185307
- float random(in float2 st)
- {
- return frac(sin(dot(st.xy, float2(12.9898, 78.233))) * 43758.5453123);
- }
- float2 rotate_2d(float2 p_input, float p_theta)
- {
- float2x2 l_rot_matrix = float2x2(cos(p_theta), -sin(p_theta),
- sin(p_theta), cos(p_theta));
- return mul(l_rot_matrix, p_input);
- }
- float3 RainRipples(float2 uv, float scale, float rotation)
- {
- float3 normal = float3(0, 0, 1);
- uv.xy = rotate_2d(uv.xy, rotation);
- float2 sUV = (uv.xy * scale + scale * 0.1f);
- sUV.x += step(1.0f, (sUV.y % 2.0)) * 0.5f;
- float2 center = float2(0.5f, 0.5f);
- float size = 0.25f;
- float2 tile = floor(sUV);
- float2 fract = frac(sUV);
- float2 offset = (center - fract.xy) * size;
- float2 cUV = (fract - 0.5) / size + offset;
- float2 polarUV = float2(length(cUV), atan2(cUV.y, cUV.x));
- float time = _Time.x * scale * 3.0f;
- float radius = frac(time * 0.9f + (random(floor(sUV) + 5000.0).x)) * 1.25f;
- if (radius < 0.8f)
- {
- float thickness = min((size * 0.5f + 0.25f) * 0.4f, radius);
- float start = radius + thickness;
- float end = max(0., radius - thickness);
- if (radius > 0.15)
- {
- thickness *= (0.9 - (radius * 0.9f));
- }
- float radius2 = radius - thickness * 1.25f;
- float cAngle = smoothstep(start, end, polarUV.x) * PI;
- float start2 = radius2 + thickness;
- float end2 = max(0., radius2 - thickness);
- float cAngle2 = smoothstep(start2, end2, polarUV.x) * PI;
- float rippleMask = smoothstep(thickness, -0.1f, abs(polarUV.x - radius));
- float rippleMask2 = smoothstep(thickness, -0.1f, abs(polarUV.x - radius2));
- float decayMask = min(1., max(0., 1. - polarUV.x));
- cAngle = lerp(cAngle, PI * 0.5f, (1.0f - rippleMask * decayMask));
- cAngle2 = lerp(cAngle2, PI * 0.5f, (1.0f - rippleMask2 * decayMask));
- float c = lerp(cos(cAngle), cos(cAngle2), 0.5f);
- #if defined(INTERRA_OBJECT) || defined(INTERRA_MESH_TERRAIN)
- normal = float3(c * sin(polarUV.y), c * cos(polarUV.y), sin(cAngle));
- #else
- normal = float3(c * sin(polarUV.y) * -1, c * cos(polarUV.y) * -1, sin(cAngle));
- #endif
- float opacity = _InTerra_GlobalRaindropRipples.y;
- normal.xy = rotate_2d(normal.xy, rotation) * (opacity - (radius * opacity));
- }
- return normal;
- }
- #endif
- #endif
- #ifdef INTERRA_OBJECT
- float ObjectTerrainIntersection(float3 worldNormal, float TerrainHeightOffset, float4 mask[_LAYER_COUNT], float4 blendMask[4], float objectHeightMap, float sharpness)
- {
- float steepWeights = _SteepIntersection == 1 ? saturate(worldNormal.y + _Steepness) : 1;
- float intersect1 = smoothstep(_Intersection.y, _Intersection.x, TerrainHeightOffset) * steepWeights;
- float intersect2 = smoothstep(_Intersection2.y, _Intersection2.x, TerrainHeightOffset) * (1 - steepWeights);
- float intersection = intersect1 + intersect2;
- float heightSum;
- #ifdef _TERRAIN_BLEND_HEIGHT
- heightSum = lerp(HeightSum(mask, blendMask), 1, intersection);
- #else
- heightSum = 0.5;
- #endif
- float2 heightIntersect = (1 / (1 * pow(2, float2(((1 - intersection) * objectHeightMap), (intersection * heightSum)) * (-(sharpness)))) + 1) * 0.5;
- heightIntersect /= (heightIntersect.r + heightIntersect.g);
- return heightIntersect.x;
- }
- #endif
|