iOS 8 Aan de slag met metaal

Deze tutorial laat je zien hoe je aan de slag kunt met Metal, een framework geïntroduceerd in iOS 8 dat GPU-versnelde weergave van 3D-afbeeldingen en gegevensparallelle berekeningsworkloads ondersteunt. In deze tutorial zullen we de theoretische concepten onder de loep nemen van Metal. U leert ook hoe u een Metal-toepassing maakt die de vereiste hardwarestatus voor afbeeldingen instelt, opdrachten uitvoert voor uitvoering in de GPU en buffer, structuurobjecten en vooraf samengestelde shaders beheert.

1. Eerste dingen eerst

Deze tutorial gaat ervan uit dat je bekend bent met de taal Objective-C en wat ervaring hebt met OpenGL, OpenCL of een vergelijkbare grafische API.

Het vereist ook een fysiek apparaat met een Apple A7- of A8-processor. Dit betekent dat je een iPhone 5S, 6 of 6 Plus of een iPad Air of mini (2e generatie) nodig hebt. De iOS Simulator geeft je compilatiefouten.

Deze tutorial is alleen gericht op Metal en zal de Metal Shading Language niet omvatten. We zullen een arcering maken, maar we zullen alleen de basishandelingen behandelen om ermee te werken.

Als u Xcode voor de eerste keer gebruikt, zorg er dan voor dat u uw Apple ID toevoegt in de accounts sectie van Xcode's voorkeuren. Dit zorgt ervoor dat u geen problemen ondervindt bij het implementeren van een toepassing op uw apparaat.

Xcode 6 bevat een projectsjabloon voor Metal, maar om je te helpen Metal beter te begrijpen, gaan we vanuit het niets een project maken.

Nog een laatste opmerking: we gebruiken Objective-C in deze tutorial en het is belangrijk dat je een basiskennis hebt van deze programmeertaal.

2. Introductie

Voor degenen onder u die bekend zijn met OpenGL of OpenGL ES, is Metal een 3D-framework met een laag niveau, maar met een lagere overhead. In tegenstelling tot Apple's Sprite Kit- of Scene Kit-frameworks waarmee je standaard geen interactie hebt met de renderingpijplijn, heb je bij Metal de absolute macht om die pijplijn te maken, te beheren en aan te passen..

Metal heeft de volgende kenmerken:

  • Het framework biedt extreem lage overhead toegang tot de A7 en A8 GPU, waardoor ongelooflijk hoge prestaties mogelijk zijn voor geavanceerde grafische weergave en computationele taken.
  • Metaal elimineert veel knelpunten in de prestaties, zoals kostbare statusvalidatie die wordt aangetroffen in traditionele grafische API's.
  • Het is expliciet ontworpen om alle dure vertaal- en compilatiebewerkingen uit de runtime- en renderingomgeving te verplaatsen.
  • Het biedt vooraf samengestelde shaders, statusobjecten en een expliciete opdrachtplanning om ervoor te zorgen dat uw toepassing de hoogst mogelijke prestaties en efficiëntie bereikt voor grafische weergave en computertaken..
  • Het raamwerk is ontworpen om moderne architecturale overwegingen, zoals multiprocessing en gedeeld geheugen, te benutten.
  • Het is diep geïntegreerd met iOS 8, de A7- en A8-chipsets en de Apple-hardware, waardoor een uniform en onafhankelijk raamwerk ontstaat.

Genoeg met de theorie, het is tijd om te begrijpen hoe een Metal-applicatie is gebouwd.

3. Een metalen applicatie maken

Een Metal-toepassing wordt gekenmerkt door een reeks vereiste stappen om gegevens correct op het scherm weer te geven. Deze stappen worden meestal op volgorde gemaakt en sommige referenties worden van de ene naar de andere doorgegeven. Deze stappen zijn:

  • pak het apparaat
  • maak een opdrachtwachtrij aan
  • maak bronnen, zoals buffers, texturen en shaders
  • maak een rendering pipeline
  • maak een weergave

