public override V3 GetNormal(V3 intersection = null)
        {
            V3 normal = Normal;

            if (!HasBump())
            {
                normal.Normalize();
                return(normal);
            }

            V3    AB = PointB - PointA;
            V3    AC = PointC - PointA;
            V3    AI = intersection - PointA;
            float u  = ((AC ^ Normal) * AI) / (AB ^ AC).Norm();
            float v  = ((Normal ^ AB) * AI) / (AC ^ AB).Norm();

            BumpTexture.Bump(u, v, out float dhdu, out float dhdv);
            V3 T2 = AB ^ (dhdv * normal);
            V3 T3 = (dhdu * normal) ^ AC;

            V3 normalBump = normal + (BumpIntensity * (T2 + T3));

            normalBump.Normalize();
            return(normalBump);
        }
        /// <summary>
        /// Calcul la normale a partir d une intersection
        /// A partir de cette intersection on va calculer u et v
        /// </summary>
        /// <param name="intersection">L intersection</param>
        /// <returns>La normal par rapport a l intersection</returns>
        public override V3 GetNormal(V3 intersection = null)
        {
            Tools.InvertCoordSpherique(FindSpherePoint(intersection), Radius, out float u, out float v);
            V3 normal = GetNormal(u, v);

            if (!HasBump())
            {
                normal.Normalize();
                return(normal);
            }

            float uTexture = u / Tools.TAU;
            float vTexture = -(v + Tools.PI2) / (Tools.PI2 + Tools.PI2);

            BumpTexture.Bump(uTexture, vTexture, out float dhdu, out float dhdv);
            V3 T2         = FindPointDerU(u, v) ^ (dhdv * normal);
            V3 T3         = (dhdu * normal) ^ FindPointDerV(u, v);
            V3 normalBump = normal + (BumpIntensity * (T2 + T3));

            normalBump.Normalize();
            return(normalBump);
        }