7

ポイント スプライトを使用して OpenGL 3+ でいくつかのパーティクルをレンダリングしようとしています。ポイントに大きな問題があることに気づきました。カメラの距離に応じて自動的にサイズが大きくなります。その結果、次のようになります。

パーティクル エミッタの近く:

ひどい

そして、遠くにあると、すべてがぼやけて肥大化して見えます。

遠い

古いバージョンでは、ポイント サイズ スケールを で調整できるようglPointParameterです。この関数は、新しい 3 以降の OpenGL でも引き続き使用できますが、サポートされるパラメーターは 2 つだけです。GL_POINT_FADE_THRESHOLD_SIZE必要なもののように思えましたが、試してみましたが結果はありませんでした。私も使っていますglEnable(GL_PROGRAM_POINT_SIZE);

カメラの距離に基づいたポイントの自動スケーリングを回避できる他の方法はありますか? 三角形で作られた標準のビルボードを使用するためにコードを変更する必要はありません。

現時点で関連性があるかどうかはわかりませんが、これは私が使用している頂点シェーダーです:

layout(location = 0) in vec4 a_position_size; // Point size in w coord
layout(location = 1) in vec4 a_color;         // RGBA color modulated with texture

layout(location = 0) out vec4 v_color;

uniform mat4 u_MVPMatrix;

void main()
{
    gl_Position  = u_MVPMatrix * vec4(a_position_size.xyz, 1.0);
    gl_PointSize = a_position_size.w;
    v_color      = a_color;
}
4

2 に答える 2

14

したがって、私の問題は の誤解によるものであることがわかりましたgl_PointSize。コメントに記載され、ドキュメントに明確に記載されているように、gl_PointSize ラスター化されたポイントのサイズがピクセル単位で含まれています。したがって、ポイント スプライトから離れると、ポイント スプライトが大きく見えるのは、それらがスケーリングされているからではなく、3D シーンの残りの部分が透視投影に従って縮小されている間、同じスクリーン スペースを占有しているからです。

ビューアーからの距離に応じてポイント サイズを実際にスケーリングするために、頂点シェーダーをいくつか調整して問題を修正しました。

uniform mat4 u_MVPMatrix;
uniform vec3 u_cameraPos;

// Constants (tweakable):
const float minPointScale = 0.1;
const float maxPointScale = 0.7;
const float maxDistance   = 100.0;

void main()
{
    // Calculate point scale based on distance from the viewer
    // to compensate for the fact that gl_PointSize is the point
    // size in rasterized points / pixels.
    float cameraDist = distance(a_position_size.xyz, u_cameraPos);
    float pointScale = 1.0 - (cameraDist / maxDistance);
    pointScale = max(pointScale, minPointScale);
    pointScale = min(pointScale, maxPointScale);

    // Set GL globals and forward the color:
    gl_Position  = u_MVPMatrix * vec4(a_position_size.xyz, 1.0);
    gl_PointSize = a_position_size.w * pointScale;
    v_color      = a_color;
}
于 2014-10-15T18:56:44.243 に答える