Stap 1: Download het apparaat

Deze stap omvat het maken van een MTLDevice object, het hart van een Metal-toepassing. De MTLDevice class biedt een directe manier om te communiceren met de GPU-driver en -hardware. Om een ​​verwijzing naar een te krijgen MTLDevice U moet bijvoorbeeld de Systeem standaard apparaat zoals hieronder getoond. Met deze referentie hebt u directe toegang tot de hardware van het apparaat.

ID kaart  mtlDevice = MTLCreateSystemDefaultDevice ();

Stap 2: maak een opdrachtwachtrij

De MTLCommandQueue class biedt een manier om opdrachten of instructies naar de GPU te verzenden. Een exemplaar van de initialiseren MTLCommandQueue klasse, je moet de MTLDevice object dat we eerder hebben gemaakt en bel het newCommandQueue methode erop.

ID kaart  mtlCommandQueue = [mtlDevice newCommandQueue];

Stap 3: Maak bronnen

Deze stap omvat het maken van uw bufferobjecten, texturen en andere bronnen. In deze zelfstudie maakt u hoekpunten. Deze objecten worden opgeslagen op de server / GPU-zijde en om met hen te communiceren, moet u een specifieke gegevensstructuur maken die vergelijkbare gegevens moet bevatten als die beschikbaar zijn in het vertex-object.

Als u bijvoorbeeld gegevens moet doorgeven voor een 2D vertex-positie, moet u één datastructuur declareren die een object voor die 2D-positie bevat. Vervolgens moet u dit declareren in zowel de client, uw iOS-applicatie als de serverkant, de Metal-shader. Bekijk het volgende voorbeeld voor meer informatie.

typedef struct GLKVector2 position;  YourDataStruct;

Merk op dat u de GLKMath bibliotheek van de GLKit kader zoals hieronder getoond.

#importeren 

Vervolgens declareert u een object met de juiste coördinaten.

YourDataStruct triangle [3] = -.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f;

Stap 4: maak een renderingpijplijn

Het maken van de renderingpijplijn is waarschijnlijk de lastigste stap, omdat je moet zorgen voor verschillende initialisaties en configuraties, die allemaal in het volgende diagram worden geïllustreerd.

De renderingpijplijn is geconfigureerd met behulp van twee klassen:

  • MTLRenderPipelineDescriptor: biedt al uw renderingpijplijnen, zoals hoekpuntposities, kleur, diepte en stencilbuffers, onder anderen
  • MTLRenderPipelineState: de gecompileerde versie van MTLRenderPipelineDescriptor en die op het apparaat worden geïmplementeerd

Merk op dat u niet alle rendering pipeline-objecten hoeft te maken. U moet alleen degenen maken die aan uw behoeften voldoen.

In het volgende codefragment ziet u hoe u het maakt MTLRenderPipelineDescriptor voorwerp.

MTLRenderPipelineDescriptor * mtlRenderPipelineDescriptor = [MTLRenderPipelineDescriptor nieuw]; 

Op dit punt hebt u de descriptor gemaakt, maar u moet deze nog steeds configureren met ten minste het pixelformaat. Dit is wat we doen in het volgende codeblok.

mtlRenderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm;

Voor geavanceerdere toepassingen moet u ook de standaard vertex en fragmentschaduw instellen, zoals hieronder weergegeven.

ID kaart  lib = [mtlDevice newDefaultLibrary]; mtlRenderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "SomeVertexMethodName"]; mtlRenderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "SomeFragmentMethodName"];

De newFunctionWithName methode zoekt in uw Metal bronbestand, op zoek naar de SomeVertexMethodName methode. De naam van de arcering zelf is niet belangrijk, omdat de lookup rechtstreeks via de methode-namen wordt gedaan. Dit betekent dat u unieke methoden voor unieke arceringbewerkingen moet definiëren. We zullen later dieper ingaan op Metal shaders.

