0

Stage3D を使用していると、予期せぬ事態に遭遇しました。オブジェクト用に 2 つの異なるシェーダー プログラムを作成しました。プログラムの 1 つは、テクスチャ ビットマップと UV データを使用するためのものです。もう 1 つは単純にカラー データを使用します。2 つのオブジェクトは非常に異なります。最終的には、無地の色と単純なレンダリング ロジックを使用していくつかのもの (方向線、ハイライトなど) を表示し、他のもの (実際のオブジェクト、背景など) をミップマップでレンダリングするなどです。前方へ。問題は、これら 2 つの非常に異なるシェーダー プログラムを使用すると、どちらか一方しか機能しないことです。したがって、色のみのオブジェクトがすべて表示されるか、テクスチャのみのオブジェクトがすべて表示されます。もちろん両方出してほしいです。

テクスチャ オブジェクトの agal コードは次のとおりです。

頂点シェーダー:

//4x4 matrix multiply to get camera angle
"m44 op, va0, vc0\n" + 
//tell fragment shader about xyz
"mov v0, va0\n" + 
//tell frament shader about uv
"mov v1, va1\n" + 
//tell fragment shader about RGBA
"mov v2, va2\n"

フラグメント シェーダー:

//grab the texture color from texture 0 and
//the uv coordinates from varying register 1 and
//store the interpolated value in ft0
"tex ft0, v1, fs0 <2d,linear,repeat,miplinear>\n" + 
//move this value to the output color
"mov oc, ft0\n"

これらのオブジェクトのレンダリング コードは次のようになります。

context3D.setProgram(_renderProgram);
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, renderMatrix, true);
context3D.setTextureAt(0, texture);

// vertex position to attribute register 0
context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setVertexBufferAt(1, uvBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
context3D.setVertexBufferAt(2, colorsBuffer, 0, Context3DVertexBufferFormat.FLOAT_4);

これは、プレーンな色のオブジェクト(つまり、テクスチャなし)の agal コードです。

頂点シェーダー:

"m44 op, va0, vc0\n" + // pos to clipspace
"mov v0, va1" // copy color

フラグメント シェーダー:

"mov oc, v0 "

これらのオブジェクトのレンダリング コードは次のようになります。

context3D.setProgram(_renderProgram); 
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, renderMatrix, true);
// vertex position to attribute register 0
context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
// color to attribute register 1
context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);

私が理解できない何らかの理由で、さまざまなデータをさまざまなレジスタ インデックス (va) に割り当てているという事実が原因で、レンダリング プロシージャの 1 つが失敗しています。テクスチャ ループで最初にテクスチャ オブジェクトをレンダリングすると、色付きのオブジェクトがすべて消え、その逆も同様です。オブジェクトは最初のフレームで正しく表示されます。しかし、レンダリング ループが 2 回目に再生されるとすぐに、この予期しない動作が発生します。

以下を追加してカラーオブジェクトのレンダリングコードを変更すると、次のことがわかりました。

context3D.setTextureAt(0, null);
context3D.setVertexBufferAt(2, null);

できます。しかし、これは本当に良い解決策ではありません。プログラムのどこかで別のオブジェクトが n 個の可変レジスタでレンダリングされていることを知りたくないので、別の program3D インスタンスが n 個未満のレジスタを必要とする場合、未使用のすべての va を null に設定する必要があります。また、4 番目の va が必要なオブジェクト (光っているオブジェクトなど) 用に新しいシェーダー プログラムを作成した場合は、戻って他のすべてのシェーダー プログラムを変更し、va4 を null に設定して、すべてがレンダリングされるようにする必要があります。これは本当ですか?確かに私はここで何かが欠けています。すべてのテクスチャ レジスタ (ft) を設定する場合も同じです。

もっと多くの情報を提供できます...

4

2 に答える 2

0

ここで古い投稿を掘り起こします。私はあなたのコメントに気づき、(主に将来の読者のために) あなたがつまずいたのは、実際には正しい解決策であることに言及したいと思いました。3D オブジェクトを画面に描画する準備をする場合、一般的なプロセスは次のようになります。

  • プログラムの定義/コンパイル/アップロード
  • 頂点とテクスチャをアップロードする
  • レンダリング ループを開始する
    • オブジェクトループを開始
      • セットプログラム
      • 定数を設定する
      • 入力バッファとテクスチャを設定する
      • drawTriangles() を呼び出す
      • 入力バッファとテクスチャを null に設定
    • オブジェクトループの終了
    • present() を呼び出す
  • レンダリング ループを終了する
于 2013-01-31T11:00:27.560 に答える
0

残念ながら、あなたは正しいようです-少なくともこれは私が見つけて実装した解決策です。以前に渡されたテクスチャは「クリア」する必要があります...

context3D.setTextureAt(<n>, null);

...そうしないと、テクスチャのないシェーダは引き続きテクスチャを期待し、レンダリングしません。

于 2013-03-07T09:31:24.740 に答える