6

単純なパーティクル システムを実装する方法をいくつか試しています。ここでは、すべて固有の fbo にアタッチされたいくつかのテクスチャ間でピンポン テクニックを使用しています。

A テクスチャからのデータを使用して B テクスチャに書き込むことがわかるので、すべてのバインディング/セットアップは正しいと思います。

問題は、B テクスチャの 1 つのテクセルのみが書き込まれていることです。

問題

この画像では、テクセルをソース テクスチャからコピー先テクスチャにコピーしようとしています。

それでは、コードに行きましょう:

設定コード

#define NB_PARTICLE 5

GLuint fbo;
GLuint tex[6];
GLuint tex_a[3];
GLuint tex_b[3];
int i;

// 3 textures for position/vitesse/couleur
// we double them for ping-pong so 3 * 2 = 6 textures
glGenTextures(6, tex);

for (i = 0 ; i < 6 ; i++ )
{
    glBindTexture(GL_TEXTURE_1D, tex[i]);
    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, NB_PARTICLE, 0, GL_RGBA, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
}

for (i = 0; i < 3; i++)
{
    tex_a[i] = tex[i];
    tex_b[i] = tex[i + 3];
}

// Uploads particle data from "a" textures
glBindTexture(GL_TEXTURE_1D, tex_a[0]);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, NB_PARTICLE, 0, GL_RGBA, GL_FLOAT, seed_pos);
glBindTexture(GL_TEXTURE_1D, tex_a[1]);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, NB_PARTICLE, 0, GL_RGBA, GL_FLOAT, seed_vit);
glBindTexture(GL_TEXTURE_1D, tex_a[2]);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, NB_PARTICLE, 0, GL_RGBA, GL_FLOAT, seed_color);

// Create the fbo
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

// Attach the textures to the corresponding fbo color attachments
int i;
for (i = 0; i < 6; i++)
    glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_1D, tex[i], 0);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

レンダリングコード

static int pingpong = 1;

glUseProgram(integratorShader);
glBindVertexArray(0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

// Set the input textures to be the "a" textures
int i;
for (i = 0 ; i < 3 ; i++ )
{
    glActiveTexture(GL_TEXTURE0 + i);
    glBindTexture(GL_TEXTURE_1D, tex_a[i]);
}

// Set the draw buffers to be the "b" textures attachments
glDrawBuffers(3, GL_COLOR_ATTACHMENT0 + (pingpong * 3) );

glViewport(0, 0, NB_PARTICLE, 1);

glDrawArrays(GL_POINTS, 0, NB_PARTICLE);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glUseProgram(0);

// A became B and B became A
swapArray(tex_a, tex_b, 3);
pingpong++;
pingpong %= 2;

頂点シェーダー

#version 430

void main() {

    gl_Position = vec4(gl_VertexID, 0, 0, 1);

}

フラグメントシェーダー

#version 430

// binding = texture unit
layout (binding = 0) uniform sampler1D position_texture;
layout (binding = 1) uniform sampler1D vitesse_texture;
layout (binding = 2) uniform sampler1D couleur_texture;

// location = index in the "drawBuffers" array
layout (location = 0) out vec4 position_texel;
layout (location = 1) out vec4 vitesse_texel;
layout (location = 2) out vec4 couleur_texel;

void main() {

    vec4 old_position_texel = texelFetch(position_texture, int(gl_FragCoord.x), 0);
    vec4 old_vitesse_texel =  texelFetch(vitesse_texture, int(gl_FragCoord.x), 0);
    vec4 old_couleur_texel =  texelFetch(couleur_texture, int(gl_FragCoord.x), 0);

    position_texel = old_position_texel;
    vitesse_texel = old_vitesse_texel;
    couleur_texel = old_couleur_texel;
}

私は 1D テクスチャを使用しているので、送信する必要がある唯一のデータはインデックスであり、そのために gl_VertexID を完全に使用できると考えました。そのため、0 属性データを送信しています。

問題は gl_FragCoord を設定する方法だと思います (悲しいことに、デバッグできない唯一の変数です:()

4

1 に答える 1