金属に基づく画像処理フレームワーク。
MTIImageを作成しますMTIImageをレンダリングしますMTIImageを表示しますCVPixelBufferのカラースペースSwiftAppleSiliconMetalPetalは、使いやすいプログラミングインターフェイスを備えた静止画像とビデオのリアルタイム処理を提供するように設計された金属に基づく画像処理フレームワークです。
この章では、MetalPetalの重要な概念について説明し、その設計、実装、パフォーマンスへの影響、ベストプラクティスをよりよく理解するのに役立ちます。
MetalPetalは、次の目標を念頭に置いて設計されています。
使いやすいAPI
便利なAPIを提供し、一般的な落とし穴を回避します。
パフォーマンス
CPU、GPU、およびメモリを効率的に使用します。
拡張性
カスタムフィルターとプラグインカスタム画像処理ユニットを簡単に作成できます。
Swifty
迅速なプログラマーに流動的な体験を提供します。
MetalPetalのコア概念のいくつかは、Appleのコア画像フレームワークのコア概念と非常に似ています。
MTIImageをレンダリングするための評価コンテキストを提供します。また、多くのキャッシュと状態情報を保存するため、可能な限りコンテキストを再利用する方が効率的です。
MTIImageオブジェクトは、処理または生成される画像の表現です。代わりに、画像ビットマップデータを直接表します。その代わりに、画像またはより正確にMTLTexture作成するために必要なすべての情報があります。これは、テクスチャ( MTIImagePromise )の生成方法のレシピと、コンテキストが画像をキャッシュする方法( cachePolicy )、テクスチャのサンプリング方法( samplerDescriptor )などの2つの部分で構成されています。
MTIFilter 、画像処理効果と、その効果を制御するパラメーターを表します。出力としてMTIImageオブジェクトを生成します。フィルターを使用するには、フィルターオブジェクトを作成し、入力画像とパラメーターを設定し、出力画像にアクセスします。通常、フィルタークラスは静的カーネル( MTIKernel )を所有します。 outputImageプロパティにアクセスすると、入力画像とパラメーターを使用してカーネルに出力MTIImage生成します。
MTIKernel画像処理ルーチンを表します。 MTIKernel 、フィルターの対応するレンダリングまたは計算パイプライン状態を作成し、 MTIImage用のMTIImagePromise構築する責任があります。
MetalPetalは、ボンネットの下で多くの最適化を行います。
機能、カーネル状態、サンプラー状態などを自動的にキャッシュします。
プログラム可能なブレンド、メモリレスレンダリングターゲット、リソースヒープ、金属のパフォーマンスシェーダーなどの金属機能を利用して、レンダリングを高速かつ効率的にします。 MACOSでは、MetalPetalはApple SiliconのTBDRアーキテクチャを活用することもできます。
レンダリングの前に、MetalPetalは画像のレンダリンググラフを調べ、レンダリング、保存、メモリ、エネルギー、時間を実行するために必要な中間テクスチャの最小数を把握できます。
また、複数の「レシピ」を連結して冗長レンダリングパスを排除することができる場合、画像レンダリンググラフを再編成することもできます。 ( MTIContext.isRenderGraphOptimizationEnabled )
MTIImageオブジェクトは不変です。つまり、スレッド間で安全に共有できることを意味します。
ただし、 MTIFilterオブジェクトは可変であるため、スレッド間で安全に共有することはできません。
MTIContextには、多くの状態とキャッシュが含まれています。 MTIContextオブジェクトにはスレッドセーフメカニズムがあり、スレッド間でMTIContextオブジェクトを共有しても安全です。
完全にカスタマイズ可能な頂点とフラグメント関数。
MRT(複数のレンダリングターゲット)サポート。
一般的にパフォーマンスが向上します。 (詳細なベンチマークデータが必要です)
カラーマトリックス
カラールックアップ
カラールックアップテーブルを使用して、画像の色を再マップします。
不透明
暴露
飽和
輝度
対比
色の反転
活力
心地よい肌のトーンを保ちながら、画像の飽和を調整します。
RGBトーンカーブ
ブレンドモード
マスクとブレンドします
変身
作物
ピクセル酸塩
多層複合材
MPS畳み込み
MPS Gaussian Blur
MPS定義
国会議員のソベル
MPS UNSHARPマスク
MPSボックスブラー
ハイパススキンスムージング
Clahe(コントラスト制限適応ヒストグラムの均等化)
レンズブラー(六角形のボケのぼやけ)
表面のぼかし
バルジの歪み
クロマキーブレンド
カラーハーフトーン
ドット画面
丸い角(円形/連続曲線)
すべてのコア画像フィルター
MTIImageを作成します以下を含む、ほぼすべての画像データのソースからMTIImageオブジェクトを作成できます。
URLのロードされる画像ファイルを参照してくださいCVImageBufferRefまたはCVPixelBufferRef )CIImageオブジェクトMDLTextureオブジェクト let imageFromCGImage = MTIImage ( cgImage : cgImage , isOpaque : true )
let imageFromCIImage = MTIImage ( ciImage : ciImage )
let imageFromCoreVideoPixelBuffer = MTIImage ( cvPixelBuffer : pixelBuffer , alphaType : . alphaIsOne )
let imageFromContentsOfURL = MTIImage ( contentsOf : url )
// unpremultiply alpha if needed
let unpremultipliedAlphaImage = image . unpremultiplyingAlpha ( ) let inputImage = ...
let filter = MTISaturationFilter ( )
filter . saturation = 0
filter . inputImage = inputImage
let outputImage = filter . outputImageMTIImageをレンダリングします let options = MTIContextOptions ( )
guard let device = MTLCreateSystemDefaultDevice ( ) , let context = try ? MTIContext ( device : device , options : options ) else {
return
}
let image : MTIImage = ...
do {
try context . render ( image , to : pixelBuffer )
//context.makeCIImage(from: image)
//context.makeCGImage(from: image)
} catch {
print ( error )
}MTIImageを表示します let imageView = MTIImageView ( frame : self . view . bounds )
// You can optionally assign a `MTIContext` to the image view. If no context is assigned and `automaticallyCreatesContext` is set to `true` (the default value), a `MTIContext` is created automatically when the image view renders its content.
imageView . context = ...
imageView . image = image GPUコマンドエンコードプロセスをメインスレッドから移動したい場合は、 MTIThreadSafeImageViewを使用できます。任意のスレッドのMTIThreadSafeImageViewにMTIImageを割り当てることができます。
MetalPetalには、フィルターを接続するためのタイプセーフSWIFT APIがあります。 FilterGraph.makeImage関数の=> operatorを使用して、フィルターを接続し、出力イメージを取得できます。
ここにいくつかの例があります:
let image = try ? FilterGraph . makeImage { output in
inputImage => saturationFilter => exposureFilter => output
} let image = try ? FilterGraph . makeImage { output in
inputImage => saturationFilter => exposureFilter => contrastFilter => blendFilter . inputPorts . inputImage
exposureFilter => blendFilter . inputPorts . inputBackgroundImage
blendFilter => output
} =>を使用して、unaryフィルター( MTIUnaryFilter )を直接接続できます。
複数の入力を備えたフィルターの場合、 inputPortsの1つに接続する必要があります。
=>オペレーターは、 FilterGraph.makeImageメソッドでのみ機能します。
1つのフィルターの出力が1つだけoutputできます。
AVPlayerとの作業:
let context = try MTIContext ( device : device )
let asset = AVAsset ( url : videoURL )
let composition = MTIVideoComposition ( asset : asset , context : context , queue : DispatchQueue . main , filter : { request in
return FilterGraph . makeImage { output in
request . anySourceImage! => filterA => filterB => output
} !
}
let playerItem = AVPlayerItem ( asset : asset )
playerItem . videoComposition = composition . makeAVVideoComposition ( )
player . replaceCurrentItem ( with : playerItem )
player . play ( )ビデオのエクスポート:
Videoioは、次の例に必要です。
import VideoIO
var configuration = AssetExportSession . Configuration ( fileType : . mp4 , videoSettings : . h264 ( videoSize : composition . renderSize ) , audioSettings : . aac ( channels : 2 , sampleRate : 44100 , bitRate : 128 * 1000 ) )
configuration . videoComposition = composition . makeAVVideoComposition ( )
self . exporter = try ! AssetExportSession ( asset : asset , outputURL : outputURL , configuration : configuration )
exporter . export ( progress : { progress in
} , completion : { error in
} )この例にはビデオが必要です。
import VideoIO
// Setup Image View
let imageView = MTIImageView ( frame : self . view . bounds )
...
// Setup Camera
let camera = Camera ( captureSessionPreset : . hd1920x1080 , configurator : . portraitFrontMirroredVideoOutput )
try camera . enableVideoDataOutput ( on : DispatchQueue . main , delegate : self )
camera . videoDataOutput ? . videoSettings = [ kCVPixelBufferPixelFormatTypeKey as String : kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ]
...
// AVCaptureVideoDataOutputSampleBufferDelegate
let filter = MTIColorInvertFilter ( )
func captureOutput ( _ output : AVCaptureOutput , didOutput sampleBuffer : CMSampleBuffer , from connection : AVCaptureConnection ) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer ( sampleBuffer ) else {
return
}
let inputImage = MTIImage ( cvPixelBuffer : pixelBuffer , alphaType : . alphaIsOne )
filter . inputImage = inputImage
self . imageView . image = filter . outputImage
}フィルタリングされたライブビデオのプレビューと記録の詳細については、ExampleプロジェクトのCameraFilterView.swiftを参照してください。
可能な限り、 MTIContextを再利用します。
コンテキストはヘビー級のオブジェクトです。そのため、作成する場合はできるだけ早く作成し、画像をレンダリングする必要があるたびに再利用してください。
MTIImage.cachePolicyを賢く使用します。
画像のレンダリング結果を保存したくない場合、たとえば画像がフィルターチェーンの中間結果である場合、レンダリング結果MTIImageCachePolicyTransient根底にあるテクスチャを再利用できる場合、画像のレンダリング結果を保存したくない場合に使用します。これは、最もメモリ効率の高いオプションです。ただし、コンテキストに以前にレンダリングされた画像をレンダリングするように依頼すると、その根底にあるテクスチャが再利用されているため、その画像を再レンダリングする可能性があります。
デフォルトでは、フィルターの出力イメージにはtransientポリシーがあります。
基礎となるテクスチャが再利用されないようにしたい場合は、 MTIImageCachePolicyPersistentを使用します。
デフォルトでは、外部ソースから作成された画像にはpersistentポリシーがあります。
MTIFilter.outputImageは計算プロパティであることを理解してください。
フィルターに出力イメージを尋ねるたびに、フィルターは、入力が前の呼び出しと同一であっても、新しい出力画像オブジェクトを提供する場合があります。可能な限り出力画像を再利用してください。
例えば、
// ╭→ filterB
// filterA ─┤
// ╰→ filterC
//
// filterB and filterC use filterA's output as their input.この状況では、次の解決策:
let filterOutputImage = filterA . outputImage
filterB . inputImage = filterOutputImage
filterC . inputImage = filterOutputImageより良いです:
filterB . inputImage = filterA . outputImage
filterC . inputImage = filterA . outputImageMTIShaderLib.hを.metalファイルに含めたい場合は、 MTIShaderLib.hファイルのパスをMetal Compiler - Header Search Paths ( MTL_HEADER_SEARCH_PATHS )設定に追加する必要があります。
たとえば、cocoapodsを使用する場合、 MTL_HEADER_SEARCH_PATHS ${PODS_CONFIGURATION_BUILD_DIR}/MetalPetal/MetalPetal.framework/Headersまたは${PODS_ROOT}/MetalPetal/Frameworks/MetalPetal/Shadersに設定できます。 Swiftパッケージマネージャーを使用する場合は、 MTL_HEADER_SEARCH_PATHS $(HEADER_SEARCH_PATHS)に設定します
MetalPetalには、シェーダー関数引数をエンコードするための組み込みメカニズムがあります。シェーダー関数の引数をname: value dictionaries to the MTIRenderPipelineKernel.apply(toInputImages:parameters:outputDescriptors:) 、 MTIRenderCommand(kernel:geometry:images:parameters:)など)に渡すことができます。
たとえば、金属関数のパラメーター辞書vibranceAdjustは次のとおりです。
// Swift
let amount : Float = 1.0
let vibranceVector = float4 ( 1 , 1 , 1 , 1 )
let parameters = [ " amount " : amount ,
" vibranceVector " : MTIVector ( value : vibranceVector ) ,
" avoidsSaturatingSkinTones " : true ,
" grayColorTransform " : MTIVector ( value : float3 ( 0 , 0 , 0 ) ) ] // vibranceAdjust metal function
fragment float4 vibranceAdjust (...,
constant float & amount [[ buffer( 0 ) ]],
constant float4 & vibranceVector [[ buffer( 1 ) ]],
constant bool & avoidsSaturatingSkinTones [[ buffer( 2 ) ]],
constant float3 & grayColorTransform [[ buffer( 3 ) ]])
{
...
}
シェーダー関数引数タイプとパラメーター辞書で使用する対応するタイプを以下に示します。
| シェーダー関数引数タイプ | 迅速 | Objective-C |
|---|---|---|
| フロート | フロート | フロート |
| int | INT32 | int |
| uint | UINT32 | uint |
| ブール | ブール | ブール |
| Simd(float2、float4、float4x4、int4など) | SIMD( MetalPetal/Swiftを使用) / mtivector | mtivector |
| struct | データ / mtidatabuffer | nsdata / mtidatabuffer |
| その他(float *、struct *など)不変 | データ / mtidatabuffer | nsdata / mtidatabuffer |
| その他(float *、struct *など)可変 | mtidatabuffer | mtidatabuffer |
カスタムユニリーフィルターを構築するには、 MTIUnaryImageRenderingFilterをサブクラス化し、 SubclassingHooksカテゴリのメソッドをオーバーライドできます。例: MTIPixellateFilter 、 MTIVibranceFilter 、 MTIUnpremultiplyAlphaFilter 、 MTIPremultiplyAlphaFilterなど。
// Objective-C
@interface MTIPixellateFilter : MTIUnaryImageRenderingFilter
@property ( nonatomic ) float fractionalWidthOfAPixel;
@end
@implementation MTIPixellateFilter
- ( instancetype ) init {
if (self = [ super init ]) {
_fractionalWidthOfAPixel = 0.05 ;
}
return self;
}
+ (MTIFunctionDescriptor *) fragmentFunctionDescriptor {
return [[MTIFunctionDescriptor alloc ] initWithName: @" pixellateEffect " libraryURL: [bundle URLForResource: @" default " withExtension: @" metallib " ]];
}
- ( NSDictionary <NSString *,id> *) parameters {
return @{ @" fractionalWidthOfAPixel " : @(self. fractionalWidthOfAPixel )};
}
@end //Swift
class MTIPixellateFilter : MTIUnaryImageRenderingFilter {
var fractionalWidthOfAPixel : Float = 0.05
override var parameters : [ String : Any ] {
return [ " fractionalWidthOfAPixel " : fractionalWidthOfAPixel ]
}
override class func fragmentFunctionDescriptor ( ) -> MTIFunctionDescriptor {
return MTIFunctionDescriptor ( name : " pixellateEffect " , libraryURL : MTIDefaultLibraryURLForBundle ( Bundle . main ) )
}
}より複雑なフィルターを構築するには、カーネル( MTIRenderPipelineKernel / MTIComputePipelineKernel / MTIMPSKernel )を作成し、入力画像にカーネルを適用します。例: MTIChromaKeyBlendFilter 、 MTIBlendWithMaskFilter 、 MTIColorLookupFilterなど。
@interface MTIChromaKeyBlendFilter : NSObject <MTIFilter>
@property ( nonatomic , strong , nullable ) MTIImage *inputImage;
@property ( nonatomic , strong , nullable ) MTIImage *inputBackgroundImage;
@property ( nonatomic ) float thresholdSensitivity;
@property ( nonatomic ) float smoothing;
@property ( nonatomic ) MTIColor color;
@end
@implementation MTIChromaKeyBlendFilter
@synthesize outputPixelFormat = _outputPixelFormat;
+ (MTIRenderPipelineKernel *) kernel {
static MTIRenderPipelineKernel *kernel;
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
kernel = [[MTIRenderPipelineKernel alloc ] initWithVertexFunctionDescriptor: [[MTIFunctionDescriptor alloc ] initWithName: MTIFilterPassthroughVertexFunctionName] fragmentFunctionDescriptor: [[MTIFunctionDescriptor alloc ] initWithName: @" chromaKeyBlend " ]];
});
return kernel;
}
- ( instancetype ) init {
if (self = [ super init ]) {
_thresholdSensitivity = 0.4 ;
_smoothing = 0.1 ;
_color = MTIColorMake ( 0.0 , 1.0 , 0.0 , 1.0 );
}
return self;
}
- (MTIImage *) outputImage {
if (!self. inputImage || !self. inputBackgroundImage ) {
return nil ;
}
return [ self .class.kernel applyToInputImages: @[ self .inputImage, self .inputBackgroundImage]
parameters: @{ @" color " : [MTIVector vectorWithFloat4: (simd_float4){self. color . red , self. color . green , self. color . blue ,self. color . alpha }],
@" thresholdSensitivity " : @(self. thresholdSensitivity ),
@" smoothing " : @(self. smoothing )}
outputTextureDimensions: MTITextureDimensionsMake2DFromCGSize ( self .inputImage.size)
outputPixelFormat: self .outputPixelFormat];
}
@endMTIRenderCommandを使用して、1つのレンダリングパスで複数のドローコールを発行できます。
// Create a draw call with kernelA, geometryA, and imageA.
let renderCommandA = MTIRenderCommand ( kernel : self . kernelA , geometry : self . geometryA , images : [ imageA ] , parameters : [ : ] )
// Create a draw call with kernelB, geometryB, and imageB.
let renderCommandB = MTIRenderCommand ( kernel : self . kernelB , geometry : self . geometryB , images : [ imageB ] , parameters : [ : ] )
// Create an output descriptor
let outputDescriptor = MTIRenderPassOutputDescriptor ( dimensions : MTITextureDimensions ( width : outputWidth , height : outputHeight , depth : 1 ) , pixelFormat : . bgra8Unorm , loadAction : . clear , storeAction : . store )
// Get the output images, the output image count is equal to the output descriptor count.
let images = MTIRenderCommand . images ( byPerforming : [ renderCommandA , renderCommandB ] , outputDescriptors : [ outputDescriptor ] )また、複数の出力記述子を作成して、1つのレンダリングパスに複数の画像を出力することもできます(MRT、https://en.wikipedia.org/wiki/multiple_render_targetsを参照)。
MTIVertexニーズに合わない場合、 MTIGeometryプロトコルを実装して、Command EncoderにカスタムVertexデータを提供できます。
MTIRenderCommand APIを使用して、呼び出しを発行し、カスタムMTIGeometryを渡します。
まれなシナリオでは、基礎となるテクスチャに直接アクセスしたり、1つのレンダリングパスで複数のMPSカーネルを使用したり、3Dレンダリングを実行したり、レンダリングコマンドをエンコードしたりすることをお勧めします。
MTIImagePromiseプロトコルは、金属ペタルのステップの基礎となるテクスチャとレンダリングコンテキストへの直接アクセスを提供します。
MTIImagePromiseプロトコルを実装することにより、新しい入力ソースまたは完全なカスタム処理ユニットを作成できます。追加するために追加のモジュールをインポートする必要があります。
Objective-C
@import MetalPetal.Extension;
迅速
// CocoaPods
import MetalPetal.Extension
// Swift Package Manager
import MetalPetalObjectiveC.Extension
たとえば、 MTIComputePipelineKernel 、 MTICLAHELUTRecipe 、 MTIImageの実装を参照してください。
画像でアルファチャネルが使用されている場合、利用可能な2つの一般的な表現があります。
未処理のアルファを使用すると、RGBコンポーネントはピクセルの色を表し、その不透明度を無視します。
Premultipried Alphaを使用すると、RGBコンポーネントはピクセルの色を表し、乗算により不透明に調整されます。
MetalPetalは、アルファタイプを明示的に処理します。画像作成中に正しいアルファタイプを提供する責任があります。
MetalPetalには3つのアルファタイプがあります。
MTIAlphaType.nonPremultiplied :画像内のアルファ値は事前にはなりません。
MTIAlphaType.premultiplied :画像のアルファ値は事前に行われています。
MTIAlphaType.alphaIsOne :画像にはアルファチャネルがなく、画像が不透明です。
通常、 CGImage 、 CVPixelBuffer 、 CIImageオブジェクトには、前提条件のアルファチャネルがあります。 MTIAlphaType.alphaIsOne 、画像が不透明である場合、たとえばカメラフィードからのCVPixelBuffer 、またはjpgファイルからロードされたCGImageなどを強くお勧めします。
MTIImageでunpremultiplyingAlpha()またはpremultiplyingAlpha()を呼び出して、画像のアルファタイプを変換できます。
パフォーマンスの理由から、アルファタイプの検証はデバッグビルドでのみ行われます。
MetalPetalのフィルターのほとんどは、不均等なアルファと不透明な画像を受け入れ、具体化されていないアルファ画像を出力します。
outputAlphaTypeプロパティを備えたフィルターすべてのアルファタイプの入力を受け入れます。また、 outputAlphaType使用して、出力画像のアルファ型を指定できます。
たとえば、 MTIBlendFilter 、 MTIMultilayerCompositingFilter 、 MTICoreImageUnaryFilter 、 MTIRGBColorSpaceConversionFilter
実際に色を変更しないフィルターには、パススルーアルファ処理ルールがあります。つまり、出力画像のアルファタイプは入力画像で同じです。
MTIPixellateFilter 、 MTITransformFilter 、 MTICropFilter 、 MTIBulgeDistortionFilter
AlphaタイプとAlpha Compositingの詳細については、Bartosz Ciechanowskiによるこの驚くべきインタラクティブな記事を参照してください。
画像処理にはカラースペースが不可欠です。赤、緑、青のコンポーネントの数値は、色空間なしでは意味がありません。
MetalPetalが色空間をどのように処理するかを継続する前に、色空間とは何か、それが色の値の表現にどのように影響するかを知りたいかもしれません。カラースペースを説明する多くの記事があります。開始するために、提案はカラースペースです。
さまざまなソフトウェアとフレームワークには、色空間を処理するさまざまな方法があります。たとえば、PhotoshopにはデフォルトのSRGB IEC61966-2.1作業カラースペースがあり、コア画像はデフォルトでは線形SRGBの動作カラー空間を使用します。
メタルテクスチャは、カラースペース情報を保存しません。 MetalPetalの色空間のほとんどは、画像データの入力( MTIImage(...) )および出力( MTIContext.render... )中に発生します。
入力用の色空間を指定することは、MetalPetalがテクスチャの作成中にソースカラー値を指定された色空間に変換することを意味します。
URLまたはCGImageからロードするときは、 MTICGImageLoadingOptionsを使用して、テクスチャデータを使用したい色空間を指定できます。画像をロードするときにオプションを指定しない場合、デバイスRGBカラースペースが使用されます( MTICGImageLoadingOptions.default )。 nil色空間は色のマッチングを無効にします。これは、入力画像の色空間を使用してMTICGImageLoadingOptionsを作成することと同等です。指定されたカラースペースのモデルがRGBでない場合、デバイスRGBカラースペースはフォールバックとして使用されます。
CIImageからロードするときは、 MTICIImageRenderingOptionsを使用して、テクスチャデータを使用する色空間を指定できます。 CIImageロード時にオプションを指定しない場合、デバイスRGBカラースペースが使用されます( MTICIImageRenderingOptions.default )。 nilカラースペースは色の一致を無効にし、色の値はCIContextの動作色空間にロードされます。
出力用のカラースペースを指定する場合、カラースペースは、出力の色値を表す方法についてシステムの残りの部分と通信するために使用されるタグのように機能します。実際のカラースペース変換は実行されません。
MTIContext.makeCGImage...またはMTIContext.startTaskTo... colorSpaceパラメーターを使用して、出力CGImageの色空間を指定できます。
MTICIImageCreationOptionsを使用して、出力CIImageの色空間を指定できます。
MetalPetalは、出力カラースペースが指定されていない場合、出力色の値がデバイスRGBカラースペースにあると想定しています。
CVPixelBufferのカラースペースMetalPetalは、 CVMetalTextureCacheとIOSurfaceを使用して、 CVPixelBuffer Sを金属テクスチャに直接マッピングします。そのため、 CVPixelBufferからロードまたはレンダリングするためのカラースペースを指定することはできません。ただし、マッピングにSRGBピクセル形式でテクスチャを使用するかどうかを指定できます。
金属では、ピクセル形式名に_sRGB接尾辞がある場合、ピクセルの色の値の読み取りと書き込み中にSRGBガンマ圧縮と減圧が適用されます。つまり、 _sRGBピクセル形式のテクスチャは、シェーダーで色の値が読み取られると、SRGBから線形RGB変換が実行される場合、保存する色の値がSRGBガンマ修正されていると想定しています。色の値がシェーダーで記述されると、線形RGBからSRGB変換が実行されます。
MTIRGBColorSpaceConversionFilterを使用して、カラースペース変換を実行できます。カラースペース変換機能は、 MTIShaderLib.hでも利用できます。
metalpetal::sRGBToLinear (SRGB IEC61966-2.1から線形SRGBへ)metalpetal::linearToSRGB (線形SRGBからSRGB IEC61966-2.1)metalpetal::linearToITUR709 (Linear SRGBからITU-R 709)metalpetal::ITUR709ToLinear (ITU-R 709から線形SRGBへ) MTISCNSceneRendererを使用して、 SCNSceneからMTIImage sを生成できます。 SceneKit Rendererの線形RGBカラースペースを処理することをお勧めします。問題#76 SceneKitの画像は通常よりも暗いです。
MTISKSceneRendererを使用して、 SKSceneからMTIImage sを生成できます。
CIImage sからMTIImage sを作成できます。
MTIContextを使用して、 CIImageにMTIImageをレンダリングできます。
MTICoreImageKernelまたはMTICoreImageUnaryFilterクラスを使用して、 CIFilter直接使用できます。 (Swiftのみ)
MetalPetaljsを参照してください
MetalPetAljsを使用すると、JavaScriptを使用してレンダリングパイプラインとフィルターを作成し、「The Cloud」からフィルター/レンダラーをダウンロードできるようにすることができます。
MTICGImageLoadingOptionsを受け入れるAPIを使用する代わりにURL CGImage MTKTextureLoaderOption受け入れるAPIを使用するAPIを使用することをお勧めします。
MTKTextureLoaderOptionを受け入れるAPIを使用する場合、MetalPetalはデフォルトでMTIDefaultTextureLoaderを使用してCGImage S、 URLの画像、および名前付き画像をロードします。 MTIDefaultTextureLoader 、 MTKTextureLoaderを内部で使用し、 MTKTextureLoaderの矛盾とバグのいくつかの回避策をパフォーマンスコストでいくつか持っています。 MTITextureLoaderプロトコルを実装して、独自のテクスチャローダーを作成することもできます。次に、 MTIContextを作成するときに、Texture LoaderクラスをMTIContextOptions.textureLoaderClassに割り当てます。
Cocoapodsを使用して、最新バージョンをインストールできます。
use_frameworks!
pod 'MetalPetal'
# Required if you are using Swift.
pod 'MetalPetal/Swift'
# Recommended if you'd like to run MetalPetal on Apple silicon Macs.
pod 'MetalPetal/AppleSilicon'
SwiftSwiftへのマッピングを改善するために、Objective-C APIの迅速な追加と変更を提供します。 Swiftを使用している場合は強くお勧めします。
AppleSiliconAppleシリコンMacのプログラム可能なブレンディングサポートを可能にするために必要な金属シェーディング言語v2.3でコンパイルされたデフォルトのシェーダーライブラリを提供します。
アプリにパッケージの依存関係を追加します
MetalPetalは、Xcode 11+およびMacOS 10.15+でシミュレータで実行できます。
MetalPerformanceShaders.frameworkシミュレーターでは利用できないため、 MTIMPSGaussianBlurFilter 、 MTICLAHEFilterなどのMetalPerformanceShadersに依存するフィルターは機能しません。
シミュレーターは、実際のApple GPUよりも少ない機能または異なる実装制限をサポートしています。シミュレータで実行されるメタルアプリの開発を詳細に参照してください。
MTIImageを簡単に見てみると、その画像を作成するために構築した画像グラフが表示されます。

なぜObjective-C?
MetalPetalに貢献することを検討していただきありがとうございます。貢献ガイドラインをお読みください。
MetalPetalはMITライセンスです。ライセンス
/MetalPetalExamplesディレクトリのファイルは、別のライセンスの下でライセンスされています。 license.md
ドキュメントは、CC-by-4.0のライセンスを取得しています。