Met de MTLRenderPipelineDescriptor object gemaakt en geconfigureerd, de volgende stap is het maken en definiëren van het MTLRenderPipelineState door het nieuw gecreëerde door te geven MTLRenderPipelineDescriptor voorwerp.

NSError * error = [[NSError alloc] init]; ID kaart  mtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: mtlRenderPipelineDescriptor error: & error];

Stap 5: Maak een weergave

Als u een metalen weergave wilt maken, moet u een subklasse maken UIView en negeer de layerClass methode zoals hieronder getoond.

+(id) layerClass return [CAMetalLayer class]; 

In deze zelfstudie bekijken we een andere manier om een ​​te maken CAMetalLayer klasse die de ontwikkelaar meer controle geeft over de kenmerken en configuratie van de laag.

4. Een metalen app tekenen

Nu we de benodigde objecten hebben geïnitialiseerd, moeten we iets op het scherm tekenen. Net als bij de initialisatie moet u een aantal stappen volgen:

  • verkrijg de command buffer
  • stel een renderpas in
  • trek.
  • toewijzen aan de opdrachtbuffer

Stap 1: Verkrijg de Command Buffer

De eerste stap bestaat uit het maken van een object met een seriële lijst met opdrachten voor het uit te voeren apparaat. Je maakt een MTLCommandBuffer object en voeg commando's toe die achtereenvolgens door de GPU worden uitgevoerd. Het volgende codefragment laat zien hoe u een opdrachtbuffer maakt. Wij gebruiken de MTLCommandQueue object dat we eerder hebben gemaakt.

ID kaart  mtlCommandBuffer = [mtlCommandQueue commandBuffer];

Stap 2: Start een renderpas

In Metal is de weergaveconfiguratie complex en moet u expliciet aangeven wanneer de renderpas begint en wanneer deze eindigt. U moet de framebufferconfiguraties vooraf definiëren zodat iOS de hardware op de juiste manier voor die specifieke configuratie kan configureren.

Voor degenen die bekend zijn met OpenGL en OpenGL ES, is deze stap vergelijkbaar omdat de framebuffer dezelfde eigenschappen heeft, Kleur hechting (0 tot 3), Diepte, en Stencil configuraties. U kunt een visuele weergave van deze stap in het onderstaande diagram bekijken.

U moet eerst een textuur maken om naar te renderen. De textuur is gemaakt op basis van de CAMetalDrawable klasse en gebruikt de nextDrawable methode om de volgende textuur op te halen om in de lijst te tekenen.

ID kaart  frameDrawable; frameDrawable = [renderLayer nextDrawable];

Deze nextDrawable bellen kan en zou uw applicatieknelpunt zijn, omdat het uw applicatie gemakkelijk kan blokkeren. De CPU en GPU kunnen worden gedesynchroniseerd en de ene moet op de andere wachten, wat een blokverklaring kan veroorzaken. Er zijn synchrone mechanismen die kunnen en moeten altijd worden geïmplementeerd om deze problemen op te lossen, maar ik zal deze niet behandelen in deze inleidende zelfstudie.

Nu dat je een textuur moet renderen, moet je een maken MTLRenderPassDescriptor object om de framebuffer- en textuurinformatie op te slaan. Bekijk het volgende codefragment om te zien hoe dit werkt.

MTLRenderPassDescriptor * mtlRenderPassDescriptor; mtlRenderPassDescriptor = [MTLRenderPassDescriptor nieuw]; mtlRenderPassDescriptor.colorAttachments [0] .texture = frameDrawable.texture; mtlRenderPassDescriptor.colorAttachments [0] .loadAction = MTLLoadActionClear; mtlRenderPassDescriptor.colorAttachments [0] .clearColor = MTLClearColorMake (0,75, 0,25, 1,0, 1,0);

