Metal框架詳細(xì)解析(四十一) —— Metal編程指南之圖形渲染:渲染命令編碼器之Part 1(六)

版本記錄

版本號 時(shí)間
V1.0 2018.11.10 星期六

前言

很多做視頻和圖像的,相信對這個(gè)框架都不是很陌生动猬,它渲染高級3D圖形啤斗,并使用GPU執(zhí)行數(shù)據(jù)并行計(jì)算。接下來的幾篇我們就詳細(xì)的解析這個(gè)框架赁咙。感興趣的看下面幾篇文章钮莲。
1. Metal框架詳細(xì)解析(一)—— 基本概覽
2. Metal框架詳細(xì)解析(二) —— 器件和命令(一)
3. Metal框架詳細(xì)解析(三) —— 渲染簡單的2D三角形(一)
4. Metal框架詳細(xì)解析(四) —— 關(guān)于GPU Family 4(一)
5. Metal框架詳細(xì)解析(五) —— 關(guān)于GPU Family 4之關(guān)于Imageblocks(二)
6. Metal框架詳細(xì)解析(六) —— 關(guān)于GPU Family 4之關(guān)于Tile Shading(三)
7. Metal框架詳細(xì)解析(七) —— 關(guān)于GPU Family 4之關(guān)于光柵順序組(四)
8. Metal框架詳細(xì)解析(八) —— 關(guān)于GPU Family 4之關(guān)于增強(qiáng)的MSAA和Imageblock采樣覆蓋控制(五)
9. Metal框架詳細(xì)解析(九) —— 關(guān)于GPU Family 4之關(guān)于線程組共享(六)
10. Metal框架詳細(xì)解析(十) —— 基本組件(一)
11. Metal框架詳細(xì)解析(十一) —— 基本組件之器件選擇 - 圖形渲染的器件選擇(二)
12. Metal框架詳細(xì)解析(十二) —— 基本組件之器件選擇 - 計(jì)算處理的設(shè)備選擇(三)
13. Metal框架詳細(xì)解析(十三) —— 計(jì)算處理(一)
14. Metal框架詳細(xì)解析(十四) —— 計(jì)算處理之你好,計(jì)算(二)
15. Metal框架詳細(xì)解析(十五) —— 計(jì)算處理之關(guān)于線程和線程組(三)
16. Metal框架詳細(xì)解析(十六) —— 計(jì)算處理之計(jì)算線程組和網(wǎng)格大斜怂(四)
17. Metal框架詳細(xì)解析(十七) —— 工具崔拥、分析和調(diào)試(一)
18. Metal框架詳細(xì)解析(十八) —— 工具、分析和調(diào)試之Metal GPU Capture(二)
19. Metal框架詳細(xì)解析(十九) —— 工具猿涨、分析和調(diào)試之GPU活動(dòng)監(jiān)視器(三)
20. Metal框架詳細(xì)解析(二十) —— 工具握童、分析和調(diào)試之關(guān)于Metal著色語言文件名擴(kuò)展名、使用Metal的命令行工具構(gòu)建庫和標(biāo)記Metal對象和命令(四)
21. Metal框架詳細(xì)解析(二十一) —— 基本課程之基本緩沖區(qū)(一)
22. Metal框架詳細(xì)解析(二十二) —— 基本課程之基本紋理(二)
23. Metal框架詳細(xì)解析(二十三) —— 基本課程之CPU和GPU同步(三)
24. Metal框架詳細(xì)解析(二十四) —— 基本課程之參數(shù)緩沖 - 基本參數(shù)緩沖(四)
25. Metal框架詳細(xì)解析(二十五) —— 基本課程之參數(shù)緩沖 - 帶有數(shù)組和資源堆的參數(shù)緩沖區(qū)(五)
26. Metal框架詳細(xì)解析(二十六) —— 基本課程之參數(shù)緩沖 - 具有GPU編碼的參數(shù)緩沖區(qū)(六)
27. Metal框架詳細(xì)解析(二十七) —— 高級技術(shù)之圖層選擇的反射(一)
28. Metal框架詳細(xì)解析(二十八) —— 高級技術(shù)之使用專用函數(shù)的LOD(一)
29. Metal框架詳細(xì)解析(二十九) —— 高級技術(shù)之具有參數(shù)緩沖區(qū)的動(dòng)態(tài)地形(一)
30. Metal框架詳細(xì)解析(三十) —— 延遲照明(一)
31. Metal框架詳細(xì)解析(三十一) —— 在視圖中混合Metal和OpenGL渲染(一)
32. Metal框架詳細(xì)解析(三十二) —— Metal渲染管道教程(一)
33. Metal框架詳細(xì)解析(三十三) —— Metal渲染管道教程(二)
34. Metal框架詳細(xì)解析(三十四) —— Hello Metal叛赚! 一個(gè)簡單的三角形的實(shí)現(xiàn)(一)
35. Metal框架詳細(xì)解析(三十五) —— Hello Metal澡绩! 一個(gè)簡單的三角形的實(shí)現(xiàn)(二)
36. Metal框架詳細(xì)解析(三十六) —— Metal編程指南之概覽(一)
37. Metal框架詳細(xì)解析(三十七) —— Metal編程指南之基本Metal概念(二)
38. Metal框架詳細(xì)解析(三十八) —— Metal編程指南之命令組織和執(zhí)行模型(三)
39. Metal框架詳細(xì)解析(三十九) —— Metal編程指南之資源對象:緩沖區(qū)和紋理(四)
40. Metal框架詳細(xì)解析(四十) —— Metal編程指南之函數(shù)和庫(五)

