// A standard square grid 2D blobby Truchet routine: Render circles // in opposite corners of a tile, reverse the pattern on alternate // checker tiles, and randomly rotate. private static float Truchet(Float2 p) { const float sc = 0.5f; Float2 ip = Hlsl.Floor(p / sc) + 0.5f; p -= ip * sc; float rnd = Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(ip, new Float2(1, 113))) * 45758.5453f); if (rnd < .5) { p.Y = -p.Y; } float d = Hlsl.Min(Distance(p - 0.5f * sc), Distance(p + 0.5f * sc)) - 0.5f * sc; if (SHAPE == 4) { d += (0.5f - 0.5f / Hlsl.Sqrt(2.0f)) * sc; } if (rnd < 0.5f) { d = -d; } if (Mod(ip.X + ip.Y, 2.0f) < 0.5f) { d = -d; } return(d - 0.03f); }
// float2 to float2 hash. private float2 Hash22(float2 p) { float n = Hlsl.Sin(Hlsl.Dot(p, new float2(1, 113))); p = Hlsl.Frac(new float2(262144, 32768) * n); return(Hlsl.Sin(p * 6.2831853f + time)); }
public void Execute() { buffer[0] = DispatchSize.Count; buffer[1] = DispatchSize.X; buffer[2] = DispatchSize.Y; buffer[3] = DispatchSize.Z; buffer[4] = (int)Hlsl.Dot(DispatchSize.XY, Float2.One); buffer[5] = (int)Hlsl.Dot(DispatchSize.XYZ, Float3.One); }
public void Execute() { buffer[0] = GroupSize.X; buffer[1] = GroupSize.Y; buffer[2] = GroupSize.Z; buffer[3] = GroupSize.Count; buffer[4] = (int)Hlsl.Dot(GroupSize.XY, float2.One); buffer[5] = (int)Hlsl.Dot(GroupSize.XYZ, float3.One); }
/// <summary> /// Makes some magic happen. /// </summary> private float4 Tex(float3 p) { float t = time + 78.0f; float4 o = new(p.X, p.Y, p.Z, 3.0f * Hlsl.Sin(t * 0.1f)); float4 dec = new float4(1.0f, 0.9f, 0.1f, 0.15f) + new float4(0.06f * Hlsl.Cos(t * 0.1f), 0, 0, 0.14f * Hlsl.Cos(t * 0.23f)); for (int i = 0; i++ < NumberOfIterations;) { o.XZYW = Hlsl.Abs(o / Hlsl.Dot(o, o) - dec); } return(o); }
// Based on IQ's gradient noise formula. private float Noise2D3G(float2 p) { float2 i = Hlsl.Floor(p); p -= i; float4 v = default; v.X = Hlsl.Dot(Hash22(i), p); v.Y = Hlsl.Dot(Hash22(i + float2.UnitX), p - float2.UnitX); v.Z = Hlsl.Dot(Hash22(i + float2.UnitY), p - float2.UnitY); v.W = Hlsl.Dot(Hash22(i + 1.0f), p - 1.0f); p = p * p * p * (p * (p * 6.0f - 15.0f) + 10.0f); return(Hlsl.Lerp(Hlsl.Lerp(v.X, v.Y, p.X), Hlsl.Lerp(v.Z, v.W, p.X), p.Y)); }
// Smooth 2D noise private static float Noise2D(float2 p) { float2 i = Hlsl.Floor(p); p -= i; float4 v = default; v.X = Hlsl.Dot(Hash22B(i), p); v.Y = Hlsl.Dot(Hash22B(i + float2.UnitX), p - float2.UnitX); v.Z = Hlsl.Dot(Hash22B(i + float2.UnitY), p - float2.UnitY); v.W = Hlsl.Dot(Hash22B(i + 1.0f), p - 1.0f); p = p * p * (3.0f - 2.0f * p); return(Hlsl.Lerp(Hlsl.Lerp(v.X, v.Y, p.X), Hlsl.Lerp(v.Z, v.W, p.X), p.Y)); }
private static RayIntersection IntersectSphereWithRay(RenderableEntity entity, Ray ray) { // Create a line segment between the ray origin and the center of the sphere var line = entity.Position - ray.Origin; // Use line as a hypotenuse and find the length of the adjacent side var adjacent = Hlsl.Dot(line, ray.Direction); // Find the length-squared of the opposite side var length2 = Hlsl.Dot(line, line) - (adjacent * adjacent); // Determine the radius squared var radius2 = entity.Radius * entity.Radius; // If that length-squared is greater than radius squared, the ray doesn't interact the sphere if (length2 > radius2) { return(new RayIntersection()); } var thc = MathF.Sqrt(radius2 - length2); var t0 = adjacent - thc; var t1 = adjacent + thc; if (t0 < 0.0f && t1 < 0.0f) { return(new RayIntersection()); } // Determine the intersect distance var distance = t0 < t1 ? t0 : t1; #pragma warning disable IDE0017 // Simplify object initialization var rayIntersection = new RayIntersection(); rayIntersection.Intersecting = true; rayIntersection.Distance = distance; #pragma warning restore IDE0017 // Simplify object initialization return(rayIntersection); }
private static RayIntersection IntersectPlaneWithRay(RenderableEntity entity, Ray ray) { var denom = Hlsl.Dot(entity.Normal, ray.Direction); if (denom > 0.000001f) { var v = entity.Position - ray.Origin; var distance = Hlsl.Dot(v, entity.Normal) / denom; if (distance >= 0.0) { #pragma warning disable IDE0017 // Simplify object initialization var rayIntersection = new RayIntersection(); rayIntersection.Intersecting = true; rayIntersection.Distance = distance; #pragma warning restore IDE0017 // Simplify object initialization return(rayIntersection); } } return(new RayIntersection()); }
// Various distance metrics. private static float Distance(Float2 p) { if (SHAPE == 0) { return(Hlsl.Length(p)); } else { p = Hlsl.Abs(p); } switch (SHAPE) { case 1: return(Hlsl.Max(Hlsl.Length(p), (p.X + p.Y) * 0.7071f + 0.015f)); case 2: return(Hlsl.Max((p.X + p.Y) * 0.7071f, Hlsl.Max(p.X, p.Y))); case 3: return(Hlsl.Pow(Hlsl.Dot(Hlsl.Pow(p, 3), 1), 1.0f / 3.0f)); default: return((p.X + p.Y) * 0.7071f); } }
// Fast hash for a pair of floats static float Hash21(float2 p) { return(Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(p, new float2(27.619f, 57.583f))) * 43758.5453f)); }
// float2 to float2 hash. private static float2 Hash22B(float2 p) { float n = Hlsl.Sin(Hlsl.Dot(p, new float2(41, 289))); return(Hlsl.Frac(new float2(262144, 32768) * n) * 2.0f - 1.0f); }
// float3 to float hash. private static float Hash21(float2 p) { return(Hlsl.Frac(Hlsl.Sin(Hlsl.Dot(p, new float2(41, 289))) * 45758.5453f)); }