OpenGL ES 2.0で末尾のパーティクルエフェクト(seen here)を作成しようとしています。残念ながら、これを可能にするOpenGLコマンド(累積バッファ)はOpenGL esでは使用できません。これは、LONGの道を行く必要があることを意味します。OpenGL ES 2.0で累積バッファをエミュレートする方法(末尾パーティクルエフェクト)
Thisトピックは、このようなことを行う可能な方法について説明しました。しかし、バッファ内に物を格納してバッファを結合する方法については、私はかなり混乱しています。だから私の考えは次のことをすることでした。
- 別のバッファに前のフレーム(ただし、フェード)を描画テクスチャ
- に書き込みバッファを使用してテクスチャに現在のフレームを描きます。
- 手順2のステップ1の上に置き、それを表示します。
- 次のフレームで使用するために表示される内容を保存します。
これまでのところ、バッファにはテクスチャと同じ方法でピクセルデータが格納されていましたが、バッファはシェーダを使用して簡単に描画できます。
だから、おそらくバッファにレンダリングしてテクスチャに移動させるという考えがあります。私は振り返ってみると、この
である、あなたは2 FBOs(独自の風合いを持つ各)を作成する必要が見つけ、これを行うための
一説。 デフォルトフレームバッファを使用すると信頼性がありません(内容は がフレーム間で保証されていません)。
最初のFBOをバインドした後、クリアしてシーンを正常にレンダリングします。 シーンがレンダリングされたら、テクスチャをソースとして使用し、ブレンディングを使用して を2番目のFBOにレンダリングします(2番目のFBOは決して がクリアされません)。これにより、新しいシーン とそれ以前のものが混在した2番目のFBOが作成されます。最後に、第2のFBOはウィンドウに直接レンダリングされた でなければなりません(これは、以前の操作と同様に テクスチャ付きクワッドをレンダリングするか、 glBlitFramebufferを使用して行うことができます)。
基本的に、最初のFBOはデフォルトのフレームバッファ の代わりに使用され、2番目のFBOは累積バッファの代わりに使用されます。要約する
:
初期化:各FBOについて
: - glGenTextures - glBindTexture - glTexImage2D - glBindFrameBuffer - glFramebufferTexture2D
各フレーム:
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER 、fbo1)glClear glDraw * // scene
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER、fbo2)glBindTexture(TEX1) glEnableです(GL_BLEND)glBlendFunc glDraw * //フルスクリーンクワッド
glBindFrameBuffer(GL_DRAW_FRAMEBUFFER、0) glBindFrameBuffer(GL_READ_FRAMEBUFFER、fbo2)glBlitFramebuffer
残念ながら、それはかなりのコードを持っていませんでした(特に初期化を開始するには)。
しかし私は試してみたところ、私が得たのは残念ながら空白の画面でした。私は何をしているのか本当に分かっていないので、おそらくこのコードはかなり間違っています。
var fbo1:GLuint = 0
var fbo2:GLuint = 0
var tex1:GLuint = 0
Init()
{
//...Loading shaders OpenGL etc.
//FBO 1
glGenFramebuffers(1, &fbo1)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo1)
//Create texture for shader output
glGenTextures(1, &tex1)
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
//FBO 2
glGenFramebuffers(1, &fbo2)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo2)
//Create texture for shader output
glGenTextures(1, &tex1)
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), GLenum(GL_UNSIGNED_BYTE), nil)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex1, 0)
}
func drawFullScreenTex()
{
glUseProgram(texShader)
let rect:[GLint] = [0, 0, GLint(width), GLint(height)]
glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
//Texture is allready
glTexParameteriv(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_CROP_RECT_OES), rect)
glDrawTexiOES(0, 0, 0, width, height)
}
fun draw()
{
//Prep
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo1)
glClearColor(0, 0.1, 0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
//1
glUseProgram(pointShader);
passTheStuff() //Just passes in uniforms
drawParticles(glGetUniformLocation(pointShader, "color"), size_loc: glGetUniformLocation(pointShader, "pointSize")) //Draws particles
//2
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), fbo2)
drawFullScreenTex()
//3
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), 0)
glBindFramebuffer(GLenum(GL_READ_FRAMEBUFFER), fbo2)
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_NEAREST))
}
ここに私が有用であると分かったいくつかの情報源があります。
私の主な質問は:誰かが、このためのコードを記述してもらえます。関係する理論を理解していると思いますが、私はそれを適用するのに無駄に努力しています。
場所を開始したい場合は、ドットを描画するXcode projectがあります。ここには定期的に画面上を移動する青色の矢印があります。また、動作していないコードも同様です。
注:コードを記述する場合は、任意の言語(C++、Java、Swift、Objective-C)を使用できます。 OpenGL-ES用であれば
なぜ粒子をフェードアウトするためにすべてのものの累積バッファを使用したいのですか? –
私は彼らに歩道を持たせる方法が必要です。最初のリンクのビデオを見てください。私はパーティクルの道が必要です。しかし、私はパーティクルの軌跡にたくさんのエンティティを使用したくありません。 –
粒子軌跡に本格的なエンティティが必要な理由はわかりません。単なる位置、方向(おそらく)、および時間。私のポイントは、蓄積バッファーメソッドは、レンダリングターゲットの切り替え(通常、モバイルハードウェア上の大きなパフォーマンスno-no)を含む多くの作業を必要とするということです。独自にフェードアウトするパーティクルは、まともなパーティクルシステムを必要とするだけです。 –