「Metalでテクスチャから補正せずにサンプリングする」の版間の差分

提供: MonoBook
ナビゲーションに移動 検索に移動
1行目: 1行目:
 
[[アップル]]が公式配布している[[Metal]]で[[コンピュートシェーダー]]を叩く超入門的なサンプルプログラム「Hello Compute」というものがある。
 
[[アップル]]が公式配布している[[Metal]]で[[コンピュートシェーダー]]を叩く超入門的なサンプルプログラム「Hello Compute」というものがある。
* https://developer.apple.com/documentation/metal/hello_compute?language=objc
+
 
 +
*https://developer.apple.com/documentation/metal/hello_compute?language=objc
  
 
これは[[コンピュートシェーダー]]で[[テスクチャ]]を画像処理して新たなテクスチャを得て、それをフ[[ラグメントシェーダー]]で描画するという内容であり、いわゆる[[ハロワ]]に相当するものだ。
 
これは[[コンピュートシェーダー]]で[[テスクチャ]]を画像処理して新たなテクスチャを得て、それをフ[[ラグメントシェーダー]]で描画するという内容であり、いわゆる[[ハロワ]]に相当するものだ。
7行目: 8行目:
 
[[コンピュートシェーダー]]部分を差し替えて色々試していたのだが、どうやっても画像が歪んでしまい[[バグ]]ってるのかと思ったが、よくよく考えるとフラグメントシェーダーでの描画の際に画像補正がかかってしまっているのだった。
 
[[コンピュートシェーダー]]部分を差し替えて色々試していたのだが、どうやっても画像が歪んでしまい[[バグ]]ってるのかと思ったが、よくよく考えるとフラグメントシェーダーでの描画の際に画像補正がかかってしまっているのだった。
  
== HLSLの場合 ==
+
==HLSLの場合==
 
[[HLSL]]でテクスチャサンプリングの際に画像補正したくない場合は、サンプラーの設定でMinFilterやMagFilterにPOINTを設定し、画像補正を無効化する。
 
[[HLSL]]でテクスチャサンプリングの際に画像補正したくない場合は、サンプラーの設定でMinFilterやMagFilterにPOINTを設定し、画像補正を無効化する。
 
     sampler Samp = sampler_state
 
     sampler Samp = sampler_state
19行目: 20行目:
 
     };
 
     };
  
== Metalの場合 ==
+
==Metalの場合==
 
一方、[[Metal]]のサンプラーにはMinFilterやMgFilterにPOINT相当の設定がなく、サンプラーを経由すると強制的に補正がかかってしまう。このため等倍表示であっても画像がボヤけるという欠陥がある。
 
一方、[[Metal]]のサンプラーにはMinFilterやMgFilterにPOINT相当の設定がなく、サンプラーを経由すると強制的に補正がかかってしまう。このため等倍表示であっても画像がボヤけるという欠陥がある。
    constexpr sampler textureSampler (mag_filter::linear,
+
    constexpr sampler textureSampler (mag_filter::linear,
 
                                       min_filter::linear);
 
                                       min_filter::linear);
    const half4 colorSample = colorTexture.sample (textureSampler, in.textureCoordinate);
+
    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(x,y));
 +
Metalではテクスチャのサイズをget_widthやget_heightで簡単に取得できるので[[ソースコード]]の見通しが非常によい。[[HLSL]]や[[GLSL]]ではいちいち[[ユニフォーム変数]]などでテクスチャとは別に渡しておかねばならず非常に面倒だった点が改善されている。
  
これどうするんだと思ったが[[テクスチャ]]に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));
 
  
== 関連項目 ==
+
*[[Xamarin.MacでMetalに対応したMacかを判定する]]
* [[Xamarin.MacでMetalに対応したMacかを判定する]]
+
*[[MonoGameで直線を描画する]]
* [[MonoGameで直線を描画する]]
+
*[[Metal Shading Language]]
* [[Metal Shading Language]]
+
*[[プログラマブルシェーダー]]
* [[プログラマブルシェーダー]]
+
*[[シェーダー]]
* [[シェーダー]]
 
  
 
[[category: macOS]]
 
[[category: macOS]]
 
[[category: iOS]]
 
[[category: iOS]]
 
[[category: Metal]]
 
[[category: Metal]]

2019年8月28日 (水) 05:52時点における版

アップルが公式配布している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(x,y));

Metalではテクスチャのサイズをget_widthやget_heightで簡単に取得できるのでソースコードの見通しが非常によい。HLSLGLSLではいちいちユニフォーム変数などでテクスチャとは別に渡しておかねばならず非常に面倒だった点が改善されている。

関連項目