Ensapra

Untitled

Mar 31st, 2026 (edited)
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.42 KB | Source Code | 0 0
  1. [BurstCompile(FloatPrecision.Standard, FloatMode.Fast, CompileSynchronously = true)]
  2. public struct FakeErosionJob : IJobParallelFor
  3. {
  4.     [ReadOnly] HeightData inputData;
  5.     [ReadOnly] GridData gridData;
  6.     [ReadOnly] NormalMapData normalMapData;
  7.  
  8.     [WriteOnly] NativeArray<float> targetMap;
  9.     [WriteOnly] NativeArray<float> targetStreams;
  10.  
  11.     ResolutionAndLength outputIndex;
  12.  
  13.     float Persistance;
  14.     float Size;
  15.     int Octaves;
  16.     float Lacunarity;
  17.     float Strength;
  18.     float DetailStrength;
  19.     int StreamMaxOctave;
  20.  
  21.     public void Execute(int i)
  22.     {
  23.         float3 position = gridData.GetWorldPosition(i, outputIndex.Resolution) / Size;
  24.         float3 normal = normalMapData.GetNormal(i, outputIndex.Resolution);
  25.         float noise = inputData.GetValue(i, outputIndex.Resolution);
  26.  
  27.         float2 dir = math.normalize(normal.zx * new float2(1.0f, -1.0f));
  28.         float slope = math.saturate(math.acos(normal.y) * 0.636f);
  29.         float erosionMask = ease_out(slope*1.25f);
  30.  
  31.         float dist = inputData.minMaxValue.y - inputData.minMaxValue.x;
  32.         float fadeTarget =
  33.             JobTools.invLerp(
  34.                 inputData.minMaxValue.x + dist * 0.2f,
  35.                 inputData.minMaxValue.y - dist * 0.2f,
  36.                 noise
  37.             ) * 2.0f - 1.0f;
  38.  
  39.         float3 erosion = 0;
  40.         float a = 0.5f;
  41.         float f = 1.0f;
  42.  
  43.         float ridgeFadeTarget = fadeTarget;
  44.         float ridgeMask = ease_out(slope*2.8f);
  45.  
  46.         for (int e = 0; e < Octaves; e++)
  47.         {
  48.             var perpendicular = math.normalize(dir + erosion.zy * new float2(-1.0f, 1.0f));
  49.             float2 erodedValue = ErosionField(position.xz * f, perpendicular) * new float2(1.0f, f);
  50.  
  51.             float2 trueFade = math.lerp(new float2(fadeTarget, 0), erodedValue, erosionMask);
  52.             float3 newErosion = new float3(trueFade.x, (-trueFade.y) * perpendicular);
  53.             erosion += newErosion * a;
  54.  
  55.             float newSlope = ease_out(math.abs(erodedValue.y) * 1.25f);
  56.             erosionMask = pow_inv(erosionMask, DetailStrength) * math.saturate(newSlope);
  57.             fadeTarget = trueFade.x;
  58.  
  59.             a *= Persistance;
  60.             f *= Lacunarity;
  61.  
  62.             if(e >= StreamMaxOctave) continue;
  63.             ridgeFadeTarget = math.lerp(ridgeFadeTarget, erodedValue.x, ridgeMask);
  64.             float ridgeNewSlope = ease_out(math.abs(erodedValue.y) * 1.5f);
  65.             ridgeMask *= ridgeNewSlope;
  66.         }
  67.  
  68.         targetMap[i] = noise + (erosion.x - 0.5f) * Strength;
  69.         targetStreams[i] = math.saturate((ridgeFadeTarget * (1.0f - ridgeMask)+1.0f)/2.0f);
  70.     }
  71.     float ease_out(float t) {
  72.         float v = 1.0f - math.saturate(t);
  73.         return 1.0f - v * v;
  74.     }
  75.     float pow_inv(float t, float power) => 1.0f - math.pow(1.0f - math.saturate(t), power);
  76.     float2 ErosionField(float2 position, float2 flowDirection)
  77.     {
  78.         const float tau = 2.0f * math.PI;
  79.         float2 cellPosition = math.floor(position);
  80.         float2 relativeFraction = math.frac(position);
  81.  
  82.         float2 acomulatedErosion = 0;
  83.         float totalWeight = 0;
  84.  
  85.         for (int i = -2; i <= 1; i++)
  86.         {
  87.             for (int j = -2; j <= 1; j++)
  88.             {
  89.                 float2 nearOrigin = new float2(i, j);
  90.                 float2 offset = hash(cellPosition - nearOrigin) * 0.5f;
  91.                 float2 vectorToOrigin = relativeFraction + nearOrigin - offset;
  92.  
  93.                 float sqlength = math.dot(vectorToOrigin, vectorToOrigin);
  94.                 float weight = math.exp(-sqlength * 2.0f);
  95.                 totalWeight += weight;
  96.  
  97.                 float phase = math.dot(vectorToOrigin, flowDirection);
  98.                 float angle = phase * tau;
  99.  
  100.                 math.sincos(angle, out float sin, out float cos);
  101.                 acomulatedErosion += new float2(cos, sin) * weight;
  102.             }
  103.         }
  104.  
  105.         float2 result = acomulatedErosion / totalWeight;
  106.  
  107.         float len = math.length(result);
  108.         float clampedLen = math.min(len * 2.0f, 1.0f);
  109.         result = result * math.select(0.0f, 1.0f / len, len > 1e-5f) * clampedLen;
  110.         return result;
  111.     }
  112.  
  113.     float2 hash(in float2 xIn)
  114.     {
  115.         float2 k = new float2(0.3183099f, 0.3678794f);
  116.         float2 x = xIn * k + k.yx;
  117.         return -1.0f + 2.0f *
  118.             math.frac(16.0f * k *
  119.             math.frac(x.x * x.y * (x.x + x.y)));
  120.     }
  121.  
  122.     public static JobHandle Schedule(
  123.         HeightData inputData,
  124.         GridData gridData,
  125.         NormalMapData normalMapData,
  126.         NativeArray<float> targetMap, NativeArray<float> targetStreams,
  127.         ResolutionAndLength outputIndex,
  128.         float Persistance, float Size, int Octaves, float Lacunarity,
  129.         float Strength, float DetailStrength, int StreamMaxOctave, JobHandle dependency)
  130.         => new FakeErosionJob(){
  131.             inputData = inputData,
  132.             gridData = gridData,
  133.             normalMapData = normalMapData,
  134.             targetMap = targetMap,
  135.             targetStreams = targetStreams,
  136.             outputIndex = outputIndex,
  137.  
  138.             Persistance = Persistance,
  139.             Strength = Strength,
  140.             Size = Size,
  141.             Octaves = Octaves,
  142.             Lacunarity = Lacunarity,
  143.             DetailStrength = DetailStrength,
  144.             StreamMaxOctave = StreamMaxOctave < 0 ? Octaves : StreamMaxOctave,
  145.         }.Schedule(outputIndex.MapLength, outputIndex.Resolution, dependency);
  146. }
Advertisement
Add Comment
Please, Sign In to add comment