2012-03-07 22 views
10

これは簡単ではないようですが、ポイントスプライトでテクスチャの一部を使用するのは非常に困難です。私は広範囲にグーグルグーグルで様々な答えを出しましたが、これらのどれもが私が持っている特定の問題に対処していません。 +スプライトシートのスプライトを指しiOSのポイントスプライトにテクスチャ(スプライトシート/テクスチャマップ)の一部を適用するOpenGL ES 2.0

  1. Basics of point sprite drawing
  2. How to deal with point sprites rendering as solid squares
  3. How to alter orientation of a point sprite
  4. How to use multiple textures with a point spriteを、ここに近づいてきて...
  5. されています:私はこれまで学んできたが、

    以前に行われましたが、OpenGL ES 2.0(1.0ではなく)でのみ可能です

    • 私が働いてポイントスプライトのセットを持っている:ここでは

私がでてるPoint sprite diagram

私が達成しようとしているものの図です。すべて同じ単一の正方形の画像を使用します。例:円の16x16画像がうまくいきます。

  • 複数の画像を含むスプライトシートを含む600x600画像を生成するObjective-Cメソッドがあります。 GL_TRIANGLESで描画されたクワッドにスプライトシートイメージ全体を適用することでこれが機能していることを確認しました。
  • 私は上記の方法を使ってスプライトシートの一部をクワッドに描画しました。私はちょうどポイントスプライトで動作するようにそれを得ることができません。
  • 現在、私はターゲットとするスプライトシート上のスプライトの中心を指すテクスチャ座標を生成しています。例:下の画像を使用する。星:0.166,0.5;曇り:0.5,0.5;心臓:0.833,0.5。
  • コード:

    バーテックスシェーダ

    uniform mat4 Projection; 
    uniform mat4 Modelview; 
    uniform float PointSize; 
    
    attribute vec4 Position; 
    attribute vec2 TextureCoordIn; 
    
    varying vec2 TextureCoord; 
    
    void main(void) 
    { 
        gl_Position = Projection * Modelview * Position; 
        TextureCoord = TextureCoordIn; 
        gl_PointSize = PointSize; 
    } 
    

    フラグメントシェーダ私が上でこだわって何

    varying mediump vec2 TextureCoord; 
    uniform sampler2D Sampler; 
    
    void main(void) 
    { 
        // Using my TextureCoord just draws a grey square, so 
        // I'm likely generating texture coords that texture2D doesn't like. 
        gl_FragColor = texture2D(Sampler, TextureCoord); 
    
        // Using gl_PointCoord just draws my whole sprite map 
        // gl_FragColor = texture2D(Sampler, gl_PointCoord); 
    } 
    

    1. フラグメントシェーダーでgl_PointCoord変数を使用する方法がわかりません。最初にgl_PointCoordには何が含まれていますか?どうして?データはどこにありますか?
    2. どのようなテクスチャ座標が渡されるのか分かりません。たとえば、ポイントスプライトは、スプライトシートのどの部分をテクスチャ座標に基づいて使用するのですか?私は効果的に4セットのテクスチャ座標(各頂点ごとに1つ)を持つ四角形を描画するのに慣れていますが、これはどのように異なっていますか?
    +0

    まだ立ち往生、誰もが持っている例シェーダ? –

    +0

    ソートされました、以下の回答。 –

    答えて

    10

    私の同僚が答えを助けました。そのトリックは、ポイントのサイズ(OpenGL単位)とスプライトのサイズ(テクスチャ単位で(0..1))の両方を小さなベクトル計算と組み合わせて使用​​することですスプライトシートを各ポイントに貼り付けます。彼らが共有できる

    バーテックスシェーダ

    uniform mat4 Projection; 
    uniform mat4 Modelview; 
    // The radius of the point in OpenGL units, eg: "20.0" 
    uniform float PointSize; 
    // The size of the sprite being rendered. My sprites are square 
    // so I'm just passing in a float. For non-square sprites pass in 
    // the width and height as a vec2. 
    uniform float TextureCoordPointSize; 
    
    attribute vec4 Position; 
    attribute vec4 ObjectCenter; 
    // The top left corner of a given sprite in the sprite-sheet 
    attribute vec2 TextureCoordIn; 
    
    varying vec2 TextureCoord; 
    varying vec2 TextureSize; 
    
    void main(void) 
    { 
        gl_Position = Projection * Modelview * Position; 
        TextureCoord = TextureCoordIn; 
        TextureSize = vec2(TextureCoordPointSize, TextureCoordPointSize); 
    
        // This is optional, it is a quick and dirty way to make the points stay the same 
        // size on the screen regardless of distance. 
        gl_PointSize = PointSize/Position.w; 
    } 
    

    フラグメントシェーダ

    varying mediump vec2 TextureCoord; 
    varying mediump vec2 TextureSize; 
    uniform sampler2D Sampler; 
    
    void main(void) 
    { 
        // This is where the magic happens. Combine all three factors to render 
        // just a portion of the sprite-sheet for this point 
        mediump vec2 realTexCoord = TextureCoord + (gl_PointCoord * TextureSize); 
        mediump vec4 fragColor = texture2D(Sampler, realTexCoord); 
    
        // Optional, emulate GL_ALPHA_TEST to use transparent images with 
        // point sprites without worrying about z-order. 
        // see: http://stackoverflow.com/a/5985195/806988 
        if(fragColor.a == 0.0){ 
         discard; 
        } 
    
        gl_FragColor = fragColor; 
    } 
    
    +0

    私はこれにいくつかの問題があり、誰かが私を助けてくれるのだろうかと疑問に思います。私のスプライトシートの総サイズは640×640です.5行で5スプライトで。したがって、各スプライトは128 x 128です。私のPointSizeは50です。私はこのコードをフラグメントシェーダに追加しています。 vec2 TextureCoord = vec2(0、0); //これはスプライトシートの左上にあると思います。 vec2 TextureSize = vec2(128、128); //これがPointSize(50)かスプライトサイズ(128)の場合はわかりません。 mediump vec2 realTexCoord = TextureCoord +(gl_PointCoord * TextureSize); vec4 rotatedTexture = texture2D(texture、realTexCoord); – Kahless

    4

    ポイントスプライトは単一の位置で構成されています。したがって、「変動する」値は実際にはに変化しません。その間には何も挿入されないからです。

    gl_PointCoordは、vec2の値であり、XY値は[0,1]の間です。それらはポイント上の位置を表す。 (0,0)は点の左下、(1,1)は右上です。

    したがって、スプライトの左下に(0、0)、右上に(1,1)をマッピングします。これを行うには、スプライトのサイズ(すべて同じサイズであることが前提)、テクスチャのサイズ(テクスチャの取り込み関数はピクセル位置ではなく正規化されたテクスチャ座標をとるため)、スプライトが現在レンダリングされているのはです。

    varyingで設定できます。これは、頂点シェーダーのvaryingに頂点ごとのデータとして渡される値にすぎません。

    スプライトのサイズに加えて、このスプライトのテクスチャ内のデータを取得する場所を指定します。使用するテクセル座標を取得したら、それらをテクスチャサイズで割って正規化テクスチャ座標を生成します。

    いずれにしても、ポイントスプライトは、実際にはスプライトレンダリングのためのものではありません。すべてのポジションを正確に把握できるので、クワッド/トライアングルを使用する方が簡単です。

    +0

    あなたのお返事ありがとうございますNicol。だから私はほぼそこにいるようです。 TextureCoordInは基本的にどのスプライトをレンダリングするかを示すXY(0..1)ポイントです。私はスプライトのサイズ、スプライトシート/テクスチャのサイズなどを持っています。しかし、私は混乱していますが、これをどのようにまとめているかです。私はウェブ上に浮かんでいる例題を見て、 'gl_PointCoord'に対して数学を行い、レンダリングするテクスチャの部分を決定しています。' gl_FragColor = texture2D(Sampler、gl_PointCoord + SomeOtherVec2); '正しいシェーダーの例を教えてくれますか? –

    +0

    私はGLSL(そして一般的にはOpenGL)にはかなり新しく書かれています。 「あなたのスプライトの左下に(0、0)をマッピングする」と「このスプライトのデータをプルする」と言うときはどういう意味ですか?ありがとう。 –

    関連する問題