De eerste stap stelt de te tekenen textuur in. De tweede definieert een specifieke actie die moet worden uitgevoerd, in dit geval het wissen van de textuur en het voorkomen dat de inhoud van die textuur in de GPU-cache wordt geladen. De laatste stap verandert de achtergrondkleur in een specifieke kleur.

Stap 3: Draw

Met de framebuffer en de textuur geconfigureerd, is het tijd om een MTLRenderCommandEncoder aanleg. De MTLRenderCommandEncoder class is verantwoordelijk voor de traditionele interacties met het scherm en kan worden gezien als een container voor een grafische weergavestatus. Het vertaalt ook uw code in een hardwarespecifieke opdrachtindeling die door het apparaat wordt uitgevoerd.

ID kaart  renderCommand = [mtlCommandBuffer renderCommandEncoderWithDescriptor: mtlRenderPassDescriptor]; // Stel MTLRenderPipelineState // Draw hier objecten in [renderCommand endEncoding];

Stap 4: Vastleggen op de opdrachtbuffer

We hebben nu een buffer en instructies wachten in het geheugen. De volgende stap is het committen van de commando's naar de opdrachtbuffer en de grafische weergave op het scherm zien. Merk op dat de GPU alleen code zal uitvoeren die u specifiek voor het effect hebt vastgelegd. Met de volgende coderegels kunt u uw framebuffer plannen en de opdrachtbuffer toewijzen aan de GPU.

[mtlCommandBuffer presentDrawable: frameDrawable]; [mtlCommandBuffer commit];

Op dit punt moet u een algemeen idee hebben van hoe een Metal-applicatie is gestructureerd. Om dit echter goed te begrijpen, moet u het zelf doen. Het is nu tijd om uw eerste Metal-applicatie te coderen.

5. Een metalen applicatie maken

Start Xcode 6 en kies Nieuw> Project ... van de het dossier menu. kiezen Toepassing enkele weergave uit de lijst met sjablonen en kies een productnaam. set Doelstelling C als de taal en selecteer iPhone van de apparaten menu.

Open ViewController.m en voeg de volgende importinstructies bovenaan toe.

#importeren  #importeren 

U moet ook het Metaal en QuartzCore kaders in de Gekoppelde kaders en bibliotheken deel van de doelwitten Bouw fases. Vanaf nu moet uw aandacht gericht zijn op het uitvoeringsbestand van de ViewController klasse.

6. De metalen structuur maken

Zoals ik eerder al zei, is uw eerste taak het instellen en initialiseren van de kernobjecten die in de hele applicatie worden gebruikt. In het volgende codefragment declareren we een aantal instantievariabelen. Deze moeten er bekend uitzien als je het eerste deel van deze tutorial hebt gelezen.

@implementation ViewController id  mtlDevice; ID kaart  mtlCommandQueue; MTLRenderPassDescriptor * mtlRenderPassDescriptor; CAMetalLayer * metalLayer; ID kaart  frameDrawable; CADisplayLink * displayLink; 

In de view controller's viewDidLoad methode, initialiseren we de MTLDevice en CommandQueue instanties.

mtlDevice = MTLCreateSystemDefaultDevice (); mtlCommandQueue = [mtlDevice newCommandQueue];

U kunt nu communiceren met uw apparaat en opdrachtwachtrijen maken. Het is nu tijd om het te configureren CAMetalLayer voorwerp. Jouw CAMetalLayer laag moet een specifieke configuratie hebben, afhankelijk van het apparaat, het pixelformaat en de framegrootte. Je moet ook opgeven dat alleen de framebuffer wordt gebruikt en dat deze aan de huidige laag wordt toegevoegd.

Als u een probleem hebt met het configureren van de CAMetalLayer object, dan helpt het volgende codefragment u hierbij.

