Metalでテクスチャから補正せずにサンプリングする
2019年8月28日 (水) 05:44時点における124.87.119.49 (トーク)による版
アップルが公式配布しているMetalでコンピュートシェーダーを叩く超入門的なサンプルプログラム「Hello Compute」というものがある。
これはコンピュートシェーダーでテスクチャを画像処理して新たなテクスチャを得て、それをフラグメントシェーダーで描画するという内容であり、いわゆるハロワに相当するものだ。
ただ、これはフラグメントシェーダーでの描画の際に画像補正がかかってしまっている。 コンピュートシェーダー部分を差し替えて色々試していたのだが、どうやっても画像が歪んでしまいバグってるのかと思ったが、よくよく考えるとフラグメントシェーダーでの描画の際に画像補正がかかってしまっているのだった。
HLSLの場合
HLSLでテクスチャサンプリングの際に画像補正したくない場合は、サンプラーの設定でMinFilterやMagFilterにPOINTを設定し、画像補正を無効化する。
sampler Samp = sampler_state { Texture = <Tex>; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; };
Metalの場合
一方、MetalのサンプラーにはMinFilterやMgFilterにPOINT相当の設定がなく、サンプラーを経由すると強制的に補正がかかってしまう。このため等倍表示であっても画像がボヤけるという欠陥がある。
constexpr sampler textureSampler (mag_filter::linear, min_filter::linear); const half4 colorSample = colorTexture.sample (textureSampler, in.textureCoordinate);
これどうするんだと思ったがテクスチャにreadメソッドを発見。 サンプラーを経由せずにテクスチャからピクセルを読み取ればいいようだ。
ushort w = colorTexture.get_width(); ushort h = colorTexture.get_height(); ushort x = w * in.textureCoordinate.x ; ushort y = h * in.textureCoordinate.y ; const half4 colorSample = colorTexture.read(ushort2(pos));