I am currently working on Shaders and since there is somehow no useful intrinsic perlin noise function, I decided to use This library or more specific the cnoise function. The problem is that this is indeed a noise function, but does not give the same results as Mathf.PerlinNoise(). I decided to rewrite that specific function in C# but I obviously made a mistake and because of that it does look neither like the cnoise() function nor the Mathf.PerlinNoise() function. I included the original code as comments at the right. Did I misinterpret an intrinsic function or made an other mistake?
static Vector4 Mod(Vector4 x, Vector4 y) // float4 mod(float4 x, float4 y)
{
return x - Mul(y, Floor(Div(x, y))); // return x - y * floor(x / y);
}
static Vector4 Floor(Vector4 a) // intrinsic function floor(x)
{
return new Vector4(Floor(a.x), Floor(a.y), Floor(a.z), Floor(a.w));
}
static float Floor(float f)
{
return Mathf.Floor(f);
}
static Vector4 Div(Vector4 x, Vector4 y) // component-wise division
{
return new Vector4(x.x / y.x, x.y / y.y, x.z / y.z, x.w / y.w);
}
static Vector4 Mul(Vector4 x, Vector4 y) // component-wise multiplication
{
return new Vector4(x.x * y.x, x.y * y.y, x.z * y.z, x.w * y.w);
}
static Vector4 Mod289(Vector4 v) // float4 mod289(float4 x)
{
return v - Floor(v / 289) * 289; // return x - floor(x / 289.0) * 289.0;
}
static Vector4 Permute(Vector4 v) // float4 permute(float4 x)
{
return Mul(Mod289(((v * 34.0f) + Vector4.one)), v); // return mod289(((x * 34.0) + 1.0) * x);
}
static Vector4 TaylorInvSqrt(Vector4 r) // float4 taylorInvSqrt(float4 r)
{
return Vector4.one * 1.79284291400159f
- r * 0.85373472095314f; // return (float4)1.79284291400159 - r * 0.85373472095314;
}
static Vector2 Fade(Vector2 t) // float2 fade(float2 t)
{
Vector2 t3 = Mul(Mul(t, t), t); // t*t*t
Vector4 u = Mul(t, t * 6.0f
- Vector2.one * 15.0f);// t*(t*6.0-15.0)
Vector2 s = new Vector2(u.x, u.y)
+ Vector2.one * 10.0f; // (t * (t * 6.0 - 15.0) + 10.0)
return Mul(t3, s);
// return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
}
static Vector4 Frac(Vector4 v) // intrinsic functino frac(x)
{
return v - Floor(v);
}
static Vector4 Abs(Vector4 v) // intrinsic function abs(x)
{
return new Vector4(Abs(v.x), Abs(v.y), Abs(v.z), Abs(v.w));
}
static float Abs(float f)
{
return Mathf.Abs(f);
}
static Vector2 Lerp(Vector2 a, Vector2 b, float f) // intrinsic function lerp(x, y, s)
{
return new Vector2(Mathf.Lerp(a.x, b.x, f), Mathf.Lerp(a.y, b.y, f));
}
public static float CNoise(Vector2 P)
{
Vector4 Pxyxy = new Vector4(P.x, P.y, P.x, P.y);
Vector4 Pi = Floor(Pxyxy) + new Vector4(0, 0, 1, 1); // float4 Pi = floor(P.xyxy) + float4(0.0, 0.0, 1.0, 1.0);
Vector4 Pf = Frac(Pxyxy) - new Vector4(0, 0, 1, 1); // float4 Pf = frac(P.xyxy) - float4(0.0, 0.0, 1.0, 1.0);
Pi = Mod289(Pi); // Pi = mod289(Pi);
Vector4 ix = new Vector4(Pi.x, Pi.z, Pi.x, Pi.z); // float4 ix = Pi.xzxz;
Vector4 iy = new Vector4(Pi.y, Pi.y, Pi.w, Pi.w); // float4 iy = Pi.yyww;
Vector4 fx = new Vector4(Pf.x, Pf.z, Pf.x, Pf.z); // float4 fx = Pf.xzxz;
Vector4 fy = new Vector4(Pf.y, Pf.y, Pf.w, Pf.w); // float4 fy = Pf.yyww;
Vector4 i = Permute(Permute(ix) + iy); // float4 i = permute(permute(ix) + iy);
Vector4 gx = Frac(i / 41.0f) * 2.0f - Vector4.one; // float4 gx = frac(i / 41.0) * 2.0 - 1.0;
Vector4 gy = Abs(gx) - 0.5f * Vector4.one; // float4 gy = abs(gx) - 0.5;
Vector4 tx = Floor(gx + 0.5f * Vector4.one); // float4 tx = floor(gx + 0.5);
gx = gx - tx; // gx = gx - tx;
Vector2 g00 = new Vector2(gx.x, gy.x); // float2 g00 = float2(gx.x, gy.x);
Vector2 g10 = new Vector2(gx.y, gy.y); // float2 g10 = float2(gx.y, gy.y);
Vector2 g01 = new Vector2(gx.z, gy.z); // float2 g01 = float2(gx.z, gy.z);
Vector2 g11 = new Vector2(gx.w, gy.w); // float2 g11 = float2(gx.w, gy.w);
Vector4 norm = TaylorInvSqrt(new Vector4(
Vector2.Dot(g00, g00),
Vector2.Dot(g01, g01),
Vector2.Dot(g10, g10),
Vector2.Dot(g11, g11))
); // float4 norm = taylorInvSqrt(float4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
g00 *= norm.x; // g00 *= norm.x;
g01 *= norm.y; // g01 *= norm.y;
g10 *= norm.z; // g10 *= norm.z;
g11 *= norm.w; // g11 *= norm.w;
float n00 = Vector2.Dot(g00, new Vector2(fx.x, fy.x)); // float n00 = dot(g00, float2(fx.x, fy.x));
float n10 = Vector2.Dot(g10, new Vector2(fx.y, fy.y)); // float n10 = dot(g10, float2(fx.y, fy.y));
float n01 = Vector2.Dot(g01, new Vector2(fx.z, fy.z)); // float n01 = dot(g01, float2(fx.z, fy.z));
float n11 = Vector2.Dot(g11, new Vector2(fx.w, fy.w)); // float n11 = dot(g11, float2(fx.w, fy.w));
Vector2 fade_xy = Fade(new Vector2(Pf.x, Pf.y)); // float2 fade_xy = fade(Pf.xy);
Vector2 n_x = Lerp(new Vector2(n00, n01),
new Vector2(n10, n11), fade_xy.x); // float2 n_x = lerp(float2(n00, n01), float2(n10, n11), fade_xy.x);
float n_xy = Mathf.Lerp(n_x.x, n_x.y, fade_xy.y); // float n_xy = lerp(n_x.x, n_x.y, fade_xy.y);
return 2.3f * n_xy; // return 2.3 * n_xy;
}