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....