15.5. Derivative Operations

SPIR-V derivative instructions include OpDPdx, OpDPdy, OpDPdxFine, OpDPdyFine, OpDPdxCoarse, and OpDPdyCoarse. Derivative instructions are only available in a fragment shader.

Figure 15.3. Implicit Derivatives


Derivatives are computed as if there is a 2x2 neighborhood of fragments for each fragment shader invocation. These neighboring fragments are used to compute derivatives with the assumption that the values of P in the neighborhood are piecewise linear. It is further assumed that the values of P in the neighborhood are locally continuous, therefore derivatives in non-uniform control flow are undefined.

\begin{align*} dPdx_{i_1,j_0} & = dPdx_{i_0,j_0} & = P_{i_1,j_0} - P_{i_0,j_0} \\ dPdx_{i_1,j_1} & = dPdx_{i_0,j_1} & = P_{i_1,j_1} - P_{i_0,j_1} \\ \\ dPdy_{i_0,j_1} & = dPdy_{i_0,j_0} & = P_{i_0,j_1} - P_{i_0,j_0} \\ dPdy_{i_1,j_1} & = dPdy_{i_1,j_0} & = P_{i_1,j_1} - P_{i_1,j_0} \end{align*}

The Fine derivative instructions must return the values above, for a group of fragments in a 2x2 neighborhood. Coarse derivatives may return only two values. In this case, the values should be:

\begin{align*} dPdx & = \begin{cases} dPdx_{i_0,j_0} & \textrm{preferred}\\ dPdx_{i_0,j_1} \end{cases} \\ dPdy & = \begin{cases} dPdy_{i_0,j_0} & \textrm{preferred}\\ dPdy_{i_1,j_0} \end{cases} \end{align*}

OpDPdx and OpDPdy must return the same result as either OpDPdxFine or OpDPdxCoarse and either OpDPdyFine or OpDPdyCoarse, respectively. Implementations must make the same choice of either coarse or fine for both OpDPdx and OpDPdy, and implementations should make the choice that is more efficient to compute.