Graphics Rendering: Render Command Encoder - 圖形渲染:渲染命令編碼器

本章介紹如何創(chuàng)建和使用MTLRenderCommandEncoderMTLParallelRenderCommandEncoder對象,這些對象用于將圖形渲染命令編碼到命令緩沖區(qū)中俺附。 MTLRenderCommandEncoder命令描述圖形渲染管道肥卡,如圖5-1所示。

Figure 5-1 Metal Graphics Rendering Pipeline

MTLRenderCommandEncoder對象表示單個(gè)渲染命令編碼器事镣。 MTLParallelRenderCommandEncoder對象允許將單個(gè)呈現(xiàn)過程分解為多個(gè)單獨(dú)的MTLRenderCommandEncoder對象步鉴,每個(gè)對象可以分配給不同的線程。 然后將來自不同渲染命令編碼器的命令鏈接在一起并以一致,可預(yù)測的順序執(zhí)行氛琢,如 Multiple Threads for a Rendering Pass中所述喊递。


Creating and Using a Render Command Encoder - 創(chuàng)建和使用渲染命令編碼器

要?jiǎng)?chuàng)建,初始化和使用單個(gè)渲染命令編碼器:

1. Creating a Render Pass Descriptor - 創(chuàng)建渲染管道描述符

MTLRenderPassDescriptor對象表示編碼的渲染命令的目標(biāo)布疼,該命令是附件(attachments)的集合摊趾。渲染通道描述符的屬性可以包括用于顏色像素?cái)?shù)據(jù)的多達(dá)四個(gè)附件的陣列,一個(gè)附件用于深度像素?cái)?shù)據(jù)游两,以及一個(gè)附件用于模板像素?cái)?shù)據(jù)砾层。 renderPassDescriptor便捷方法使用默認(rèn)附件狀態(tài)創(chuàng)建具有顏色,深度和模板附件屬性的MTLRenderPassDescriptor對象贱案。 visibilityResultBuffer屬性指定設(shè)備可以更新的緩沖區(qū)肛炮,以指示是否有任何樣本通過深度和模板測試 - 有關(guān)詳細(xì)信息,請參閱Fixed-Function State Operations

每個(gè)單獨(dú)的附件侨糟,包括將要寫入的紋理鞭缭,由附件描述符表示刹衫。對于附件描述符,必須適當(dāng)?shù)剡x擇相關(guān)紋理的像素格式以存儲顏色,深度或模板數(shù)據(jù)墩瞳。對于顏色附件描述符MTLRenderPassColorAttachmentDescriptor,使用顏色可渲染像素格式览妖。對于深度附加描述符MTLRenderPassDepthAttachmentDescriptor瘾杭,使用深度可渲染像素格式,例如MTLPixelFormatDepth32Float汰具。對于模板附件描述符MTLRenderPassStencilAttachmentDescriptor卓鹿,使用模板可渲染像素格式,例如MTLPixelFormatStencil8留荔。

