Mathematicaでの空の色の計算が間違っているのはなぜですか?


17

この論文(Perezモデル)に基づいて空の色を計算するアルゴリズムを実装しようとしています。シェーダーのプログラミングを始める前に、Mathematicaで概念をテストしたかったのです。私は取り除くことができないいくつかの問題が既にあります。誰かがすでにアルゴリズムを実装しているかもしれません。

私は絶対zenital輝度のための方程式を開始しYzxzそしてyzなど紙(22ページ)で提案されています。の値はYz妥当なようです。次の図はYz、濁度Tが5の場合の太陽の天頂距離の関数として示しています。

Yz(z)

関数gamma(zenith、azimuth、solarzenith、solarazimuth)は、指定された天頂距離と方位角を持つポイントと指定された位置の太陽の間の角度を計算します。この機能も機能しているようです。次の図は、この角度を示しているsolarzenith=0.5solarazimuth=0zenith上から下へ(0からPi / 2へ)azimuth成長し、左から右へ(-PiからPiへ)成長します。太陽の位置をはっきりと見ることができます(輝点、角度はゼロになります):

ガンマ(天頂、方位、0.5、0)

Perez関数(F)と係数は、論文に記載されているとおりに実装されています。その場合、色値Yxyはになりますabsolute value * F(z, gamma) / F(0, solarzenith)。これらの値は[0,1]の範囲内にあると考えています。ただし、これはYコンポーネントの場合ではありません(詳細については、以下の更新を参照してください)。サンプル値は次のとおりです。

{Y, x, y}
{19.1548, 0.25984, 0.270379}
{10.1932, 0.248629, 0.267739]
{20.0393, 0.268119, 0.280024}

現在の結果は次のとおりです。

RGB画像

すべての計算が記載された Mathematicaノートブックはここにあり、PDFバージョンはこちらにあります

誰も私が論文と同じ結果を得るために何を変更しなければならないか考えていますか?

Cのようなコード

// this function returns the zenital Y component for 
// a given solar zenital distance z and turbidity T
float Yz(float z, float T)
{
    return (4.0453 * T - 4.9710)*tan( (4.0f/9-T/120)*(Pi-2*z) ) - 0.2155 * T + 2.4192
}

// returns zenital x component
float xz(float z, float T)
{
    return //matrix calculation, see paper
}

// returns zenital y component
float yz(float z, float T)
{
    return //matrix calculation, see paper
}

// returns the rgb color of a Yxy color
Color RGB(float Y, float x, float y)
{
    Matrix m; //this is a CIE XYZ -> RGB conversion matrix
    Vector v;
    v.x = x/y*Y;
    v.y = Y;
    v.z = (1-x-y)/y*Y;
    v = M * v; //matrix-vector multiplication;
    return Color ( v.x, v.y, v.z );        
}

// returns the 5 coefficients (A-E) for the given turbidity T
float[5] CoeffY(float T)
{
    float[5] result;
    result[0] = 0.1787 * T - 1.4630;
    result[1] = -0.3554 * T + 0.4275;
    ...
    return result;
}

//same for Coeffx and Coeffy

// returns the angle between an observed point and the sun
float PerezGamma(float zenith, float azimuth, float solarzenith, float solarazimuth)
{
    return acos(sin(solarzenith)*sin(zenith)*cos(azimuth-solarazimuth)+cos(solarzenith)*cos(zenith));
}

// evalutes Perez' function F
// the last parameter is a function
float Perez(float zenith, float gamma, float T, t->float[5] coeffs)
{
    return (1+coeffs(T)[0] * exp(coeffs(T)[1]/cos(zenith)) *
           (1+coeffs(T)[2] * exp(coeffs(T)[3]*gamma) + 
            coeffs(T)[4]*pow(cos(gamma),2))
}

// calculates the color for a given point
YxyColor calculateColor(float zenith, float azimuth, float solarzenith, float solarazimuth, float T)
{
    YxyColor c;
    float gamma = PerezGamma(zenith, azimuth, solarzenith, solarazimuth);
    c.Y = Yz(solarzenith, T) * Perez(zenith, gamma, T, CoeffY) / Perez(0, solarzenith, T, CoeffY);
    c.x = xz(solarzenith, T) * Perez(zenith, gamma, T, Coeffx) / Perez(0, solarzenith, T, Coeffx);
    c.y = yz(solarzenith, T) * Perez(zenith, gamma, T, Coeffy) / Perez(0, solarzenith, T, Coeffy); 
    return c;
}

// draws an image of the sky
void DrawImage()
{
    for(float z from 0 to Pi/2) //zenithal distance
    {
        for(float a from -Pi to Pi) //azimuth
        {
            YxyColor c = calculateColor(zenith, azimuth, 1, 0, 5);
            Color rgb = RGB(c.Y, c.x, c.y);
            setNextColor(rgb);
        }
        newline();
    }
}

解決

約束どおり、空のレンダリングに関するブログ記事を書きました。ここで見つけることができます。


Mathematicaの代わりに実際のコード(シェーダーなど)でアルゴリズムを実装しようとする場合、ここにいる人の多くがあなたを助けることができると思います。
テトラッド

2
あるMathematicaのSEは、あなたの質問があそこトピック上にあるかどうかを確認するために彼らのよくある質問をチェックしなければならないのに、。
マイケルハウス

さて、問題は本当にMathematicaについてではなく、アルゴリズムについてです。PDFバージョンのノートブックを追加したので、誰でも読むことができます。構文は一般的なプログラマーにとって理解可能であり、おそらくシェーダーコードよりも理解しやすいと確信しています。
ニコ・シェトラー

@NicoSchertler:問題は、ここにいる多くの人がMathematica構文を理解していないと思うことです。少なくともこの質問の目的のために、Cライクな言語またはPythonライクな言語でコードを書き直せば、おそらくもっと幸運があるでしょう。
パンダパジャマ

2
質問は非常にローカライズされており、閉じられるかもしれませんが、紙のリンクのおかげで、興味深いものです。
サムホセバル

回答:


4

使用されるマトリックスには2つのエラーがありxzます。1.00166は0.00166、0.6052は0.06052です。


修正していただきありがとうございます。結果はより良く見えるようになりましたが、正確ではありません。更新された質問を検討していただければ幸いです。
ニコシェルトラー

-2

色の値のスケーリングの問題のようです?


2
あなたの仮定は正しいかもしれませんが、追加の説明を提供する方がより役立つでしょう。質問全体に答えることはできないので、書いた内容は質問の下のコメントでなければなりません。
ダニジャー

これは質問に対する答えを提供しません。投稿者に批評または説明を依頼するには、投稿の下にコメントを残します-自分の投稿にいつでもコメントできます。評価が十分になったら、投稿にコメントできます。
マイケルハウス

1
ここで提案がまったく容認されない理由がわかりません。上記のソリューションを見ると、それは価値の問題です。常に正確な解決策を提示するよりも、正しい方向に人々を向けることは、学ぶためのより良い方法です いいえ、許可されていないため、彼の質問の下にコメントすることはできません。これが私がここでコメントした理由です。しかし、降格してくれてありがとう。本当に素敵で、私のような新しい人々にとても励ましてくれます。ありがとうございました。
boobami
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.