2016-07-25 7 views
0

アプリケーションでは、メッシュの奥行き画像を作成する必要があります。基本的には、各ピクセルがカメラの中心と交点の間の距離を指示する画像が必要です。 OpenGLを使ってこのタスクを実行することにしました。そのため、CPUの代わりにGPU上で計算を行うことができます。フラグメントハードウェアからの浮動小数点

頂点シェーダのコードです。交差点の実際の座標を計算し、その座標をvarying vec4に格納します。これにより、フラグメントシェーダでその座標にアクセスできるようになります。

varying vec4 verpos; 
void main(void) 
{ 
    gl_Position = ftransform(); 
    verpos = gl_ModelViewMatrix*gl_Vertex; 
} 

ここでは、フラグメントシェーダのコードです。フラグメントシェーダでは、これらの座標を使用してピタゴラスを使用して原点(0,0,0)までの距離を計算します。 CPUの計算値へのアクセスを取得するには、私の計画はgl_FragColorを使用して色として距離を格納し、問題は私だけで結果を受け取ること、であるglReadPixels(0, 0, width, height, GL_RED, GL_FLOAT, &distances[0]);

varying vec4 verpos; 
void main() 
{ 
    float x = verpos.x; 
    float y = verpos.y; 
    float z = verpos.z; 

    float depth = sqrt(x*x + y*y + z*z)/5000.0; 
    gl_FragColor = vec4(depth, depth, depth, 1.0); 
} 

を使用してカラー値を抽出することです0.003921569=1/255)の精度。 結果の値には、たとえば0.364705890, 0.364705890, 0.364705890, 0.364705890, 0.368627459, 0.368627459, 0.368627459が含まれます。行の値の大部分はまったく同じで、1/255のジャンプがあります。 だから間違いなくgl_FragColorglReadPixels OpenGLはfloatを8ビットに変換し、その後floatに変換し直します。

精度を失うことなく距離値を浮動小数点として抽出するにはどうすればよいですか?

+1

8ビットRGBAのバックバッファに書き込んでいますが、浮動小数点値を書きたい場合は、 'HALF_FLOAT'または' FLOAT'テクスチャを付けた 'FrameBufferObject'にレンダリングしてから読み込みテクスチャ –

+0

なぜ深さが1/5000になるのでしょうか?なぜ簡単に利用できる 'length'組み込み関数、つまり' length(verpos) 'を使わないのですか?技術的には、フラグメントカラーに深度を書き込む(そしてカラー書き込みをすべて無効にする)ステップを省略し、深度バッファの内容を読み込み、深度値の1/xマッピングを線形化することさえできます。深度バッファは、少なくとも16ビット、より可能性が高い24ビットを有する。技術的には、線の深さを深度バッファに書き込むこともできますが、それはパフォーマンスに影響します。 – datenwolf

+0

@datenwolf私は5000で割って、値が '[0、1]'の範囲に入るようにします。 – user38034

答えて

1

FBOにR32FまたはR16Fテクスチャを付けてレンダリングします。 glReadPixels()と同じように、ピクセルをglGetTexImage2D()で抽出します。

関連する問題