紋理實(shí)際上在設(shè)備上每個(gè)像素使用的內(nèi)存量并不總是與Metal框架代碼中紋理的像素格式的大小相匹配吟孙,因?yàn)樵O(shè)備添加了填充以用于對齊或其他目的。有關(guān)每種像素格式實(shí)際使用的內(nèi)存量以及附件大小和數(shù)量的限制聚蝶,請參閱Metal Feature Set Tables一章杰妓。

Load and Store Actions - 加載和存儲操作

附件描述符的loadActionstoreAction屬性指定在呈現(xiàn)過程的開始或結(jié)束時(shí)執(zhí)行的操作。 (對于MTLParallelRenderCommandEncoder碘勉,加載和存儲操作發(fā)生在整個(gè)命令的邊界巷挥,而不是每個(gè)MTLRenderCommandEncoder對象。有關(guān)詳細(xì)信息验靡,請參閱Multiple Threads for a Rendering Pass倍宾。)

可能的loadAction值包括:

如果您的應(yīng)用程序?qū)⒊尸F(xiàn)給定幀的附件的所有像??素埃元,請使用默認(rèn)加載操作MTLLoadActionDontCareMTLLoadActionDontCare操作允許GPU避免加載紋理的現(xiàn)有內(nèi)容牵啦,從而確保最佳性能亚情。否則,您可以使用MTLLoadActionClear操作清除附件的先前內(nèi)容哈雏,或使用MTLLoadActionLoad操作來保留它們楞件。 MTLLoadActionClear操作還可以避免加載現(xiàn)有紋理內(nèi)容衫生,但是會(huì)產(chǎn)生使用純色填充目標(biāo)的成本。

可能的storeAction值包括:

對于顏色附件,MTLStoreActionStore操作是默認(rèn)的存儲操作扶叉,因?yàn)閼?yīng)用程序幾乎總是在渲染過程結(jié)束時(shí)保留附件中的最終顏色值勿锅。對于深度和模板附件,MTLStoreActionDontCare是默認(rèn)的存儲操作枣氧,因?yàn)樵阡秩緜鬟f完成后通常不需要保留這些附件溢十。

Specifying the Clear Load Action - 指定Clear Load Action

如果附件描述符的loadAction屬性設(shè)置為MTLLoadActionClear,則在渲染過程開始時(shí)將清除值寫入指定附件描述符中的每個(gè)像素达吞。清除值屬性取決于附件的類型张弛。

Example: Creating a Render Pass Descriptor with Load and Store Actions - 示例:使用Load and Store Actions創(chuàng)建渲染通道描述符

Listing 5-1創(chuàng)建了一個(gè)帶有顏色和深度附件的簡單渲染過程描述符嫩与。 首先,創(chuàng)建兩個(gè)紋理對象交排,一個(gè)具有可顏色渲染的像素格式划滋,另一個(gè)具有深度像素格式。 接下來埃篓,MTLRenderPassDescriptorrenderPassDescriptor便捷方法創(chuàng)建默認(rèn)的渲染通道描述符处坪。 然后通過MTLRenderPassDescriptor的屬性訪問顏色和深度附件。 紋理和動(dòng)作在colorAttachments [0]中設(shè)置架专,它表示第一個(gè)顏色附件(在數(shù)組中的索引0處)和深度附件同窘。

Listing 5-1  Creating a Render Pass Descriptor with Color and Depth Attachments