metalLayer = [CAMetalLayer-laag]; [metalLayer setDevice: mtlDevice]; [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = YES; [metalLayer setFrame: self.view.layer.frame]; [self.view.layer addSublayer: metalLayer];

U moet ook de dekking, achtergrondkleur en de schaalfactor van de inhoud instellen. Dit wordt geïllustreerd in het volgende codefragment.

[self.view setOpaque: YES]; [self.view setBackgroundColor: nil]; [self.view setContentScaleFactor: [Hoofdscherm van UIScreen] .scale];

De enige resterende stap is om iets naar het scherm te renderen. Initialiseer de CADisplayLink, binnenkomen zelf als doelwit en @ selector (renderScene) als de selector. Voeg ten slotte de CADisplayLink object tegen de huidige run loop.

displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector (renderScene)]; [displayLink addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];

Dit is wat het voltooide viewDidLoad methode zou moeten lijken.

- (void) viewDidLoad [super viewDidLoad]; mtlDevice = MTLCreateSystemDefaultDevice (); mtlCommandQueue = [mtlDevice newCommandQueue]; metalLayer = [CAMetalLayer-laag]; [metalLayer setDevice: mtlDevice]; [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = YES; [metalLayer setFrame: self.view.layer.frame]; [self.view.layer addSublayer: metalLayer]; [self.view setOpaque: YES]; [self.view setBackgroundColor: nil]; [self.view setContentScaleFactor: [Hoofdscherm van UIScreen] .scale]; displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector (renderScene)]; [displayLink addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; 

Als je het project bouwt, zul je merken dat Xcode ons een waarschuwing geeft. We moeten nog steeds het renderScene methode.

De renderScene methode wordt elk frame uitgevoerd. Er zijn verschillende objecten die moeten worden geïnitialiseerd voor elk nieuw frame, zoals de MTLCommandBuffer en MTLRenderCommandEncoder voorwerpen.

De stappen die we moeten nemen om een ​​frame weer te geven zijn:

  • Maak een MTLCommandBuffer voorwerp
  • initialiseer a CAMetalDrawable voorwerp
  • initialiseer a MTLRenderPassDescriptor voorwerp
  • configureer de structuur, loadAction, clearColor, en storeAction eigenschappen van de MTLRenderPassDescriptor voorwerp
  • maak een nieuw MTLRenderCommandEncoder voorwerp
  • presenteer de drawable en commit de command buffer

Kom gerust terug naar wat we tot nu toe hebben gezien om deze uitdaging alleen op te lossen. Als je verder wilt gaan met deze tutorial, bekijk dan de onderstaande oplossing.

- (ongeldig) renderScene id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; while (! frameDrawable) frameDrawable = [metalLayer nextDrawable];  if (! mtlRenderPassDescriptor) mtlRenderPassDescriptor = [MTLRenderPassDescriptor nieuw]; mtlRenderPassDescriptor.colorAttachments [0] .texture = frameDrawable.texture; mtlRenderPassDescriptor.colorAttachments [0] .loadAction = MTLLoadActionClear; mtlRenderPassDescriptor.colorAttachments [0] .clearColor = MTLClearColorMake (0,75, 0,25, 1,0, 1,0); mtlRenderPassDescriptor.colorAttachments [0] .storeAction = MTLStoreActionStore; ID kaart  renderCommand = [mtlCommandBuffer renderCommandEncoderWithDescriptor: mtlRenderPassDescriptor]; // Teken hier objecten // stel MTLRenderPipelineState ... [renderCommand endEncoding] in; [mtlCommandBuffer presentDrawable: frameDrawable]; [mtlCommandBuffer commit]; mtlRenderPassDescriptor = nihil; frameDrawable = nil; 

We moeten ook de view-controller's implementeren dealloc methode waarbij we de ongeldig maken DisplayLink voorwerp. We hebben de mtlDevice en mtlCommandQueue objecten aan nul.

-(void) dealloc [displayLink invalidate]; mtlDevice = nihil; mtlCommandQueue = nihil; 

7. Een driehoek tekenen

Je hebt nu een heel eenvoudige Metal-applicatie. Het is tijd om je eerste grafische primitieve, een driehoek toe te voegen. De eerste stap is om een ​​structuur voor de driehoek te maken.

typedef struct GLKVector2 position; Driehoek;

Vergeet niet om een ​​importinstructie toe te voegen voor de GLKMath bibliotheek bovenaan ViewController.m.

#importeren 

Om de driehoek weer te geven, moet u een maken MTLRenderPipelineDescriptor object en een MTLRenderPipelineState voorwerp. Bovendien behoort elk object dat op het scherm wordt getekend tot de MTLBuffer klasse.

MTLRenderPipelineDescriptor * renderPipelineDescriptor; ID kaart  renderPipelineState; ID kaart  voorwerp;

Wanneer deze instantievariabelen zijn gedeclareerd, moet u ze nu initialiseren in de viewDidLoad methode zoals ik eerder heb uitgelegd.

renderPipelineDescriptor = [MTLRenderPipelineDescriptor nieuw]; renderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm;

Om de driehoek te verduisteren, hebben we Metal shaders nodig. De Metal shaders moeten worden toegewezen aan de MTLRenderPipelineDescriptor object en ingekapseld door a MTLLibrary protocol. Het klinkt misschien ingewikkeld, maar u hoeft alleen de volgende coderegels te gebruiken:

ID kaart  lib = [mtlDevice newDefaultLibrary]; renderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "VertexColor"]; renderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "FragmentColor"]; renderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: renderPipelineDescriptor error: nil];

