版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.10.09 星期二 |
前言
很多做視頻和圖像的,相信對這個框架都不是很陌生,它渲染高級3D圖形,并使用GPU執行數據并行計算。接下來的幾篇我們就詳細的解析這個框架。感興趣的看下面幾篇文章。
1. Metal框架詳細解析(一)—— 基本概覽
2. Metal框架詳細解析(二) —— 器件和命令(一)
3. Metal框架詳細解析(三) —— 渲染簡單的2D三角形(一)
4. Metal框架詳細解析(四) —— 關于GPU Family 4(一)
5. Metal框架詳細解析(五) —— 關于GPU Family 4之關于Imageblocks(二)
6. Metal框架詳細解析(六) —— 關于GPU Family 4之關于Tile Shading(三)
7. Metal框架詳細解析(七) —— 關于GPU Family 4之關于光柵順序組(四)
8. Metal框架詳細解析(八) —— 關于GPU Family 4之關于增強的MSAA和Imageblock采樣覆蓋控制(五)
9. Metal框架詳細解析(九) —— 關于GPU Family 4之關于線程組共享(六)
10. Metal框架詳細解析(十) —— 基本組件(一)
11. Metal框架詳細解析(十一) —— 基本組件之器件選擇 - 圖形渲染的器件選擇(二)
12. Metal框架詳細解析(十二) —— 基本組件之器件選擇 - 計算處理的設備選擇(三)
13. Metal框架詳細解析(十三) —— 計算處理(一)
14. Metal框架詳細解析(十四) —— 計算處理之你好,計算(二)
15. Metal框架詳細解析(十五) —— 計算處理之關于線程和線程組(三)
16. Metal框架詳細解析(十六) —— 計算處理之計算線程組和網格大小(四)
17. Metal框架詳細解析(十七) —— 工具、分析和調試(一)
18. Metal框架詳細解析(十八) —— 工具、分析和調試之Metal GPU Capture(二)
19. Metal框架詳細解析(十九) —— 工具、分析和調試之GPU活動監視器(三)
20. Metal框架詳細解析(二十) —— 工具、分析和調試之關于Metal著色語言文件名擴展名、使用Metal的命令行工具構建庫和標記Metal對象和命令(四)
21. Metal框架詳細解析(二十一) —— 基本課程之基本緩沖區(一)
22. Metal框架詳細解析(二十二) —— 基本課程之基本紋理(二)
23. Metal框架詳細解析(二十三) —— 基本課程之CPU和GPU同步(三)
24. Metal框架詳細解析(二十四) —— 基本課程之參數緩沖 - 基本參數緩沖(四)
25. Metal框架詳細解析(二十五) —— 基本課程之參數緩沖 - 帶有數組和資源堆的參數緩沖區(五)
Argument Buffers with GPU Encoding - 具有GPU編碼的參數緩沖區
演示如何使用計算傳遞對參數緩沖區進行編碼,然后在后續渲染過程中訪問其參數。
在Argument Buffers with Arrays and Resource Heaps示例中,您學習了如何將參數緩沖區與資源和資源堆組合在一起。
在本示例中,您將學習如何使用圖形或計算函數將資源編碼為參數緩沖區。 特別是,您將學習如何從計算傳遞中將數據寫入參數緩沖區,然后在渲染過程中讀取該數據。 該示例呈現多個四元實例的網格,每個實例應用兩個紋理,其中紋理在四邊形內從左向右滑動,在四邊形之間從左向右移動。
Encode Data into Argument Buffers - 將數據編碼到參數緩沖區中
在初始化期間,樣本使用CPU將數據編碼到由SourceTextureArguments
結構定義的參數緩沖區中。
typedef struct SourceTextureArguments {
array<texture2d<float>, AAPLNumTextures> textures [[ id(AAPLArgumentBufferIDTextures) ]];
} SourceTextureArguments;
此參數緩沖區由_sourceTextures
緩沖區支持,可通過updateInstances
函數中的source_textures
變量進行訪問。source_textures
包含由樣本渲染器加載的紋理的引用數組。
在初始化之后,對于每個幀,樣本使用GPU將數據編碼到由InstanceArguments
結構定義的單獨的參數緩沖區中。
typedef struct InstanceArguments {
vector_float2 position;
texture2d<float> left_texture;
texture2d<float> right_texture;
} InstanceArguments;
此參數緩沖區由_instanceParameters
緩沖區支持,可通過updateInstances
,vertexShader
和fragmentShader
函數中的instance_params
變量進行訪問。 instance_params
是一個結構數組,其數據在計算傳遞中填充,然后通過實例化繪制調用在渲染過程中訪問。
Create an Array of Argument Buffer Structures - 創建一個參數緩沖區結構數組
該示例定義了一個InstanceArguments
結構,其中包含計算函數updateInstances
,對矢量和兩個紋理進行編碼。
typedef struct InstanceArguments {
vector_float2 position;
texture2d<float> left_texture;
texture2d<float> right_texture;
} InstanceArguments;
前一個參數緩沖區樣本使用encodedLength
屬性直接確定支持參數緩沖區結構的MTLBuffer
所需的大小。 但是,此示例需要為后續渲染過程渲染的每個四邊形提供此結構的一個實例。 因此,該示例將encodedLength
的值乘以實例總數,該實例總數由AAPLNumInstances
常量的值定義。
NSUInteger instanceParameterLength = instanceParameterEncoder.encodedLength * AAPLNumInstances;
_instanceParameters = [_device newBufferWithLength:instanceParameterLength options:0];
注意:
[[id(n)]]
屬性限定符不是在此示例中定義InstanceArguments
結構所必需的。 僅當通過Metal API
使用CPU對參數進行編碼時才需要此限定符,而不是在通過圖形或計算函數使用GPU對參數進行編碼時。
Encode an Argument Buffer with a Compute Function - 使用計算函數對參數緩沖區進行編碼
對于要渲染的每個四邊形,樣本執行updateInstances
計算函數以確定四邊形的位置和紋理。 樣本執行的計算過程遍歷instance_params
數組,并為每個四元組編碼正確的數據。 該示例通過在instanceID
索引值處設置數組元素中的InstanceArguments
值,將數據編碼為instance_params
。
device InstanceArguments & quad_params = instance_params[instanceID];
// Store the position of the quad
quad_params.position = position;
// Select and store the textures to apply to this quad
quad_params.left_texture = source_textures.textures[left_texture_index];
quad_params.right_texture = source_textures.textures[right_texture_index];
Render Instances with an Argument Buffer - 使用參數緩沖區渲染實例
該示例發出實例化繪制調用以呈現四邊形,同時產生最小量的CPU開銷。 將此技術與參數緩沖區相結合,允許樣本在同一個繪制調用中為每個四元組使用一組唯一的資源,其中每個實例繪制一個四元組。
該示例在頂點和片段函數的簽名中聲明了一個instanceID
變量。 渲染管道使用instanceID
索引到以前由updateInstances
計算函數編碼的instance_params
數組。
在頂點函數中,instanceID
被定義為具有[[instance_id]]
屬性限定符的參數。
vertex RasterizerData
vertexShader(uint vertexID [[ vertex_id ]],
uint instanceID [[ instance_id ]],
device AAPLVertex *vertices [[ buffer(AAPLVertexBufferIndexVertices) ]],
device InstanceArguments *instance_params [[ buffer(AAPLVertexBufferIndexInstanceParams) ]],
constant AAPLFrameState &frame_state [[ buffer(AAPLVertexBufferIndexFrameState) ]])
頂點函數從參數緩沖區中讀取位置數據,以在drawable
中的正確位置渲染四邊形。
float2 quad_position = instance_params[instanceID].position;
頂點函數然后通過RasterizerData
結構和[[stage_in]]
屬性限定符將instanceID
變量傳遞給fragment
函數。 (在fragment
函數中,通過in
參數訪問instanceID
。)
fragment float4
fragmentShader(RasterizerData in [[ stage_in ]],
device InstanceArguments *instance_params [[ buffer(AAPLFragmentBufferIndexInstanceParams) ]],
constant AAPLFrameState &frame_state [[ buffer(AAPLFragmentBufferIndexFrameState) ]])
片段函數從參數緩沖區中指定的兩個紋理中進行采樣,然后根據slideFactor
的值選擇輸出樣本。
texture2d<float> left_texture = instance_params[instanceID].left_texture;
texture2d<float> right_texture = instance_params[instanceID].right_texture;
float4 left_sample = left_texture.sample(texture_sampler, in.tex_coord);
float4 right_sample = right_texture.sample(texture_sampler, in.tex_coord);
if(frame_state.slideFactor < in.tex_coord.x)
{
output_color = left_sample;
}
else
{
output_color = right_sample;
}
片段函數輸出所選樣本。 左側紋理從左側滑入,右側紋理向右滑動。 在右紋理完全滑離四邊形之后,樣本將此紋理指定為下一個計算過程中的左紋理。 因此,每個紋理在四邊形網格上從左向右移動。
在此示例中,您學習了如何使用圖形或計算函數將資源編碼為參數緩沖區
后記
本篇主要講述了具有GPU編碼的參數緩沖區,感興趣的給個贊或者關注~~~