Exemplo n.º 1
0
        Vector3 SampleVNDF(float r1, float r2)
        {
            // Rotate so UnitZ is up, and flip incoming to outgoing direction
            Normal3 up = Normal3.UnitZ;

            OpenTK.Mathematics.Quaternion rotation;
            if (Orientation == -up)
            {
                rotation = new OpenTK.Mathematics.Quaternion(Normal3.AnyPerpendicular(up).Vector, 0f);
            }
            else
            {
                rotation = new OpenTK.Mathematics.Quaternion(Vector3.Cross(Orientation.Vector, up.Vector), Vector3.Dot(Orientation.Vector, up.Vector) + 1f).Normalized();
            }
            Vector3 Ve = rotation * -IncomingDirection.Vector;

            // Section 3.2: transforming the view direction to the hemisphere configuration
            Vector3 Vh = new Vector3(Roughness * Ve.X, Roughness * Ve.Y, Ve.Z).Normalized();

            // Section 4.1: orthonormal basis (with special case if cross product is zero)
            float   lensq = Vh.X * Vh.X + Vh.Y * Vh.Y;
            Vector3 T1    = lensq > 0 ? new Vector3(-Vh.Y, Vh.X, 0) / (float)Math.Sqrt(lensq) : new Vector3(1f, 0f, 0f);
            Vector3 T2    = Vector3.Cross(Vh, T1);

            // Section 4.2: parameterization of the projected area
            float r   = (float)Math.Sqrt(r1);
            float phi = 2.0f * (float)Math.PI * r2;
            float t1  = r * (float)Math.Cos(phi);
            float t2  = r * (float)Math.Sin(phi);
            float s   = 0.5f * (1f + Vh.Z);

            t2 = (1f - s) * (float)Math.Sqrt(1f - t1 * t1) + s * t2;

            // Section 4.3: reprojection onto hemisphere
            Vector3 Nh = t1 * T1 + t2 * T2 + (float)Math.Sqrt(Math.Max(0f, 1f - t1 * t1 - t2 * t2)) * Vh;

            // Section 3.4: transforming the normal back to the ellipsoid configuration
            Vector3 Ne = new(Roughness * Nh.X, Roughness *Nh.Y, (float)Math.Max(0.0, Nh.Z));

            return(rotation.Inverted() * Ne);
        }
Exemplo n.º 2
0
 public static Quaternion ToNumeric(this OpenTK.Mathematics.Quaternion quaternion) => new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);