[MetalKit]39-Working-with-Particles-in-Metal粒子系統

蘋果API搬運工發表於2017-12-25

本系列文章是對 metalkit.org 上面MetalKit內容的全面翻譯和學習.

MetalKit系統文章目錄


今天,我們將開始一個新系列,關於Metal中的粒子系統.絕大多數時間,粒子都是小物體,我們總是不關心他們的幾何形狀.這讓他們適合於使用計算著色器,因為稍後我們將在粒子-粒子互動中使用粒度控制,這是一個用於展示通過計算著色器進行高度並行控制的例子.我們使用上一次的playground,就是從環境光遮蔽那裡開始.這個playground在這裡非常有用,因為它已經有一個CPU傳遞到GPUtime變數.我們從一個新的Shader.metal檔案開始,給一個漂亮的背景色:

#include <metal_stdlib>
using namespace metal;

kernel void compute(texture2d<float, access::write> output [[texture(0)]],
                    constant float &time [[buffer(0)]],
                    uint2 gid [[thread_position_in_grid]]) {
    int width = output.get_width();
    int height = output.get_height();
    float2 uv = float2(gid) / float2(width, height);
    output.write(float4(0.2, 0.5, 0.7, 1), gid);
}
複製程式碼

接著,讓我們建立一個粒子物件,只包含一個位置(中心)和半徑:

struct Particle {
    float2 center;
    float radius;
};
複製程式碼

我們還需要一個方法來獲取粒子在螢幕上的位置,那讓我們建立一個距離函式:

float distanceToParticle(float2 point, Particle p) {
    return length(point - p.center) - p.radius;
}
複製程式碼

在核心中,在最後一行上面,讓我們一個新的粒子並將其放置在螢幕頂部,X軸中間.設定半徑為0.05:

float2 center = float2(0.5, time);
float radius = 0.05;
Particle p = Particle{center, radius};
複製程式碼

注意:我們使用time作為粒子的Y座標,但這只是一個顯示基本運動的小技巧.很快,我們將用符合物理法則的座標來替換這個變數.

用下面程式碼替換核心的最後一行,並執行app.你會看到粒子以固定速率掉落:

float distance = distanceToParticle(uv, p);
float4 color = float4(1, 0.7, 0, 1);
if (distance > 0) { color = float4(0.2, 0.5, 0.7, 1); }
output.write(float4(color), gid);
複製程式碼

然而,這個粒子將永遠朝下運動.為了讓它停在底部,在建立粒子之前使用下面的條件:

float stop = 1 - radius;
if (time >= stop) { center.y = stop; }
else center.y = time;
複製程式碼

注意:timeuv變數都在0-1範圍內變化,這樣我們就建立一個stop點,它就在螢幕正方邊緣一個粒子半徑的位置.

這是一個非常基本的碰撞檢測規則.如果你執行app,你將會看到粒子掉落並停上底部,像這樣:

particle.gif

下次,我們將更深入粒子動態效果,並實現物理運動法則.

原始碼source code已釋出在Github上.

下次見!

相關文章