私は、ゲームの世界を移動する際に、レベルデータ(シェーダーを含む)をストリームする大規模なゲームを開発しています。シェーダーがコンパイル/リンクされたり、初めて使用されたりすると、フレームレートにヒッチがないようにしたいと思います。独自のコンテキストで背景スレッドのシェーダを予熱できますか?
シェイダーのコンパイルとリンクは、独自のopen-glコンテキストを持つ別のスレッドで動作します。しかし、シェーダの予熱を別のスレッドで処理することはできませんでした(シェーダが最初に使用されたときにパフォーマンスが低下することはありません)。
予熱は実際にはiOSまたはOpenGLドキュメントのどこにも記載されていません。ただし、OpenGL ESアナライザ(xcodeからプロファイリングする際に使用できる計測器の1つ)に記載されています。このツールでは、以前に何かをレンダリングするのに使用されていないシェーダで何かがレンダリングされるたびに、 "予熱段階の外にシェーダをコンパイルしました"という警告が表示されます。
"OpenGL ESアナライザは、初期予熱段階の一部ではないシェーダのコンパイルを検出しました。シェーダのコンパイルには時間がかかることがあります。これらを避けるには、レンダリングに使用するすべてのシェーダを予熱します。これを行うには、あなたのアプリケーションが起動され、使用される各シェーダープログラムで描画呼び出しを実行し、シェーダープログラムが使用される任意のgl状態設定を使用してブレンド、カラーマスク、ロジックオプション、マルチスキャン、テクスチャ形式、およびポイントプリミティブ状態は、すべてシェーダのコンパイルに影響します。
「コンパイル」という用語はここで少し混乱します。頂点シェーダとフラグメントシェーダはすでにコンパイルされており、プログラムはリンクされています。しかし、何かが与えられたOpenGL状態で最初にレンダリングされるとき、それはシェイダー上で、私が推測するその状態のためにそれを最適化するために、より多くの作業を行います。
私は最初に使用する前にゼロサイズの三角形をレンダリングすることによってシェーダを予熱するコードを用意しています。
メインフレーム上のシェーダをコンパイルしてリンクして、通常のレンダリングと同じOpenGLコンテキストでプリウォーミングしている場合は動作します。しかし、別のOpen GLコンテキストを使用してバックグラウンドスレッド上で実行すると、動作しません(最初の使用時にAnalyzerの警告が表示されます)。
だから、別のコンテキストでシェーダを予熱することは、他のコンテキストに影響を与えないことがあります。あるいは、私は別の文脈をすべて同じ状態に設定する必要はありません。設定が必要なOpenGLの潜在的な可能性があります。バックグラウンドスレッドでオフスクリーンのレンダリングバッファを使用しているため、状態の一部と考えることができます。
予備的なウォームをバックグラウンドスレッドで処理することに成功した人はいますか?
リンクありがとうございます。私はこの問題がPC上にも存在していることを知りました。私は、OpenGL ESでのこのような人々の経験にもっと興味があります。誰かがiOSや別のOpenGL ESプラットフォームでこの作業をして、知っていれば大丈夫です。それ以外の場合は、レベルで使用できるすべてのシェーダと使用されているコンテキストを事前に計算し、最初のロード中にそれらをあらかじめ暖めておくシステムの開発に頼る必要があります。 – Namaste
期限切れのAtiのリンク。新しいもの:http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/ATI_OpenGL_Programming_and_Optimization_Guide.pdf –