BSplineFunction does not interpolate given points (control points), so of course the result is expected.

You can create a list of grid points like this:

spherePtsList = Flatten[Table[{i, j, spherePts[[i, j]]}, {i, 21}, {j, 21}], 1];

Now, create an interpolation function based on that:

f = Interpolation[spherePtsList]

Now, test:

In[2]:= Table[f[i, i] === spherePts[[i, i]], {i, 1, 21}]

Out[2]= {True, True, True, True, True, True, True, True, True, True,

True, True, True, True, True, True, True, True, True, True, True}

And graphics:

ParametricPlot3D[f[u, v], {u, 1, 21}, {v, 1, 21}]

You can reparametrize it to be between 0 and 1.

spherePtsList2 = Flatten[Table[N@{(i-1)/20,(j-1)/20,spherePts[[i,j]]},{i,21},{j,21}],1];

g=Interpolation[spherePtsList2]

Also, if you want to use B-spline, you can choose Method->"Spline" for the interpolation, but it may introduce a slight numerical error at the inpolation point (it will be equal (==) within machine precision, but not exactly the same (===)).

Besides, the same problem here... Can't copy-and-paste inside the M- box....