私はc ++でopenglを使用して作成した進行中のゲームのアイデアを持っています。プレイヤーが何かに勝ったときに、複数の重複するオブジェクトに大きなアウトライン(5〜6ピクセル)が欲しいです。
最良の方法はステンシルバッファーを使用することだと思いましたが、ステンシルバッファーを画面外にレンダリングしようとするのは数時間であり、どんな種類の結果も達成できないので、大したことはありません。他にもいくつかテクニックがあります!
これは私が入手したいものです:
何か案は?
私はc ++でopenglを使用して作成した進行中のゲームのアイデアを持っています。プレイヤーが何かに勝ったときに、複数の重複するオブジェクトに大きなアウトライン(5〜6ピクセル)が欲しいです。
最良の方法はステンシルバッファーを使用することだと思いましたが、ステンシルバッファーを画面外にレンダリングしようとするのは数時間であり、どんな種類の結果も達成できないので、大したことはありません。他にもいくつかテクニックがあります!
これは私が入手したいものです:
何か案は?
回答:
ここに私が働いているいくつかのwebGLステンシルコードから適応されたコードがあります:
// drawing will set stencil stencil
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(gl.ALWAYS,1,1);
gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
gl.stencilMask(1);
gl.clearStencil(0);
gl.clear(gl.STENCIL_BUFFER_BIT);
// draw objects
for(var object in objects)
objects[object].draw();
// set stencil mode to only draw those not previous drawn
gl.stencilFunc(gl.EQUAL,0,1);
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
gl.stencilMask(0x00);
// draw object halo
for(var object in objects)
objects[object].drawHalo(1.1,red); // each mesh should be individually scaled e.g. by 1.1
// done
gl.disable(gl.STENCIL_TEST);
RTSゲームでこのアプローチを使用して、選択したユニットの周りにハローを描画したと思いますが、それはずっと前のことであり、問題やニュアンスがあったかどうかは覚えていません。
オブジェクトのすべてのグループを見つけることから始めます。オブジェクトのグループは、重複するオブジェクトのコレクションです。標準の衝突検出でうまくいくはずです。各グループに一意の色を割り当てます。どの色でもかまいません。
すべてのオブジェクトを、グループカラーを使用して無地の色としてテクスチャにレンダリングします。
レンダーターゲットと同じサイズの新しいアウトラインテクスチャを作成します。レンダーターゲットの各テクセルをスキャンして、周囲のテクセルと異なる色かどうかを確認します。その場合は、アウトラインテクスチャの対応するテクセルを必要な線の色に変更します。
最後に、このアウトラインテクスチャを取得して、画面に描画したい画像の上にレンダリングします(もちろん、フラグメントシェーダーでのエッジ検出と同時にこれを行うことができ、最初のエッジテクスチャの作成を回避できます)場所)。
forループを使用してレンダーターゲットのテクセルを通過することにより、CPUでこの手順を実行する場合、これはかなり遅くなりますが、場合によってはテストして使用するのに十分です。これをリアルタイムで使用するには、これをシェーダーで処理するのが最善です。
このエッジ検出を行うフラグメントシェーダーは次のようになります。
precision mediump float;
uniform sampler2D s_texture;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = vec4(0.0);
vec4 baseColor = texture2D(s_texture, v_texCoord);
gl_FragColor += baseColor - texture2D(s_texture, top);
gl_FragColor += baseColor - texture2D(s_texture, topRight);
gl_FragColor += baseColor - texture2D(s_texture, right);
gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
gl_FragColor += baseColor - texture2D(s_texture, bottom);
gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
gl_FragColor += baseColor - texture2D(s_texture, left);
gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}
texture2Dルックアップの2番目の値は、v_texCoordを基準とした2D座標です。これを適用するには、最初のレンダーターゲットをテクスチャとしてフルスクリーンクワッドにレンダリングします。これは、ガウスぼかしなどの全画面ぼかし効果を適用する方法に似ています。
最初のレンダーターゲットを単色で使用する理由は、異なるオブジェクトの間に重なるエッジが認識されないようにするためです。画面イメージで単純にエッジ検出を実行した場合は、オーバーラップでもエッジを検出していることがわかります(オブジェクトの色/テクスチャ/ライティングが異なる場合)。