2012-02-27 9 views
1

私のiOSアプリケーションの最初のバージョンCoreboxを完成させたばかりで、今いくつかの新機能を開発中です。iOSでGL_LINESを使用してレンダリングされたオブジェクトの最小サイズOpen GL ES

新しい機能の1つは、OpenGLレンダリングの「小さな」微調整で、一部のオブジェクトを最小サイズよりも小さく描画しないようにしています。この処理を必要とするオブジェクトはすべて、GL_LINESで描画された単純な2点線です。

この注釈付きスクリーンショットは、私が何をしているのかを説明しています。灰色の線を無視して、私が変更に興味を持っている唯一のオブジェクトは、黄色いより広い線です。

Corebox OpenGL scene

私は広範囲にこれをGoogleで検索して、私が頂点シェーダを使用してラインの形状を変更されて何をする必要があるかと思われます。私はGLSLの新機能で、ライティングやその他のエフェクトを適用して見つけることができるほとんどのシェーダの例は、GLSL Heroku EditorKicksJS shader editorです。

私の現在の頂点シェーダは、非常に基本的なものです:

// GL_LINES vertex shader 
uniform mat4 Projection; 
uniform mat4 Modelview; 

attribute vec4 Position; 
attribute vec4 SourceColor; 

varying vec4 DestinationColor; 

void main(void) { 
    DestinationColor = SourceColor; 
    gl_Position = Projection * Modelview * Position; 
} 

私のフラグメントシェーダであるとして:

// GL_LINES fragment shader 
varying lowp vec4 DestinationColor; 

void main(void) { 
    gl_FragColor = DestinationColor; 
} 

必要とされるものについての私の推測:

  • は間の距離を決定ビューア(カメラ位置)とオブジェクト
  • Det
  • オブジェクトが小さすぎる場合は、画面に表示されるようにオブジェクトのサイズが大きくなるようにオブジェクトの頂点を調整します。

注意事項とその他の注意事項:

  1. しかし、あなたは、このモデルは、画面上のオレンジ色のちょうどブロブされることはありませんズームアウトか?はい、これはまさに私の後の効果です。

編集:ここで私は、コードをテストしていないが、それは解決策を説明する必要がありmifortin

uniform mat4 Projection; 
uniform mat4 Modelview; 
uniform float MinimumHeight; 

attribute vec4 Position; 
attribute vec4 ObjectCenter; 
attribute vec4 SourceColor; 

varying vec4 DestinationColor; 

void main(void) { 
    // screen-space position of this vertex 
    vec4 screenPosition = Projection * Modelview * Position; 
    // screen-space mid-point of the object this vertex belongs to 
    vec4 screenObjectCenter = Projection * Modelview * ObjectCenter; 

    // Z should be 0 by this time and the projective transform in w. 
    // scale so w = 1 (these two should be in screen-space) 
    vec2 newScreenPosition = screenPosition.xy/screenPosition.w; 
    vec2 newObjectCenter = screenObjectCenter.xy/screenObjectCenter.w; 

    float d = distance(newScreenPosition, newObjectCenter); 

    if (d < MinimumHeight && d > 0.0) { 
     // Direction of this object, this really only makes sense in the context 
     // of a line (eg: GL_LINES) 
     vec2 towards = normalize(newScreenPosition - newObjectCenter); 

     // Shift the center point then adjust the vertex position accordingly 
     // Basically this converts: *--x--* into *--------x--------* 
     newObjectCenter = newObjectCenter + towards * MinimumHeight; 
     screenPosition.xy = newObjectCenter.xy * screenPosition.w; 
    } 

    gl_Position = screenPosition; 
    DestinationColor = SourceColor; 
} 

答えて

2

ノートで提案を実施し、最終的な作業バージョンです。

シェーダを使用する場合は、ラインの中心位置にある別の均一なvec4を追加します。画面上の頂点を確保するために必要ならば、ブロブの中心からそれを伸ばし、描かれることになる

uniform float MIN; //Minimum size of blob on-screen 
uniform vec4 center; //Center of the line/blob 
... 
vec4 screenPos = Projection * Modelview * Position; 
vec4 center = Projection * Modelview * Position; 

//Z should be 0 by this time and the projective transform in w. 
//scale so w = 1 (these two should be in screen-space) 
vec2 nScreenPos = screenPos.xy/screenPos.w; 
vec2 nCenter = center.xy/center.w; 

float d = distance(nScreenPos, nCenter); 
if (d < MIN && d > 0) 
{ 
    vec2 towards = normalize(nScreenPos - nCenter); 
    nCenter = nCenter + towards * MIN; 

    screenPos.xy = nCenter.xy * screenPos.w; 
} 

gl_Position = screenPos; 

検索:次に、あなたは(ノートセンターは一度CPU上で事前に計算することができる)に似た何かを行うことができます最小サイズ。

この例は、丸いオブジェクトです。コーナーでは、MINを属性にすることができますので、中心からの距離は頂点ごとに異なります。

さらにボックスのようなものが必要な場合は、x座標とy座標の最小距離を個別に確認してください。

CPUでは、GPUに送信する前に、CPU上で座標を計算してそれに応じてスケールすることができます。

+0

偉大な、私はこれを試して報告することを与えるでしょう。 –

+0

問題を再読み込みすると、ラインの代わりに小さな薄いボックス(GL_TRIANGLE_STRIP)を使用して、頂点シェーダがボックスの高さを伸ばすことができます。 – mifortin

+0

私は現在glLineWidth()を設定してGL_LINESを使用しています。私はGL_TRIANGLE_STRIPを使用することが多くの理由で好まれていることを知っていますが、私はGL_LINESで大丈夫ですので、私はそれに固執すると思いました。 GL_LINESを使用することはできませんか?それとももっと難しいですか? –

関連する問題