MTLTextureDescriptor *colorTexDesc = [MTLTextureDescriptor
           texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
           width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
id <MTLTexture> colorTex = [device newTextureWithDescriptor:colorTexDesc];
 
MTLTextureDescriptor *depthTexDesc = [MTLTextureDescriptor
           texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float
           width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
id <MTLTexture> depthTex = [device newTextureWithDescriptor:depthTexDesc];
 
MTLRenderPassDescriptor *renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDesc.colorAttachments[0].texture = colorTex;
renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0,1.0,0.0,1.0);
 
renderPassDesc.depthAttachment.texture = depthTex;
renderPassDesc.depthAttachment.loadAction = MTLLoadActionClear;
renderPassDesc.depthAttachment.storeAction = MTLStoreActionStore;
renderPassDesc.depthAttachment.clearDepth = 1.0;

Example: Creating a Render Pass Descriptor for Multisampled Rendering - 示例:為多重采樣渲染創(chuàng)建渲染通道描述符

要使用MTLStoreActionMultisampleResolve操作,必須將texture屬性設(shè)置為多重采樣類型紋理部脚,resolveTexture屬性將包含多重采樣解析操作的結(jié)果想邦。 (如果texture不支持多重采樣,則多重采樣解析操作的結(jié)果未定義睛低。)resolveLevel案狠,resolveSliceresolveDepthPlane屬性也可用于多重采樣解析操作,以指定多重采樣紋理的mipmap級別钱雷,立方體切片和深度平面骂铁。在大多數(shù)情況下,resolveLevel罩抗,resolveSliceresolveDepthPlane的默認(rèn)值都是可用的拉庵。 在Listing 5-2中,最初創(chuàng)建了一個(gè)附件套蒂,然后將其loadAction钞支,storeActiontextureresolveTexture屬性設(shè)置為支持多重采樣解析操刀。

Listing 5-2  Setting Properties for an Attachment with Multisample Resolve

MTLTextureDescriptor *colorTexDesc = [MTLTextureDescriptor
           texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
           width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
id <MTLTexture> colorTex = [device newTextureWithDescriptor:colorTexDesc];
 
MTLTextureDescriptor *msaaTexDesc = [MTLTextureDescriptor
           texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
           width:IMAGE_WIDTH height:IMAGE_HEIGHT mipmapped:NO];
msaaTexDesc.textureType = MTLTextureType2DMultisample;
msaaTexDesc.sampleCount = sampleCount;  //  must be > 1
id <MTLTexture> msaaTex = [device newTextureWithDescriptor:msaaTexDesc];
 
MTLRenderPassDescriptor *renderPassDesc = [MTLRenderPassDescriptor renderPassDescriptor];
renderPassDesc.colorAttachments[0].texture = msaaTex;
renderPassDesc.colorAttachments[0].resolveTexture = colorTex;
renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve;
renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(0.0,1.0,0.0,1.0);

2. Using the Render Pass Descriptor to Create a Render Command Encoder - 使用渲染通道描述符創(chuàng)建渲染命令編碼器

在創(chuàng)建渲染過程描述符并指定其屬性后烁挟,使用MTLCommandBuffer對象的renderCommandEncoderWithDescriptor:方法創(chuàng)建渲染命令編碼器,如Listing 5-3所示骨坑。

Listing 5-3  Creating a Render Command Encoder with the Render Pass Descriptor

id <MTLRenderCommandEncoder> renderCE = [commandBuffer
                    renderCommandEncoderWithDescriptor:renderPassDesc];

Displaying Rendered Content with Core Animation - 使用Core Animation顯示渲染內(nèi)容

Core Animation定義了CAMetalLayer類撼嗓,該類專為使用Metal渲染內(nèi)容的圖層支持視圖的特殊行為而設(shè)計(jì)。 CAMetalLayer對象表示有關(guān)內(nèi)容幾何(位置和大谢锻佟)且警,其可視屬性(背景顏色,邊框和陰影)的信息礁遣,以及Metal用于在顏色附件中顯示內(nèi)容的資源斑芜。它還封裝了內(nèi)容呈現(xiàn)的時(shí)間,以便內(nèi)容可以在可用時(shí)或在指定時(shí)間顯示祟霍。有關(guān)Core Animation的更多信息杏头,請參閱Core Animation Programming Guide盈包。

Core Animation還為可顯示資源的對象定義了CAMetalDrawable協(xié)議。 CAMetalDrawable協(xié)議擴(kuò)展了MTLDrawable并提供了符合MTLTexture協(xié)議的對象大州,因此它可以用作渲染命令的目標(biāo)续语。要渲染到CAMetalLayer對象中,您應(yīng)該為每個(gè)渲染過程獲取一個(gè)新的CAMetalDrawable對象厦画,獲取它提供的MTLTexture對象疮茄,并使用該紋理創(chuàng)建顏色附件。與顏色附件(attachment)不同根暑,深度或模板附件的創(chuàng)建和破壞是昂貴的力试。如果需要深度或模板附件,請創(chuàng)建一次排嫌,然后在每次渲染幀時(shí)重復(fù)使用它們畸裳。

通常,您使用layerClass方法將CAMetalLayer指定為您自己的自定義UIView子類的支持層類型淳地,如Listing 5-4所示怖糊。否則,您可以使用其init方法創(chuàng)建CAMetalLayer颇象,并將該圖層包含在現(xiàn)有視圖中

Listing 5-4  Using CAMetalLayer as the backing layer for a UIView subclass

+ (id) layerClass {
    return [CAMetalLayer class];
}

要顯示圖層中Metal渲染的內(nèi)容伍伤,您必須從CAMetalLayer對象獲取可顯示資源(CAMetalDrawable對象),然后通過將其附加到MTLRenderPassDescriptor對象來渲染到此資源中的紋理遣钳。為此扰魂,首先設(shè)置描述其提供的可繪制資源的CAMetalLayer對象的屬性,然后在每次開始渲染新幀時(shí)調(diào)用其nextDrawable方法蕴茴。如果未設(shè)置CAMetalLayer屬性劝评,則nextDrawable方法調(diào)用將失敗。以下CAMetalLayer屬性描述了可繪制對象:

  • device屬性聲明從中創(chuàng)建資源的MTLDevice對象倦淀。
  • pixelFormat屬性聲明紋理的像素格式蒋畜。支持的值是MTLPixelFormatBGRA8Unorm(默認(rèn)值)和MTLPixelFormatBGRA8Unorm_sRGB
  • drawableSize屬性聲明設(shè)備像素中紋理的尺寸撞叽。要確保您的應(yīng)用以顯示的精確尺寸呈現(xiàn)內(nèi)容(在某些設(shè)備上無需額外的采樣階段)百侧,請?jiān)谟?jì)算圖層所需的大小時(shí)考慮目標(biāo)屏幕的nativeScalenativeBounds屬性。
  • framebufferOnly屬性聲明紋理是僅可用作附件(YES)還是也可用于紋理采樣和像素讀/寫操作(NO)能扒。如果是YES,則圖層對象可以優(yōu)化紋理以供顯示辫狼。對于大多數(shù)應(yīng)用初斑,建議值為YES。
  • presentsWithTransaction屬性聲明是否使用標(biāo)準(zhǔn)Core Animation事務(wù)機(jī)制(YES)更新圖層渲染資源的更改膨处,或者是否異步更新為常規(guī)圖層更新(NO见秤,默認(rèn)值)砂竖。

