6

iPhoneシェーダーGLSLES1.1で3x3カーネルを使用して畳み込みを実行しています。現在、9つのテクスチャルックアップを行っています。より速い方法はありますか?いくつかのアイデア:

  • テクスチャ補間の呼び出しを回避するために、入力画像をテクスチャではなくバッファとして渡します。

  • 頂点シェーダーから9つの異なるvec2座標を渡すことで(現在行っている1つだけではなく)、プロセッサーがテクスチャを効率的にプリフェッチするように促します。

  • これに適している可能性のあるさまざまなApple拡張機能を調べます。

  • (追加)GLSLシェーダーオフセット呼び出しに相当するESを調査します(これはESでは使用できませんが、おそらく同等のものがあります)

ハードウェアに関しては、特にiPhone4Sに焦点を当てています。

4

2 に答える 2

7

OpenGL ES 2.0 のことではないですか? OpenGL ES 1.1 を使用してあらゆる種類のシェーダーを実行することはできません。前者とします。

私の経験では、これを行うための最速の方法は、2 番目にリストされているアイテムです。私はGPUImageフレームワークでいくつかのタイプの 3x3 畳み込みを行い (独自のロールを試行する代わりに使用できます)、水平方向と垂直方向のテクスチャ オフセットをフィードし、頂点内で必要な 9 つのテクスチャ座標を計算します。シェーダー。そこから、変数としてフラグメント シェーダーに渡します。

これにより (ほとんどの場合)、iOS PowerVR GPU では非常にコストがかかるフラグメント シェーダーでの依存テクスチャ読み取りが回避されます。iPhone 4 のような古いデバイスでは、依存するテクスチャの読み取りを避けるために、これらの変数のうち 8 つしか使用されないため、「ほとんどの場合」と言います。先週学んだように、9 番目は古いデバイスで依存するテクスチャの読み取りをトリガーするため、動作が少し遅くなります。ただし、iPhone 4S では、この方法で使用されるより多くの変数をサポートしているため、この問題はありません。

頂点シェーダーには以下を使用します。

 attribute vec4 position;
 attribute vec4 inputTextureCoordinate;

 uniform highp float texelWidth; 
 uniform highp float texelHeight; 

 varying vec2 textureCoordinate;
 varying vec2 leftTextureCoordinate;
 varying vec2 rightTextureCoordinate;

 varying vec2 topTextureCoordinate;
 varying vec2 topLeftTextureCoordinate;
 varying vec2 topRightTextureCoordinate;

 varying vec2 bottomTextureCoordinate;
 varying vec2 bottomLeftTextureCoordinate;
 varying vec2 bottomRightTextureCoordinate;

 void main()
 {
     gl_Position = position;

     vec2 widthStep = vec2(texelWidth, 0.0);
     vec2 heightStep = vec2(0.0, texelHeight);
     vec2 widthHeightStep = vec2(texelWidth, texelHeight);
     vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);

     textureCoordinate = inputTextureCoordinate.xy;
     leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;
     rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;

     topTextureCoordinate = inputTextureCoordinate.xy - heightStep;
     topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;
     topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;

     bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;
     bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;
     bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;
 }

およびフラグメント シェーダー:

 precision highp float;

 uniform sampler2D inputImageTexture;

 uniform mediump mat3 convolutionMatrix;

 varying vec2 textureCoordinate;
 varying vec2 leftTextureCoordinate;
 varying vec2 rightTextureCoordinate;

 varying vec2 topTextureCoordinate;
 varying vec2 topLeftTextureCoordinate;
 varying vec2 topRightTextureCoordinate;

 varying vec2 bottomTextureCoordinate;
 varying vec2 bottomLeftTextureCoordinate;
 varying vec2 bottomRightTextureCoordinate;

 void main()
 {
     mediump vec4 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate);
     mediump vec4 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate);
     mediump vec4 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate);
     mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);
     mediump vec4 leftColor = texture2D(inputImageTexture, leftTextureCoordinate);
     mediump vec4 rightColor = texture2D(inputImageTexture, rightTextureCoordinate);
     mediump vec4 topColor = texture2D(inputImageTexture, topTextureCoordinate);
     mediump vec4 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate);
     mediump vec4 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate);

     mediump vec4 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2];
     resultColor += leftColor * convolutionMatrix[1][0] + centerColor * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2];
     resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2];

     gl_FragColor = resultColor;
 }

上記の注意事項があっても、このシェーダーは iPhone 4 の 640x480 フレームのビデオで約 2 ミリ秒で実行され、4S はこのようなシェーダーを使用して 30 FPS で 1080p ビデオを簡単に処理できます。

于 2012-06-23T01:25:02.737 に答える
0

分離されたガウス スタイルのぼかしで 2 つのパスを実行しないのはなぜですか? 最初のパスで垂直方向に 3 回タップし、2 回目のパスで水平方向に 3 回タップします。

于 2012-08-17T08:00:56.487 に答える