De eerste regel maakt een object dat overeenkomt met de MTLLibrary protocol. In de tweede regel vertellen we de bibliotheek welke methode moet worden aangeroepen in de arcering om de vertex-pass in de renderingpijplijn te bedienen. In de derde regel herhalen we deze stap op pixelniveau, de fragmenten. Eindelijk, in de laatste regel creëren we een MTLRenderPipelineState voorwerp.

In Metal kunt u de systeemcoördinaten definiëren, maar in deze zelfstudie gebruikt u het standaardcoördinatensysteem, dat wil zeggen, de coördinaten van het midden van het scherm zijn (0,0).

In het volgende codeblok maken we een driehoek-object met drie coördinaten, (-5f, 0,0f), (0,5f, 0,0f), (0,0f, 0,5f).

Triangeldriehoek [3] = -.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f;

Vervolgens voegen we de driehoek toe aan de object, waarmee een buffer voor de driehoek wordt gemaakt.

object = [mtlDevice newBufferWithBytes: & triangle length: sizeof (Triangle [3]) options: MTLResourceOptionCPUCacheModeDefault];

Dit is wat het voltooide viewDidLoad methode zou moeten lijken.

- (void) viewDidLoad [super viewDidLoad]; mtlDevice = MTLCreateSystemDefaultDevice (); mtlCommandQueue = [mtlDevice newCommandQueue]; metalLayer = [CAMetalLayer-laag]; [metalLayer setDevice: mtlDevice]; [metalLayer setPixelFormat: MTLPixelFormatBGRA8Unorm]; metalLayer.framebufferOnly = YES; [metalLayer setFrame: self.view.layer.frame]; [self.view.layer addSublayer: metalLayer]; [self.view setOpaque: YES]; [self.view setBackgroundColor: nil]; [self.view setContentScaleFactor: [Hoofdscherm van UIScreen] .scale]; // Maak een herbruikbare pijplijnrenderPipelineDescriptor = [MTLRenderPipelineDescriptor nieuw]; renderPipelineDescriptor.colorAttachments [0] .pixelFormat = MTLPixelFormatBGRA8Unorm; ID kaart  lib = [mtlDevice newDefaultLibrary]; renderPipelineDescriptor.vertexFunction = [lib newFunctionWithName: @ "VertexColor"]; renderPipelineDescriptor.fragmentFunction = [lib newFunctionWithName: @ "FragmentColor"]; renderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor: renderPipelineDescriptor error: nil]; Triangeldriehoek [3] = -.5f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f; object = [mtlDevice newBufferWithBytes: & triangle length: sizeof (Triangle [3]) options: MTLResourceOptionCPUCacheModeDefault]; displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector (renderScene)]; [displayLink addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode]; 

