ArticlesScrapsPagesAbout

Vulkanの座標系

Vulkan 1.4.335 - A Specification (with all registered extensions) の中の座標系に関する部分をつまみ食いする。

パイプラインの一連の流れは「10. Pipelines」に書かれている。 パイプライン上の各シェーダはざっくり下のように構造化される:

  1. プリミティブ処理

    • Primitive Shading

      1. Vertex Shader

      2. Tessellation Control Shader (optimal)

      3. Tessellation Evaluation Shader (optimal)

      4. Geometry Shader (optimal)

    • Mesh Shading

      1. Task Shader (optimal)

      2. Mesh Shader

  2. フラグメント処理

    1. Fragment Shader

頂点処理終了時点の座標系はclip座標系である。 Clip座標系は3+1次元の同次座標系。 Clip座標を

(xcyczcwc)\begin{pmatrix}x_c\\y_c\\z_c\\w_c\end{pmatrix}

と表すと、view volumeは

wcxcwcwcycwczmzcwc\begin{gather*} -w_c \le x_c \le w_c\\ -w_c \le y_c \le w_c\\ z_m \le z_c \le w_c \end{gather*}

という制約に則る空間である(ただし、zmz_mはVulkanの拡張でwc-w_cにもできるが普通は0)。 さらに、このview volumeとユーザによって与えられたCullDistanceとの共通空間をclip volumeと言う。 このclip volume外のプリミティブは以降の処理で無視される[29.4. Primitive Clipping]。

ClipされたプリミティブはNDCに変換される。 NDCの座標は

(xdydzd)=(xc/wcyc/wczc/wc)\begin{pmatrix}x_d\\y_d\\z_d\end{pmatrix} = \begin{pmatrix}x_c/w_c\\y_c/w_c\\z_c/w_c\end{pmatrix}

である[29.7. Coordinate Transform]。

NDCは次のようにframebuffer coordinates (xf,yf)(x_f, y_f)と深度zfz_fに変換される(ビューポート変換):

xf=px2xd+oxyf=py2yd+oyzf=pzzd+oz\begin{gather*} x_f = \frac{p_x}{2}x_d + o_x\\ y_f = \frac{p_y}{2}y_d + o_y\\ z_f = p_z z_d + o_z \end{gather*}

ただし、vk::Viewport(x, y, width, height, minDepth, maxDepth)としたとき、

ox=x+width2oy=y+height2oz={minDepthif zm=0,minDepth+maxDepth2otherwise.px=widthpy=heightpz={maxDepthminDepthif zm=0,maxDepthminDepth2otherwise.\begin{align*} o_x &= \text{x} + \frac{\text{width}}{2}\\ o_y &= \text{y} + \frac{\text{height}}{2}\\ o_z &= \begin{cases} \text{minDepth} & \text{if $z_m = 0$,}\\ \frac{\text{minDepth} + \text{maxDepth}}{2} & otherwise. \end{cases}\\ p_x &= \text{width}\\ p_y &= \text{height}\\ p_z &= \begin{cases} \text{maxDepth} - \text{minDepth} & \text{if $z_m = 0$,}\\ \frac{\text{maxDepth} - \text{minDepth}}{2} & otherwise. \end{cases} \end{align*}

である[29.9. Controlling the Viewport]。

ここで注意すべきことは:

また、31.10. Depth Testによると、zfz_f[0,1][0, 1]に収まらない場合、次のようになる: