[MetalKit]Using MetalKit part 12 MetalKit 12使用

3730 ワード

このシリーズの文章は正しいです.http://metalkit.org 上のMetalKit内容の全面的な翻訳と学習.
MetalKitシステム記事ディレクトリ
前回第11部Part 11から、私たちの美しいフラクタルを処理し続けましょう.また、前回私たちが働いていたplaygroundを使って、私たちはそれをどのように生きているか、つまりアニメーションに変えるかを見ます.そのため、uniformsを使います.私たちは第5部Part 5で紹介しました.なぜこの例で役に立つのかをもう一度読みたいなら.
まず、MetalView.swiftファイルの上部に、timerというグローバル変数を作成し、データバッファで保存します.
var timer: Float = 0
var timerBuffer: MTLBuffer!

次に、registerShaders()でこのバッファを初期化します.
timerBuffer = device!.newBufferWithLength(sizeof(Float), options: [])

次に、カウント時間を増やし、バッファに新しい値を送信するupdate()関数を作成する必要があります.
func update() {
    timer += 0.01
    var bufferPointer = timerBuffer.contents()
    memcpy(bufferPointer, &timer, sizeof(Float))
}

次に、drawRect()で、現在のdrawableにテクスチャを設定する行の下で、タイマバッファをインデックスに設定する必要があります.次に、update関数を呼び出す必要があります.drawRect()はフレームごとに実行されるため、タイマ時間はフレーム数の変化に伴って増加します.
commandEncoder.setBuffer(timerBuffer, offset: 0, atIndex: 1)
update()

その後、Shaders.metalでは、タイマバッファを含むカーネル署名を更新する必要があります.
kernel void compute(texture2d output [[texture(0)]],
                    constant float &timer [[buffer(1)]],
                    uint2 gid [[thread_position_in_grid]])

一番面白い部分が来ました!次の行を行います.
float2 cc = 1.1*float2( 0.5*cos(0.1) - 0.25*cos(0.2), 0.5*sin(0.1) - 0.25*sin(0.2) );

置換:
float2 cc = 1.1*float2( 0.5*cos(0.1*timer) - 0.25*cos(0.2*timer), 0.5*sin(0.1*timer) - 0.25*sin(0.2*timer) );

Playgroundを実行すると、似たようなものが見えます.
chapter12_1.gif
簡単で面白いのではないでしょうか.マウスのインタラクションという重要で有用な特性を追加することもできます.明らかに、uniformsを使用します.MetalView類にNSWindowDelegateプロトコルを遵守させ、mouseの方法を使用することができます.
public class MetalView: MTKView, NSWindowDelegate {

次に、タイマーを参照して、マウスの位置(座標)を記録し、データバッファで保存するグローバル変数をposと名付けて作成します.mouseDown()メソッドを書き換えて座標を取得できます.
var mouseBuffer: MTLBuffer!
var pos: NSPoint!

override public func mouseDown(event: NSEvent) {
    pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil))
    let scale = layer!.contentsScale
    pos.x *= scale
    pos.y *= scale
}

ご覧のように、画面全体からMetalViewサイズまで座標をスケールし、ビューのレイヤから取得したスケールで座標を更新します.次に、registerShaders()関数でマウスバッファを初期化します.
mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: [])
update()関数に戻り、次の行を末尾に追加します.これにより、現在のマウス座標をバッファに送信できます.
bufferPointer = mouseBuffer.contents()
memcpy(bufferPointer, &pos, sizeof(NSPoint))

次に、drawRect()でマウスバッファをインデックス2に設定します.
commandEncoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2)

次に、Shaders.metalでカーネル署名をアップグレードしてマウスバッファを含みます.
kernel void compute(texture2d output [[texture(0)]],
                    constant float &timer [[buffer(1)]],
                    constant float2 &mouse [[buffer(2)]],
                    uint2 gid [[thread_position_in_grid]])

最後に、次の行を行います.
float3 color = float3( dmin.w );

この行に置換:
float3 color = float3(mouse.x - mouse.y);

ここでは色の計算方法を変更し、マウス座標をcolor変数に変更します.playgroundで実行し、可変ビュー領域をクリックして効果を観察します.出力された画像はこのように見えます.
chapter12_2.gif
コードの異なる位置にマウス座標を導入することで、カーネルコードをよりきれいにすることができる.また、NSPointはカーネルのfloat2タイプに完全に対応していない可能性があるという問題もある.
ソースコードsource codeはGithubに公開されています.また後で!