ポイントスプライトでテクスチャアニメーション

前回ジオメトリシェーダでポイントスプライトを実装しましたが、

このへんを見ると当然、テクスチャ座標を自分で設定したくなりますよね。

gl_TexCoord[0].st = vec2(0,0);
gl_TexCoord[0].st = vec2(0,1);
gl_TexCoord[0].st = vec2(1,0);
gl_TexCoord[0].st = vec2(1,1);

やることは至って単純で、右辺の0と1にあたる数値をCPUから設定してやるだけです。

0がUV位置、1がUV範囲と思えばわかりやすいかと思います。

両方をuniform変数で渡しても良いのですが、汎用性を考えてUV位置は頂点ごとに設定できるようにしました。

  • バーテックスシェーダ

    前回に加えて、glTexCoord2dでCPUから渡されたテクスチャ座標をジオメトリシェーダに渡してます。

    #version 120
    void main()
    {
     gl_Position = gl_Vertex;
     gl_TexCoord[0] = gl_MultiTexCoord0;
    }
    
  • ジオメトリシェーダ

    前回に加えて、テクスチャ座標の計算が入ってます。

    #version 120
    #extension GL_EXT_geometry_shader4 : enable
    uniform vec2 size; // 描画サイズ(CPUからglUniform2fで渡す)
    uniform vec2 size_uv; // UV範囲(CPUからglUniform2fで渡す)
    void main() {
     gl_Position = gl_ModelViewProjectionMatrix * gl_PositionIn[0];
     gl_Position.x -= size.x/2;
     gl_Position.y += size.y/2;
     gl_TexCoord[0] = gl_TexCoordIn[0][0];
     EmitVertex();
     gl_Position.y -= size.y;
     gl_TexCoord[0].t += size_uv.t;
     EmitVertex();
     gl_Position.x += size.x;
     gl_Position.y += size.y;
     gl_TexCoord[0].s += size_uv.s;
     gl_TexCoord[0].t -= size_uv.t;
     EmitVertex();
     gl_Position.y -= size.y;
     gl_TexCoord[0].t += size_uv.t;
     EmitVertex();
    }
    
  • フラグメントシェーダ

    そのまんまです。

    #version 120
    uniform sampler2D tex0;
    void main (void)
    {
     gl_FragColor = texture2D(tex0, gl_TexCoord[0].st);
    }
    

CPU側では、表示したいテクスチャをglBindTextureしてglUniform1iした上でこんな感じで描画しましょう。

glBegin(GL_POINTS)
glTexCoord2d(s,t);
glVertex3d(x,y,z);
glEnd();

これで、頂点に渡すテクスチャ座標を時間変化させるだけでテクスチャアニメーションができますね。