1

現在、古いエンジンに HDR を追加していて、色空間変換の問題に遭遇しました。

  1. Yxy 色空間でライトを定義しています
  2. 次に、Yxy を XYZ に変換しています
  3. XYZ から sRGB への変換。
  4. 最終的にトーン マッピングを使用して結果をレンダリングおよび正規化するときに、RGB 値 > 1.0 を使用します。

主な光源は最大 150k ルクスの照度を持つ太陽であるため、かなり大きな数で作業しています。

YxyToXYZ 関数

osg::Vec3 YxyToXYZ( const osg::Vec3& Yxy )
{
    if ( Yxy[2] > 0.0f )
    {
        return osg::Vec3( Yxy[0] * Yxy[1] / Yxy[2] , Yxy[0] , Yxy[0] * ( 1.0f - Yxy[1] - Yxy[2])  / Yxy[2] );
    }
    else
    {
        return osg::Vec3( 0.0f , 0.0f , 0.0f );   
    }
}

XYZtosRGB

osg::Vec3 XYZToSpectralRGB( const osg::Vec3& XYZ )
{
    // Wikipedia matrix
    osg::Vec3 rgb;
    rgb[0] = 3.240479  * XYZ[0] - 1.537150 * XYZ[1] - 0.498535 * XYZ[2];
    rgb[1] = -0.969256 * XYZ[0] + 1.875992 * XYZ[1] + 0.041556 * XYZ[2];
    rgb[2] = 0.055648 * XYZ[0]  - 0.204043 * XYZ[1] + 1.057311 * XYZ[2];

    std::cout << "newrgb rgb r:" << rgb[0] << " g:" << rgb[1] << " b:" << rgb[2] << std::endl;

    // The matrix in pbrt book p. 235 gives unexpected results. We expect that if we have
    // x = y = 0.33333 we get a white pixel but that matrix gives red. Hence we use a different
    // matrix that is often used by 3D people
    rgb[0] = 2.5651  * XYZ[0] -1.1665 * XYZ[1] -0.3986 * XYZ[2];
    rgb[1] = -1.0217 * XYZ[0] + 1.9777 * XYZ[1] + 0.0439 * XYZ[2];
    rgb[2] = 0.0753 * XYZ[0]  -0.2543 * XYZ[1] + 1.1892 * XYZ[2];

    std::cout << "oldrgb rgb r:" << rgb[0] << " g:" << rgb[1] << " b:" << rgb[2] << std::endl;

    return rgb;
}

テストサンプル:

Yxy Y:1 x:1 y:1
XYZ X:1 Y:1 Z:-1
newrgb rgb r:2.20186 g:0.86518 b:-1.20571
oldrgb rgb r:1.7972  g:0.9121  b:-1.3682

Yxy Y:25 x:0.26 y:0.28
XYZ X:23.2143 Y:25 Z:41.0714
newrgb rgb r:16.3211 g:26.106  b:39.616
oldrgb rgb r:14.0134 g:27.5275 b:44.2327

Yxy Y:3100 x:0.27 y:0.29
XYZ X:2886.21 Y:3100 Z:4703.45
newrgb rgb r:2242.7  g:3213.56 b:4501.09
oldrgb rgb r:1912.47 g:3388.51 b:5022.34

Yxy Y:6e+06 x:0.33 y:0.33
XYZ X:6e+06 Y:6e+06 Z:6.18182e+06
newrgb rgb r:7.13812e+06 g:5.69731e+06 b:5.64573e+06
oldrgb rgb r:5.92753e+06 g:6.00738e+06 b:6.27742e+06

質問:

  1. 負の値は取り除かれるべきだと思いますか?それとも、計算に誤りがありますか?
  2. 2 つのマトリックスは、似ているが異なる値を生成します (原色は sRGB に非常に近い)。古いマトリックス (どこから来たのかわかりません) をWikiのものに置き換えたいと思います。古いマトリックスがどこから来て、どれが正しいものになるか知っている人はいますか?
  3. 元同僚のように聞こえる@ YxyからRGBへの変換の部分的な回答を見つけました:) ...しかし、私の問題は解決しません。

どうもありがとう

4

1 に答える 1