如果nextDrawable方法成功,則返回具有以下只讀屬性的CAMetalDrawable對象:

重要說明:只有一小部分可繪制資源置济,因此長幀渲染時(shí)間可能暫時(shí)耗盡這些資源并導(dǎo)致nextDrawable方法調(diào)用阻塞其CPU線程,直到方法完成锋八。為了避免昂貴的CPU停頓浙于,在調(diào)用CAMetalLayer對象的nextDrawable方法之前,執(zhí)行所有不需要可繪制資源的每幀操作挟纱。

要在渲染完成后顯示可繪制對象的內(nèi)容羞酗,必須通過調(diào)用drawable對象的present方法將其提交給Core Animation。要同步drawable的表示和完成負(fù)責(zé)其呈現(xiàn)的命令緩沖區(qū)紊服,可以在MTLCommandBuffer對象上調(diào)用presentDrawable:presentDrawable:atTime:便利方法檀轨。這些方法使用調(diào)度處理程序(請參閱Registering Handler Blocks for Command Buffer Execution)來調(diào)用drawablepresent方法,該方法涵蓋大多數(shù)方案欺嗤。 presentDrawable:atTime:方法提供了對drawable何時(shí)呈現(xiàn)的進(jìn)一步控制参萄。


Creating a Render Pipeline State - 創(chuàng)建渲染管道狀態(tài)

要使用MTLRenderCommandEncoder對象對渲染命令進(jìn)行編碼,必須首先指定MTLRenderPipelineState對象以定義任何繪制調(diào)用的圖形狀態(tài)剂府。 渲染管道狀態(tài)對象是一個(gè)長期存在的持久對象拧揽,可以在渲染命令編碼器之外創(chuàng)建,預(yù)先緩存腺占,并在多個(gè)渲染命令編碼器中重用淤袜。 在描述相同的圖形狀態(tài)集時(shí),重用先前創(chuàng)建的渲染管線狀態(tài)對象可以避免重新評估并將指定狀態(tài)轉(zhuǎn)換為GPU命令的昂貴操作衰伯。

