Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- [BurstCompile(FloatPrecision.Standard, FloatMode.Fast, CompileSynchronously = true)]
- public struct FakeErosionJob : IJobParallelFor
- {
- [ReadOnly] HeightData inputData;
- [ReadOnly] GridData gridData;
- [ReadOnly] NormalMapData normalMapData;
- [WriteOnly] NativeArray<float> targetMap;
- [WriteOnly] NativeArray<float> targetStreams;
- ResolutionAndLength outputIndex;
- float Persistance;
- float Size;
- int Octaves;
- float Lacunarity;
- float Strength;
- float DetailStrength;
- int StreamMaxOctave;
- public void Execute(int i)
- {
- float3 position = gridData.GetWorldPosition(i, outputIndex.Resolution) / Size;
- float3 normal = normalMapData.GetNormal(i, outputIndex.Resolution);
- float noise = inputData.GetValue(i, outputIndex.Resolution);
- float2 dir = math.normalize(normal.zx * new float2(1.0f, -1.0f));
- float slope = math.saturate(math.acos(normal.y) * 0.636f);
- float erosionMask = ease_out(slope*1.25f);
- float dist = inputData.minMaxValue.y - inputData.minMaxValue.x;
- float fadeTarget =
- JobTools.invLerp(
- inputData.minMaxValue.x + dist * 0.2f,
- inputData.minMaxValue.y - dist * 0.2f,
- noise
- ) * 2.0f - 1.0f;
- float3 erosion = 0;
- float a = 0.5f;
- float f = 1.0f;
- float ridgeFadeTarget = fadeTarget;
- float ridgeMask = ease_out(slope*2.8f);
- for (int e = 0; e < Octaves; e++)
- {
- var perpendicular = math.normalize(dir + erosion.zy * new float2(-1.0f, 1.0f));
- float2 erodedValue = ErosionField(position.xz * f, perpendicular) * new float2(1.0f, f);
- float2 trueFade = math.lerp(new float2(fadeTarget, 0), erodedValue, erosionMask);
- float3 newErosion = new float3(trueFade.x, (-trueFade.y) * perpendicular);
- erosion += newErosion * a;
- float newSlope = ease_out(math.abs(erodedValue.y) * 1.25f);
- erosionMask = pow_inv(erosionMask, DetailStrength) * math.saturate(newSlope);
- fadeTarget = trueFade.x;
- a *= Persistance;
- f *= Lacunarity;
- if(e >= StreamMaxOctave) continue;
- ridgeFadeTarget = math.lerp(ridgeFadeTarget, erodedValue.x, ridgeMask);
- float ridgeNewSlope = ease_out(math.abs(erodedValue.y) * 1.5f);
- ridgeMask *= ridgeNewSlope;
- }
- targetMap[i] = noise + (erosion.x - 0.5f) * Strength;
- targetStreams[i] = math.saturate((ridgeFadeTarget * (1.0f - ridgeMask)+1.0f)/2.0f);
- }
- float ease_out(float t) {
- float v = 1.0f - math.saturate(t);
- return 1.0f - v * v;
- }
- float pow_inv(float t, float power) => 1.0f - math.pow(1.0f - math.saturate(t), power);
- float2 ErosionField(float2 position, float2 flowDirection)
- {
- const float tau = 2.0f * math.PI;
- float2 cellPosition = math.floor(position);
- float2 relativeFraction = math.frac(position);
- float2 acomulatedErosion = 0;
- float totalWeight = 0;
- for (int i = -2; i <= 1; i++)
- {
- for (int j = -2; j <= 1; j++)
- {
- float2 nearOrigin = new float2(i, j);
- float2 offset = hash(cellPosition - nearOrigin) * 0.5f;
- float2 vectorToOrigin = relativeFraction + nearOrigin - offset;
- float sqlength = math.dot(vectorToOrigin, vectorToOrigin);
- float weight = math.exp(-sqlength * 2.0f);
- totalWeight += weight;
- float phase = math.dot(vectorToOrigin, flowDirection);
- float angle = phase * tau;
- math.sincos(angle, out float sin, out float cos);
- acomulatedErosion += new float2(cos, sin) * weight;
- }
- }
- float2 result = acomulatedErosion / totalWeight;
- float len = math.length(result);
- float clampedLen = math.min(len * 2.0f, 1.0f);
- result = result * math.select(0.0f, 1.0f / len, len > 1e-5f) * clampedLen;
- return result;
- }
- float2 hash(in float2 xIn)
- {
- float2 k = new float2(0.3183099f, 0.3678794f);
- float2 x = xIn * k + k.yx;
- return -1.0f + 2.0f *
- math.frac(16.0f * k *
- math.frac(x.x * x.y * (x.x + x.y)));
- }
- public static JobHandle Schedule(
- HeightData inputData,
- GridData gridData,
- NormalMapData normalMapData,
- NativeArray<float> targetMap, NativeArray<float> targetStreams,
- ResolutionAndLength outputIndex,
- float Persistance, float Size, int Octaves, float Lacunarity,
- float Strength, float DetailStrength, int StreamMaxOctave, JobHandle dependency)
- => new FakeErosionJob(){
- inputData = inputData,
- gridData = gridData,
- normalMapData = normalMapData,
- targetMap = targetMap,
- targetStreams = targetStreams,
- outputIndex = outputIndex,
- Persistance = Persistance,
- Strength = Strength,
- Size = Size,
- Octaves = Octaves,
- Lacunarity = Lacunarity,
- DetailStrength = DetailStrength,
- StreamMaxOctave = StreamMaxOctave < 0 ? Octaves : StreamMaxOctave,
- }.Schedule(outputIndex.MapLength, outputIndex.Resolution, dependency);
- }
Advertisement
Add Comment
Please, Sign In to add comment