As far as I understand, perlin noise is made by creating a grid/lattice with some vertices $\mathbf v'$, choosing an arbitrary gradient vector $\mathbf{g_{v'}}$ over each vertex of the grid. To evaluate at a point $\mathbf x$ of space, we first compute the dot product of the "shift vector" $\mathbf x - \mathbf v$ from $\mathbf x$ to a vertex $\mathbf v$ of the cube/square of the grid containing $\mathbf x$. Then an interpolation is done over all the vertex of the cube containing $\mathbf x$, using an interpolation function $c_{\mathbf v}$ on the dot product $\big( \mathbf v - \mathbf x \big| \mathbf g_{\mathbf v} \big)$ that evaluates $0$ over all the other different vertices $\mathbf w \ne \mathbf v$ of the cube.
We end up with something like
$$ \mathrm{perlin}(\mathbf x) = \sum_{\mathbf v\in \mathrm{enclosing}(\mathbf x)} c_{\mathbf v}(\mathbf x) \cdot \big( \mathbf v - \mathbf x \big| \mathbf g_{\mathbf v} \big) $$
However I have trouble understanding why this algorithm gives so good results. If we evaluate the noise at a vertex point exactly, then the distance vector $\mathbf v - \mathbf x$ to that vertex is $0$ so the end result should be $0$, regardless of the value of the gradient $\mathbf g_{\mathbf v}$.
But when I look at a perlin noise, I dont' see a regular pattern of black areas in perlin noise, how is this possible ?
After testing a little bit more with Perlin noise, I realized it did have that grid of values at $0$, except that perlin noise actually yields negative values as well and the result is scaled to $[0,1]$, so the grid is actually not black (value $0$), but mid-grey (value $\frac{1}{2}$) which is much less noticeable.