渲染管道狀態(tài)是不可變對象铡羡。 要?jiǎng)?chuàng)建渲染管道狀態(tài),首先要?jiǎng)?chuàng)建并配置一個(gè)可變MTLRenderPipelineDescriptor對象意鲸,該對象描述渲染管道狀態(tài)的屬性烦周。 然后,使用描述符創(chuàng)建MTLRenderPipelineState對象怎顾。

1. Creating and Configuring a Render Pipeline Descriptor - 創(chuàng)建和配置渲染管道描述符

要?jiǎng)?chuàng)建渲染管道狀態(tài)读慎,首先要?jiǎng)?chuàng)建一個(gè)MTLRenderPipelineDescriptor對象,該對象具有描述在渲染過程中要使用的圖形渲染管道狀態(tài)的屬性槐雾,如圖5-2所示夭委。 新MTLRenderPipelineDescriptor對象的colorAttachments屬性包含一個(gè)MTLRenderPipelineColorAttachmentDescriptor對象數(shù)組,每個(gè)描述符表示一個(gè)顏色附加狀態(tài)募强,指定該附件的混合操作和因子株灸,詳見Configuring Blending in a Render Pipeline Attachment Descriptor崇摄。 附件描述符還指定附件的像素格式,該格式必須與渲染管道描述符的紋理的像素格式與相應(yīng)的附件索引匹配慌烧,否則會(huì)發(fā)生錯(cuò)誤逐抑。

Figure 5-2 Creating a Render Pipeline State from a Descriptor

除了配置顏色附件外,還要為MTLRenderPipelineDescriptor對象設(shè)置以下屬性:

  • 設(shè)置depthAttachmentPixelFormat屬性以匹配MTLRenderPassDescriptordepthAttachment紋理的像素格式屹蚊。
  • 設(shè)置stencilAttachmentPixelFormat屬性以匹配MTLRenderPassDescriptorstencilAttachment紋理的像素格式厕氨。
  • 要在渲染管道狀態(tài)中指定頂點(diǎn)或片段著色器,請分別設(shè)置vertexFunctionfragmentFunction屬性淑翼。將fragmentFunction設(shè)置為nil會(huì)禁用像素光柵化到指定的顏色附件腐巢,該附件通常用于僅深度渲染或用于從頂點(diǎn)著色器將數(shù)據(jù)輸出到緩沖區(qū)對象。
  • 如果頂點(diǎn)著色器具有帶有每頂點(diǎn)輸入屬性的參數(shù)玄括,請?jiān)O(shè)置vertexDescriptor屬性以描述該參數(shù)中頂點(diǎn)數(shù)據(jù)的組織冯丙,如Vertex Descriptor for Data Organization中所述。
  • 對于大多數(shù)典型的渲染任務(wù)遭京,rasterizationEnabled屬性的默認(rèn)值YES是足夠的胃惜。要僅使用圖形管道的頂點(diǎn)階段(例如,要收集在頂點(diǎn)著色器中轉(zhuǎn)換的數(shù)據(jù))哪雕,請將此屬性設(shè)置為NO船殉。
  • 如果附件支持多重采樣(即附件是MTLTextureType2DMultisample類型紋理),則可以為每個(gè)像素創(chuàng)建多個(gè)樣本斯嚎。要確定片段如何組合以提供像素覆蓋利虫,請使用以下MTLRenderPipelineDescriptor屬性。
    • sampleCount屬性確定每個(gè)像素的樣本數(shù)堡僻。創(chuàng)建MTLRenderCommandEncoder時(shí)糠惫,所有附件的紋理的sampleCount必須與此sampleCount屬性匹配。如果附件不支持多重采樣钉疫,則sampleCount為1硼讽,這也是默認(rèn)值。
    • 如果alphaToCoverageEnabled設(shè)置為YES牲阁,則讀取colorAttachments [0]alpha通道片段輸出并用于確定coverage掩碼固阁。
    • 如果alphaToOneEnabled設(shè)置為YES,則colorAttachments [0]的alpha通道片段值將強(qiáng)制為1.0城菊,這是最大的可表示值备燃。 (其他附件不受影響。)

2. Creating a Render Pipeline State from a Descriptor - 從描述符創(chuàng)建渲染管道狀態(tài)