De viewDidLoad methode is voltooid, maar er ontbreekt nog een laatste stap, waarbij de shaders worden gemaakt.

8. Shaders maken

Selecteer om een ​​metalen arcering te maken Nieuw> Bestand ...  van de het dossier menu, kies Bron > Metalen bestand van de iOS sectie en noem deze MyShader. Xcode maakt vervolgens een nieuw bestand voor u aan, MyShader.metal.

Bovenaan ziet u de volgende twee regels code. De eerste bevat de Metalen standaardbibliotheek terwijl de tweede de metaal namespace.

#include  gebruik van naamruimte metaal;

De eerste stap is om de driehoekstructuur naar de arcering te kopiëren. Shaders worden meestal verdeeld in twee verschillende bewerkingen, vertex en pixel (fragmenten). De eerste is gerelateerd aan de positie van de vertex terwijl de tweede gerelateerd is aan de uiteindelijke kleur van die vertex en alle posities van pixels in de veelhoek. Je kunt het op deze manier bekijken, de eerste zal de polygoon rasteren, de pixels van de polygoon, en de tweede zal diezelfde pixels verduisteren.

Omdat ze op unidirectionele wijze moeten communiceren, van vertex tot fragment, is het het beste om een ​​structuur te maken voor de gegevens die worden doorgegeven. In dit geval geven we alleen de positie door.

typedef struct float4 position [[position]];  TriangleOutput;

Laten we nu de vertex- en fragmentmethodes maken. Weet u nog toen u de RenderPipelineDescriptor object voor zowel vertex als fragment? U gebruikte de newFunctionWithName methode, doorgeven in een NSString voorwerp. Die string is de naam van de methode die u in de arcering aanroept. Dit betekent dat u twee methoden met die namen moet declareren, VertexColor en FragmentColor.

Wat betekent dit? Je kunt je shaders maken en ze een naam geven zoals je wilt, maar je moet de methoden precies zo noemen als je ze declareert en ze moeten unieke namen hebben.

Voeg in je shaders het volgende codeblok toe.

vertex TriangleOutput VertexColor (const device Triangle * Vertices [[buffer (0)]], const uint index [[vertex_id]]) TriangleOutput out; out.position = float4 (Vertices [index] .position, 0.0, 1.0); terugkomen;  fragment half4 FragmentColor (void) return half4 (1.0, 0.0, 0.0, 1.0); 

De VertexColor methode ontvangt gegevens die op positie zijn opgeslagen 0 van de buffer (toegewezen geheugen) en de vertex_id van de top. Omdat we een drievierdriehoek hebben verklaard, is de vertex_id zal zijn 0, 1, en 2. Het levert a TriangleOutput object dat automatisch wordt ontvangen door de FragmentColor. Ten slotte zal het elke pixel in die drie hoekpunten verduisteren met een rode kleur.

Dat is het. Bouw en run je applicatie en geniet van je eerste, gloednieuwe 60fps Metal-applicatie.

9. Externe bronnen

Als u meer wilt weten over het Metal-framework en hoe het werkt, kunt u verschillende andere bronnen bekijken:

  • WWDC 2014 (Werken met metalen secties)
  • Metal Framework Reference
  • Programmeerhandleiding voor metaal

Conclusie

Dit is onze introductieles over het nieuwe metalen raamwerk. Als u vragen of opmerkingen heeft, kunt u een opmerking plaatsen in de opmerkingen.