Make erosion cell hashing cross-device deterministic
This commit is contained in:
parent
430cbc9695
commit
33c017b284
3 changed files with 22 additions and 8 deletions
|
|
@ -15,7 +15,10 @@ Rune Skovbo Johansen's **Advanced Terrain Erosion Filter**:
|
|||
The CultMath files retain the MPL notice and separate the faithful planar
|
||||
filter from CultMath's spherical adaptation. Modifications include C#/HLSL
|
||||
type lowering, explicit bounded octave counts, finite zero-rounding behavior,
|
||||
and CultMath naming.
|
||||
and CultMath naming. CultMath replaces the reference floating hash with a
|
||||
shared integer avalanche hash so C# and GPU evaluation select identical cell
|
||||
pivots across devices; this changes the stochastic pattern, not the filter
|
||||
mechanics.
|
||||
|
||||
The technique builds on earlier work credited by the upstream author to Fewes
|
||||
and Clay John. The hash form follows the public shader math of Inigo Quilez.
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@ struct CultMathAdvancedErosionResult
|
|||
float3 delta; float magnitude; float ridge_map; float fade_target;
|
||||
};
|
||||
|
||||
float cultmath_erosion_hash_unit(int2 cell, uint salt)
|
||||
{
|
||||
uint value = (uint)cell.x * 0x8da6b343u ^ (uint)cell.y * 0xd8163841u ^ salt;
|
||||
value ^= value >> 16; value *= 0x7feb352du; value ^= value >> 15; value *= 0x846ca68bu; value ^= value >> 16;
|
||||
return (value & 0x00ffffffu) * (1.0 / 16777216.0);
|
||||
}
|
||||
float2 cultmath_erosion_hash2(float2 input)
|
||||
{
|
||||
float2 k = float2(0.3183099, 0.3678794);
|
||||
float2 x = input * k + k.yx;
|
||||
return -1.0 + 2.0 * frac(16.0 * k * frac(x.x * x.y * (x.x + x.y)));
|
||||
int2 cell = (int2)input;
|
||||
return float2(cultmath_erosion_hash_unit(cell, 0x68bc21ebu), cultmath_erosion_hash_unit(cell, 0x02e5be93u)) * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
float4 cultmath_phacelle_noise(float2 position, float2 normal_direction, float frequency, float offset_cycles, float normalization)
|
||||
|
|
|
|||
|
|
@ -109,10 +109,16 @@ public static class AdvancedErosionFilter
|
|||
|
||||
private static float2 Hash2(float2 input)
|
||||
{
|
||||
var k = new float2(0.3183099f, 0.3678794f);
|
||||
var x = input * k + new float2(k.y, k.x);
|
||||
var scalar = math.frac(x.x * x.y * (x.x + x.y));
|
||||
return -float2.one + 2.0f * math.frac(16.0f * k * scalar);
|
||||
var x = (int)input.x;
|
||||
var y = (int)input.y;
|
||||
return new float2(HashUnit(x, y, 0x68bc21ebu), HashUnit(x, y, 0x02e5be93u)) * 2.0f - float2.one;
|
||||
}
|
||||
|
||||
private static float HashUnit(int x, int y, uint salt)
|
||||
{
|
||||
var value = unchecked((uint)x * 0x8da6b343u ^ (uint)y * 0xd8163841u ^ salt);
|
||||
value ^= value >> 16; value *= 0x7feb352du; value ^= value >> 15; value *= 0x846ca68bu; value ^= value >> 16;
|
||||
return (value & 0x00ffffffu) * (1.0f / 16777216.0f);
|
||||
}
|
||||
|
||||
private static float2 SafeNormalize(float2 value)
|
||||
|
|
|
|||
Reference in a new issue