在創(chuàng)建渲染管道描述符并指定其屬性后凌唬,使用它來創(chuàng)建MTLRenderPipelineState對象赚爵。因?yàn)閯?chuàng)建渲染管道狀態(tài)需要對圖形狀態(tài)進(jìn)行昂貴的評估以及可能編譯指定的圖形著色器,所以您可以使用阻塞或異步方法以最適合您的應(yīng)用程序設(shè)計(jì)的方式調(diào)度此類工作。

創(chuàng)建MTLRenderPipelineState對象時(shí),您還可以選擇創(chuàng)建反射數(shù)據(jù)讶隐,以顯示管道著色器函數(shù)及其參數(shù)的詳細(xì)信息起胰。newRenderPipelineStateWithDescriptor:options:reflection:error:newRenderPipelineStateWithDescriptor:options:completionHandler:提供此數(shù)據(jù)。 如果不使用反射數(shù)據(jù)巫延,請避免獲取反射數(shù)據(jù)效五。 有關(guān)如何分析反射數(shù)據(jù)的更多信息,請參閱Determining Function Details at Runtime炉峰。

創(chuàng)建MTLRenderPipelineState
對象后畏妖,調(diào)用MTLRenderCommandEncodersetRenderPipelineState:方法將渲染管道狀態(tài)與命令編碼器關(guān)聯(lián)以用于渲染。

Listing 5-5演示了如何創(chuàng)建一個(gè)名為pipeline的渲染管道狀態(tài)對象疼阔。

Listing 5-5  Creating a Simple Pipeline State

MTLRenderPipelineDescriptor *renderPipelineDesc =
                             [[MTLRenderPipelineDescriptor alloc] init];
renderPipelineDesc.vertexFunction = vertFunc;
renderPipelineDesc.fragmentFunction = fragFunc;
renderPipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
 
// Create MTLRenderPipelineState from MTLRenderPipelineDescriptor
NSError *errors = nil;
id <MTLRenderPipelineState> pipeline = [device
         newRenderPipelineStateWithDescriptor:renderPipelineDesc error:&errors];
assert(pipeline && !errors);
 
// Set the pipeline state for MTLRenderCommandEncoder
[renderCE setRenderPipelineState:pipeline];

變量vertFuncfragFunc是著色器函數(shù)戒劫,它們被指定為渲染管道狀態(tài)描述符的屬性,稱為renderPipelineDesc婆廊。 調(diào)用MTLDevice對象的newRenderPipelineStateWithDescriptor:error:的方法同步使用管道狀態(tài)描述符來創(chuàng)建渲染管道狀態(tài)對象迅细。 調(diào)用MTLRenderCommandEncodersetRenderPipelineState:方法指定要與渲染命令編碼器一起使用的MTLRenderPipelineState對象。

注意:因?yàn)?code>MTLRenderPipelineState對象的創(chuàng)建成本很高否彩,所以只要您想使用相同的圖形狀態(tài)疯攒,就應(yīng)該重復(fù)使用它。

3. Configuring Blending in a Render Pipeline Attachment Descriptor - 在渲染管道附件描述符中配置混合

Blending使用高度可配置的混合操作將片段函數(shù)(源)返回的輸出與附件(目標(biāo))中的像素值混合列荔【闯撸混合操作確定源和目標(biāo)值如何與混合因子組合。

要配置顏色附件的混合贴浙,請?jiān)O(shè)置以下MTLRenderPipelineColorAttachmentDescriptor屬性:

Understanding Blending Factors and Operations - 了解混合因子和操作

四個(gè)混合因子指的是恒定的混合顏色值:MTLBlendFactorBlendColor赎瑰,MTLBlendFactorOneMinusBlendColor王悍,MTLBlendFactorBlendAlphaMTLBlendFactorOneMinusBlendAlpha。 調(diào)用MTLRenderCommandEncodersetBlendColorRed:green:blue:alpha:方法餐曼,以指定與這些混合因子一起使用的常量顏色和alpha值压储,如Fixed-Function State Operations中所述。

某些混合操作通過將源值乘以源MTLBlendFactor值(縮寫為SBF)源譬,將目標(biāo)值乘以目標(biāo)混合因子(DBF)集惋,并使用MTLBlendOperation值指示的算法組合結(jié)果來組合片段值。 (如果混合操作是MTLBlendOperationMinMTLBlendOperationMax踩娘,則忽略SBFDBF混合因子刮刑。)例如,rgbBlendOperationalphaBlendOperation屬性的MTLBlendOperationAdd為RGB和Alpha值定義以下額外的混合操作:

