Mathematica에서 내 하늘 색상 계산이 왜 올바르지 않습니까?


17

이 종이 (Perez 모델)를 기반으로 하늘색을 계산하는 알고리즘을 구현하려고합니다 . 쉐이더 프로그래밍을 시작하기 전에 Mathematica에서 컨셉을 테스트하고 싶었습니다. 제거 할 수없는 몇 가지 문제가 이미 있습니다. 누군가 이미 알고리즘을 구현했을 수도 있습니다.

I 절대 zenital 휘도에 대한 방정식을 시작 Yz, xzyz논문에서 (22 페이지)를 제안한다. 의 가치는 Yz합리적인 것 같습니다. 다음 다이어그램은 Yz탁도 T가 5 일 때 태양의 정점 거리의 함수로 나타냅니다 .

Yz (z)

gamma (zenith, azimuth, solarzenith, solarazimuth) 함수는 주어진 천정 거리와 방위각을 가진 점과 주어진 위치에서 태양 사이의 각도를 계산합니다. 이 기능도 작동하는 것 같습니다. 다음 다이어그램은 solarzenith=0.5및에 대한이 각도를 보여줍니다 solarazimuth=0. zenith위쪽에서 아래쪽으로 (0에서 Pi / 2로), azimuth왼쪽에서 오른쪽으로 (-Pi에서 Pi) 태양의 위치를 ​​명확하게 볼 수 있습니다 (밝은 점, 각도가 0이 됨).

감마 (제니스, 방위각, 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 Notebook은 여기 및 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 대신 실제 코드 (셰이더 또는 기타)로 알고리즘을 구현하려고하면 더 많은 사람들이 당신을 도울 수 있다고 생각합니다.
Tetrad

2
있다 티카 SE는 당신이 당신의 질문을 통해이 주제에 있는지 확인하기 위해 자신의 FAQ를 확인해야하지만.
MichaelHouse

문제는 실제로 Mathematica에 관한 것이 아니라 알고리즘에 관한 것입니다. 모든 사람이 읽을 수 있도록 PDF 버전의 노트북을 추가했습니다. 구문은 일반적인 프로그래머가 이해할 수 있고 셰이더 코드보다 이해하기 쉽습니다.
Nico Schertler

@NicoSchertler : 문제는 여기서 많은 사람들이 Mathematica 구문을 이해하지 못한다고 생각합니다. 적어도이 질문의 목적을 위해 C 언어 나 Python 언어로 코드를 다시 작성하면 더 많은 행운을 얻게 될 것입니다.
Panda Pajama 2016 년

2
질문이 실제로 너무 현지화되어 닫힐 수 있지만 종이 링크 덕분에 흥미 롭습니다.
sam hocevar

답변:


4

에 사용되는 매트릭스에 두 개의 오류가 있습니다 xz: 1.00166은 0.00166해야하고, 0.6052은 0.06052을해야합니다.


수정 해 주셔서 감사합니다. 결과는 이제 더 좋아 보이지만 정확하지는 않습니다. 업데이트 된 질문을 고려해 주시면 감사하겠습니다.
Nico Schertler

-2

색상 값 스케일링 문제 일 수 있습니까?


2
귀하의 가정은 정확할 수 있지만 추가 설명을 제공하는 것이 더 도움이됩니다. 당신이 쓴 전체 질문에 대답 할 수 없기 때문에 당신이 쓴 것은 질문 아래에 주석이어야합니다.
danijar

이것은 질문에 대한 답변을 제공하지 않습니다. 작성자의 의견을 비판하거나 설명을 요청하려면 게시물 아래에 댓글을 남겨주세요. 언제든지 자신의 게시물 에 댓글 수 있으며 평판 이 충분 하면 게시물댓글 수 있습니다 .
MichaelHouse

1
제안이 여기에 전혀 용인되지 않는 이유를 이해하지 못합니다. 위의 솔루션을 보면 가치 문제입니다. 항상 올바른 솔루션을 제공하는 것보다 올바른 방향으로 사람들을 가리키는 것이 배우는 것이 더 좋은 방법입니까? 그리고 아니오, 나는 허용되지 않기 때문에 그의 질문 아래에 논평 할 수 없습니다. 그렇기 때문에 내가 여기에 댓글을 달았습니다. 그러나 강등에 감사드립니다. 정말 당신이 좋고 나 같은 새로운 사람들에게 매우 격려. 감사합니다.
부바 미
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.