How to perfectly align combined 2D and 3D graphics?

I need a loose replication of this plot from Wikipedia. My best attempt so far seems to have some unwanted padding around the vector plot, on the bottom layer. Am I missing anything to properly align the two coordinate systems? Is there an alternative implementation?

Define a potential field and its gradient:

f = Function[{x, y}, -(Cos^2 + Cos^2)^2];
g = Function[{x, y}, Evaluate@D[f[x, y], {{x, y}}]];

Make 2D plot for the texture

tx = VectorDensityPlot[g[x, y], {x, -Pi/2, Pi/2}, {y, -Pi/2, Pi/2}, 
          Frame -> False, PlotRangePadding -> None,   ColorFunction -> "DarkRainbow", VectorPoints -> 30]

Combine 3D filed plot with 2D vector plot of its gradient via texture

Show[Plot3D[f[x, y], {x, -Pi/2, Pi/2}, {y, -Pi/2, Pi/2},
          ColorFunction -> "DarkRainbow", PlotStyle -> Opacity[.8], MeshStyle -> Opacity[.3]], 
     Graphics3D[{Texture[tx], 
                  Polygon[{{-Pi/2, -Pi/2, -4}, {Pi/2, -Pi/2, -4}, {Pi/2, Pi/2, -4}, {-Pi/2, Pi/2, -4}}, 
                  VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]},   Lighting -> "Neutral"]]

Adding PlotRange → All to VectorPlot gets rid of the padding. I’m not quite sure why PlotRange → Full adds the padding. I would expect the padding for the arrowheads to be controlled by ImagePadding so that

Graphics[{Arrowheads[.2], Arrow[{{0, 0}, {1, 0}, {1, 1}}]}]

wouldn’t clip the arrowhead.

How about a different approach, not using Texture. We can extract graphics primitives from VectorPlot and put them literally in the same coordinate system used by Plot3D. This guarantees perfect alignment.

Show[Plot3D[f[x, y], {x, -Pi/2, Pi/2}, {y, -Pi/2, Pi/2},   
         PlotStyle -> FaceForm[],   MeshStyle -> Directive[Red, Thick, Opacity[.5]],BoundaryStyle->None],  
    Graphics3D[{Arrowheads[Small], Blue, Arrow@PadRight[#, {Length@#, 2, 3}, -4.] &@
         Cases[VectorPlot[g[x, y], {x, -Pi/2, Pi/2}, {y, -Pi/2, Pi/2}, VectorPoints -> 20], 
                Arrow[l_] :> l, -1]}], Boxed -> False]