単純なmix()を追加すると、フレームレートが破壊されます


7

私は非常にシンプルなシェーダーを使用しており、次のようなミックスを介して線形フォグを追加しました。

finalColor = mix(finalColor, vec3(0.5, 0.8, 0.95), vUVoutAndViewZ.z);

ビューのZ距離は、UV座標も含む変数内にあるため、フォグは新しい補間を追加していません。

それでも、この1本の無害なラインは、33 Spsから22 FpsのPower SGXチップセットを搭載したOG Droidのフレームレートをもたらしました。Adreno 200 GPUを備えたHTC Evoでも30fps未満にとどまります。(Adreno 205は一定の60fpsですが、それは獣です)。

フラグメントシェーダー自体はプリミティブです(テストシェーダーであるため、すべての値はハードコードされています)。

precision mediump float;
varying mediump vec3 vUVoutAndViewZ;
varying lowp vec3 vNormalOut;

uniform lowp sampler2D diffuse;


void main() {
    lowp vec3 normal = vNormalOut;

    // Lighting
    lowp vec3 lightDir = vec3(0.5, 0.3, 0.5);
    lowp vec3 light = vec3(dot(normal, lightDir));

    lowp vec3 diffuse = texture2D(diffuse, vUVoutAndViewZ.xy).rgb;

    lowp vec3 finalColor = diffuse * light;

    // Fog
    finalColor = mix(finalColor, vec3(0.5, 0.8, 0.95), vUVoutAndViewZ.z);

    gl_FragColor = vec4(finalColor.xyz, 1.0);
}

後でlowp / mediump宣言を追加しました(約2fpsを追加しました)。それなしでも同じように機能します。

PowerVRチップセットは非常に弱いため、このような単純なシェーダーを処理できないとは思いません。このシェーダーには、ユニットを完全に台無しにするだけの愚かなもの(暗黙的にlowpレジスターをスウィズルするようなもの)が必要です。

回答と編集:

エリスは答えとそれに続くコメントにいくつかの素晴らしい情報を持っています。この特定のケースでは、mix()は完全に壊れているようです。シェーダーを12サイクル(4から)および4 GPR(2から)にしました。代わりにこのコードを使用して29fpsに戻しました。

lowp vec3 fogDiff = vec3(0.5, 0.8, 0.95) - finalColor;
fogDiff *= vUVoutAndViewZ.z;
finalColor += fogDiff;

霧が深度に比例しないことを知っていますか?シェーダーにpow関数を追加することを恐れていない場合は、より現実的なものにしてみてください;)
Notabene

@notabene:私はそれを知っていますが、この投稿は単純なmix()フレームレートを殺す方法についてのものなpowので、それを終了するために投げ込む傾向があまりありませんでした。
EboMike、2011

回答:


5

PVRUniSCoエディターで計算されたEboMikeからの応答:mix()は、シェーダーを4サイクルから12サイクル(PowerVR)にします。

PowerVR 530/535は非常に遅いです。Andreno 200とPowerVR 530/535は、hdpi解像度用の最初のGPU世代(OpenGL ES 2.x)です。シンプルなテクスチャでは、60FPSでフルスクリーンを再描画することはできません。

シェーダーのパフォーマンスをテストするためにGPUBenchを作成しましたが、これらのGPUでは非常に悪いです。第2世代(Andreno 205、Powervr 540)ははるかに優れています。

今日、私は1つまたは2つの操作でフラグメントシェーダーを最小化しようとしています。GLSLコンパイラーは悪いので(モバイルプラットフォームでは)、シェーダーを最適化してみることができます。

注:powervr gpuについては、このドキュメントをお読みください。PVRUniSCo Editorは、シェーダーで使用されるサイクルを計算できます。

私の考え:

  • ドロイドGPUはアンドレノ200よりも遅いです
  • Andreno 200の30 FPSは良好です
  • ドロイドの20 FPSは良いです
  • 小さいFBOでシーンをレンダリングして画面に描画できます(ただし、FBOスイッチは高価です)
  • フラグメントシェーダーは非常に短くする必要があります。

あなたは私の心を壊しています!HTC Evoはどうですか?Adreno 200は少なくともそれを処理できませんか?弱いGPUであっても、それは不当に哀れです。
EboMike、2011

私の目標は、少なくともDroidとEVOで30fpsです。SEEMがかなり見栄えが良いBackbreakerのようなゲームを漠然と覚えています(見たのでしばらくの間、私は間違っているかもしれません)。ここの秘密は何ですか?オーバードローはなく、アルファブレンディングはほとんど使用していません。このシェーダーはプリミティブです。何か考えはありますか?(ところで、数時間以内に回答を受け入れますので、心配しないでください:))
EboMike

DroidまたはEVOの30 FPSは非常に困難です。これらのGPUのフィルレートは非常に低くなっています。
エリス

私はモバイルグラフィックチップセットについて何も知りませんが、あなたが最も興味深い部分を説明しなかったことに気づかざるを得ません。なぜ1行でパフォーマンスが劇的に低下するのですか?それは本当に遅いミックス操作ですか?
Nevermind

2
私は試していませんが、GLSL命令サイクルについては「PVRUniSCo Editor」をご覧ください。
エリス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.