RGB = (Source.rgb * sourceRGBBlendFactor) + (Dest.rgb * destinationRGBBlendFactor)
Alpha = (Source.a * sourceAlphaBlendFactor) + (Dest.a * destinationAlphaBlendFactor)

在默認(rèn)的混合行為中霸饲,源完全覆蓋目標(biāo)为朋。 此行為相當(dāng)于將sourceRGBBlendFactorsourceAlphaBlendFactor都設(shè)置為MTLBlendFactorOne,將destinationRGBBlendFactordestinationAlphaBlendFactor設(shè)置為MTLBlendFactorZero厚脉。 此行為在數(shù)學(xué)上表示為:

RGB = (Source.rgb * 1.0) + (Dest.rgb * 0.0)
A = (Source.a * 1.0) + (Dest.a * 0.0)

另一種常用的混合操作习寸,其中源alpha定義目標(biāo)顏色的剩余量,可以用數(shù)學(xué)方式表示為:

RGB = (Source.rgb * 1.0) + (Dest.rgb * (1 - Source.a))
A = (Source.a * 1.0) + (Dest.a * (1 - Source.a))

Using a Custom Blending Configuration - 使用自定義混合配置

Listing 5-6顯示了自定義混合配置的代碼傻工,使用混合操作MTLBlendOperationAdd霞溪,源混合因子MTLBlendFactorOne和目標(biāo)混合因子MTLBlendFactorOneMinusSourceAlphacolorAttachments [0]是一個(gè)MTLRenderPipelineColorAttachmentDescriptor對象中捆,其屬性指定混合配置

Listing 5-6  Specifying a Custom Blending Configuration

MTLRenderPipelineDescriptor *renderPipelineDesc = 
                             [[MTLRenderPipelineDescriptor alloc] init];
renderPipelineDesc.colorAttachments[0].blendingEnabled = YES; 
renderPipelineDesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
renderPipelineDesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
renderPipelineDesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne;
renderPipelineDesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
renderPipelineDesc.colorAttachments[0].destinationRGBBlendFactor = 
       MTLBlendFactorOneMinusSourceAlpha;
renderPipelineDesc.colorAttachments[0].destinationAlphaBlendFactor = 
       MTLBlendFactorOneMinusSourceAlpha;

NSError *errors = nil;
id <MTLRenderPipelineState> pipeline = [device 
         newRenderPipelineStateWithDescriptor:renderPipelineDesc error:&errors];

后記

本篇主要講述了圖形渲染:渲染命令編碼器鸯匹,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泄伪,隨后出現(xiàn)的幾起案子殴蓬,更是在濱河造成了極大的恐慌,老刑警劉巖蟋滴,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件染厅,死亡現(xiàn)場離奇詭異,居然都是意外死亡津函,警方通過查閱死者的電腦和手機(jī)肖粮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尔苦,“玉大人涩馆,你說我怎么就攤上這事行施。” “怎么了魂那?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵蛾号,是天一觀的道長。 經(jīng)常有香客問我涯雅,道長须教,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任斩芭,我火速辦了婚禮,結(jié)果婚禮上乐疆,老公的妹妹穿的比我還像新娘划乖。我一直安慰自己,他們只是感情好挤土,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布琴庵。 她就那樣靜靜地躺著,像睡著了一般仰美。 火紅的嫁衣襯著肌膚如雪迷殿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天咖杂,我揣著相機(jī)與錄音庆寺,去河邊找鬼。 笑死诉字,一個(gè)胖子當(dāng)著我的面吹牛懦尝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壤圃,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼陵霉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了伍绳?” 一聲冷哼從身側(cè)響起踊挠,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冲杀,沒想到半個(gè)月后效床,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漠趁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年扁凛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯传。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谨朝,死狀恐怖卤妒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情字币,我是刑警寧澤则披,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站洗出,受9級特大地震影響士复,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翩活,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一阱洪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菠镇,春花似錦冗荸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隘梨,卻和暖如春程癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轴猎。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工嵌莉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人税稼。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓烦秩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親郎仆。 傳聞我的和親對象是個(gè)殘疾皇子只祠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容