2

OpenGL は、一方の側からもう一方の側への色のグラデーションで四角形に色を付けることができます。C ++で次のコードを使用しています

glBegin(GL_QUADS);
{
    glColor3d(simulationSettings->hotColour.redF(), simulationSettings->hotColour.greenF(), simulationSettings->hotColour.blueF());
    glVertex2d(keyPosX - keyWidth/2, keyPosY + keyHight/2);
    glColor3d(simulationSettings->coldColour.redF(), simulationSettings->coldColour.greenF(), simulationSettings->coldColour.blueF());
    glVertex2d(keyPosX - keyWidth/2, keyPosY - keyHight/2);
    glColor3d(simulationSettings->coldColour.redF(), simulationSettings->coldColour.greenF(), simulationSettings->coldColour.blueF());
    glVertex2d(keyPosX + keyWidth/2, keyPosY - keyHight/2);
    glColor3d(simulationSettings->hotColour.redF(), simulationSettings->hotColour.greenF(), simulationSettings->hotColour.blueF());
    glVertex2d(keyPosX + keyWidth/2, keyPosY + keyHight/2);
}

HSV と RGB の間の変換を行うために、いくつかの Qt ライブラリを使用しています。コードからわかるように、hotColour から coldColour への色のグラデーションで四角形を描画しています。

なぜ私はこれをしているのですか?私が作成したプログラムは、空間に 3D ベクターを描画し、その長さを色で示します。ユーザーは、ホット (高い値) とコールド (低い値) の色を選択するように提案され、プログラムは HSV スケーリングを使用してグラデーションを自動的に実行します。

HSV スケーリングの理由 HSV は、私が使用しているカラー マップに沿った単一の値であり、それを使用してグラデーションを線形に作成するのは非常に簡単な作業であるためです。ユーザーが色を選択できるように、QColourDialog カラー マップを提供します。

http://qt-project.org/doc/qt-4.8/qcolordialog.html

このカラー マップでは、赤色が右側と左側で使用できることがわかります。このカラー マップを RGB で線形スケールにすることは不可能です。しかし、HSV を使用すると、色相値に 0 から 360 の間の線形スケールを使用するだけで、線形スケールを非常に簡単に実現できます。

このパラダイムを使用すると、ホット カラーとコールド カラーがグラデーションの方向を定義することがわかります。たとえば、色相をコールドに 0、ホットに 359 に選択すると、HSV は 0 から 359 までのグラデーションを提供し、グラデーションに色のスペクトル全体を含めます。一方、OpenGL では、基本的に赤から赤に変化しますが、これはグラデーションではありません!!!!!

OpenGL に RGB ではなく HSV グラデーションを使用させるにはどうすればよいですか? 私が思いつく唯一のアイデアは、色を付けたい長方形をスライスし、小さな長方形に多くのグラデーションを適用することですが、これは最も効率的な方法ではないと思います。

何か案は?

4

2 に答える 2

7

OpenGL に RGB ではなく HSV グラデーションを使用させるにはどうすればよいですか?

私はそれを「強制」ではなく「教え」と呼んでいます。頂点属性ベクトルを補間する OpenGL のデフォルトの方法は、フラグメントの NDC 座標に基づく単一ベクトル要素の重心補間です。

これらの重心補間された HSV 値を RGB に変換する方法を OpenGL に指示する必要があります。

このために、カラー頂点属性が RGB ではなく HSV であると想定するフラグメント シェーダーを導入します。

#version 120
varying vec3 vertex_hsv; /* set this in appropriate vertex shader to the vertex attribute data*/

vec3 hsv2rgb(vec3 hsv)
{
    float h = hsv.x * 6.; /* H in 0°=0 ... 1=360° */
    float s = hsv.y;
    float v = hsv.z;
    float c = v * s;

    vec2 cx = vec2(v*s, c * ( 1 - abs(mod(h, 2.)-1.) ));

    vec3 rgb = vec3(0., 0., 0.);
    if( h < 1. ) {
        rgb.rg = cx;
    } else if( h < 2. ) {
        rgb.gr = cx;
    } else if( h < 3. ) {
        rgb.gb = cx;
    } else if( h < 4. ) {
        rgb.bg = cx;
    } else if( h < 5. ) {
        rgb.br = cx;
    } else {
        rgb.rb = cx;
    }
    return rgb + vec3(v-cx.y);
}

void main()
{
    gl_FragColor = hsv2rgb(vertex_hsv);
}
于 2012-03-05T18:02:31.197 に答える
3

これは、フラグメント シェーダーを使用して行うことができます。クワッドを描画し、クワッドに必要なカラーリングを行うフラグメント シェーダーを適用します。これを行う方法は、角の色を必要な HSV 値に設定し、フラグメント シェーダーで補間された色値を HSV から RGB に変換することです。フラグメント シェーダーの詳細については、ドキュメントを参照してください。

于 2012-03-05T15:40:57.550 に答える