Archived

This topic is now archived and is closed to further replies.

BlackSheep

Preetham's Daylight Paper problem (50k of images)

Recommended Posts

BlackSheep    100
I''ve implemented the famous Practical Analytical Model of Daylight, by ''borrowing'' some code from a previous thread (thanks greeneggs, I would never have had the patience to type those Perez matrices myself!). However, I''ve hit some issues with the colour of the resulting sky (the rather dodgy sun color is a hangover from a previous experiment, and will be changed) Here come the chunky pics! (all taken on 22nd June) 0700 1000 1100 1200 1800 Spot the mistake! For some reason, the sky is at it''s brightest at mid-morning, and fades almost to black at noon, which is clearly wrong. My guess is that one of my angles is maybe 90degrees out-of-synch, but I''ve tried fiddling, and I get the correct brightness, but the wrong colours (purple sky being unsuitable for my purposes!). Will post code as nec, but it''s essentially identical to the code found on this page NB: have searched forums and checked the major old threads, but didn''t want to necro a 6-pager for the sake of my probably-simple issue.

Share this post


Link to post
Share on other sites
Ilici    862
Watch out for those cosines and sines in the PerezFunc: i once got a weird problem that the top of the skydome was black because a cosine was 0 and caused a div by 0. so when the angle was PI i changed the cosine to 0.00001f. After looking a second time at the pictars i see that at the bottom of the dome the color is fading to black which should not happen. You have to flip the y axis and appply the hack above with the cos.

Also tweak the exposure function for converting to RGB - using a fixed value will not give very good results - the sky is to bright at night.

[ My Site ]
'I wish life was not so short,' he thought. 'Languages take such a time, and so do all the things one wants to know about.' - J.R.R Tolkien
/*ilici*/


[edited by - Ilici on October 11, 2003 5:29:20 AM]

Share this post


Link to post
Share on other sites
stephanh    174
Hi,

i also get similar results. The only thing i can suggest is to change the exposure with sun angle.

I am not sure but i think a better tone matching technique then a simple exposure function is required.

The black bottom edge is from sun angle getting PI/2 or -PI/2. (zenith angles!). Valid range is ]-PI/2, +PI/2[ (excluding!). That's why this model is not really suited for the night ( there's also a paper about nightsky, check vterrain.org) even if it's possible to get something night-sky-like with heavy use of color modifications(exposure,gamma etc.).

regards,
Stephan


eisscholle.de

[edited by - stephanh on October 11, 2003 11:20:36 AM]

Share this post


Link to post
Share on other sites
Ilici    862
It works during the night, but if you dont tweak it nicely the colors are too bright.

here''s my code for the skyshader:


#include "stdafx.h"

#include "mathlib.h"
#include "vectors.h"
#include "skyshader.h"

CSkyColor::CSkyColor()
{
suntheta = 0.0f;
T = 0.0f;
}

inline float CSkyColor::PerezFunction_x(float cosTheta, float cosGamma, float gamma)
{
float val1 = ( 1 + Ax * exp(Bx / cosTheta ) ) * ( 1 + Cx * exp(Dx * gamma) + Ex * SQR(cosGamma) );
float val2 = ( 1 + Ax * exp(Bx) ) * ( 1 + Cx * exp(Dx * suntheta) + Ex * SQR(cosSTheta) );

return val1 / val2;
}

inline float CSkyColor::PerezFunction_y(float cosTheta, float cosGamma, float gamma)
{
float val1 = ( 1 + Ay * exp(By / cosTheta) ) * ( 1 + Cy * exp(Dy * gamma ) + Ey * SQR(cosGamma ) );
float val2 = ( 1 + Ay * exp(By ) ) * ( 1 + Cy * exp(Dy * suntheta) + Ey * SQR(cosSTheta) );

return val1 / val2;
}

inline float CSkyColor::PerezFunction_Y(float cosTheta, float cosGamma, float gamma)
{
float val1 = ( 1 + AY * exp(BY / cosTheta) ) * ( 1 + CY * exp(DY * gamma ) + EY * SQR(cosGamma) );
float val2 = ( 1 + AY * exp(BY ) ) * ( 1 + CY * exp(DY * suntheta) + EY * SQR(cosSTheta) );

return val1 / val2;
}

void CSkyColor::SetInfo(float SunTheta, float Turbidity)
{
suntheta = SunTheta;
T = Turbidity;

T2 = T * T;
suntheta2 = suntheta * suntheta;
suntheta3 = suntheta * suntheta2;

Ax = -0.01925 * T - 0.25922;
Bx = -0.06651 * T + 0.00081;
Cx = -0.00041 * T + 0.21247;
Dx = -0.06409 * T - 0.89887;
Ex = -0.00325 * T + 0.04517;

Ay = -0.01669 * T - 0.26078;
By = -0.09495 * T + 0.00921;
Cy = -0.00792 * T + 0.21023;
Dy = -0.04405 * T - 1.65369;
Ey = -0.01092 * T + 0.05291;

AY = 0.17872 * T - 1.46303;
BY = -0.35540 * T + 0.42749;
CY = -0.02266 * T + 5.32505;
DY = 0.12064 * T - 2.57705;
EY = -0.06696 * T + 0.37027;

xz = ( 0.00165 * suntheta3 - 0.00375 * suntheta2 + 0.00209 * suntheta + 0.00000) * T2 +
(-0.02903 * suntheta3 + 0.06377 * suntheta2 - 0.03202 * suntheta + 0.00394) * T +
( 0.11693 * suntheta3 - 0.21196 * suntheta2 + 0.06052 * suntheta + 0.25886);

yz = ( 0.00275 * suntheta3 - 0.00610 * suntheta2 + 0.00317 * suntheta + 0.00000) * T2 +
(-0.04214 * suntheta3 + 0.08970 * suntheta2 - 0.04153 * suntheta + 0.00516) * T +
( 0.15346 * suntheta3 - 0.26756 * suntheta2 + 0.06670 * suntheta + 0.26688);

float X = (4.0f / 9.0f - T / 120.0f) * (PI - 2 * suntheta);

Yz = ((4.0453f * T - 4.9710) * tan(X) - 0.2155 * T + 2.4192) * 1000.0f;
}

void CSkyColor::ToRGB(float x, float y, float Y, CVector3* rgb)
{
float fX, fY, fZ;

fY = Y;
fX = x / y * Y;
fZ = ((1.0f - x - y) / y) * Y;

float r, g, b;

r = 3.2404f * fX - 1.5371f * fY - 0.4985f * fZ;
g = -0.9692f * fX + 1.8759f * fY + 0.0415f * fZ;
b = 0.0556f * fX - 0.2040f * fY + 1.0573f * fZ;

float expo = -(1.0f / 10000.0f);
r = 1.0f - exp(expo * r);
g = 1.0f - exp(expo * g);
b = 1.0f - exp(expo * b);

if (r < 0.0f) r = 0.0f;
if (g < 0.0f) g = 0.0f;
if (b < 0.0f) b = 0.0f;
if (r > 1.0f) r = 1.0f;
if (g > 1.0f) g = 1.0f;
if (b > 1.0f) b = 1.0f;

rgb->x = r;
rgb->y = g;
rgb->z = b;
}


void CSkyColor::GetVertexColor(float th, float gm, CVector4* color)
{
float x, y, Y;
float cosTheta, cosGamma, cosSTheta;

if (th == PI / 2)
cosTheta = 0.0000001f;
else
cosTheta = Cos(th);

cosGamma = Cos(gm);
cosSTheta = Cos(suntheta);

x = xz * PerezFunction_x(cosTheta, cosGamma, gm);
y = yz * PerezFunction_y(cosTheta, cosGamma, gm);
Y = Yz * PerezFunction_Y(cosTheta, cosGamma, gm);

CVector3 rgb;
ToRGB(x, y, Y, &rgb);

color->x = rgb.x;
color->y = rgb.y;
color->z = rgb.z;
color->w = 1.0f;

}


It''s quite optimized and the Cos and Sin funcs are based on precalculated values.




[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/

Share this post


Link to post
Share on other sites
BlackSheep    100
Illici:
The tight fade to black is caused by my forcing the vertices at the horizon to black, which I intend to cover with foreground geometry (terrain or something). Will try your code later on and see what happens.

Inverting the y-axis completely screws everything up, and I''ve tried and re-tried fudging extra factors of PI into the angles, with no success.

Share this post


Link to post
Share on other sites
Ilici    862
Is you forced those to black then my mistake - inverting the y axis screws things up.

Instead of fading those to black try using a fake horizon: a cylinder with an alpha gradient to make a nice fade into the fog. Set the cylinder''s colors from the ones in the skydome.



[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/

Share this post


Link to post
Share on other sites
HellRaiZer    1001
BlackSheep here are my shots.

As you can see i have the same problem as you more or less. The only thing i do different from you, is color scaling. I know that exposure maybe the best option you have, but it doesn't seem to work for me. So i used some kind of linear scaling.

As ycwn say in his thread "about "a practical analytic model for daylight"" (I don't have the url, because i save threads to hd and read them afterwards! Try to search for it.), i used sun's color magnitude, as a scaling factor. This is:

1) Calculate color at sun's position (sun's theta and phi)
2) calculate its magnitude (assume its a vector. Isn't it?)
3) calculate scale = SunBrightness / Magnitude. SunBrightness gives good results for values from 2.0 - 2.5 as he says.
4) Scale every vertex's color component (R, G, B) by this value.

I don't scale luminance Y in xyY space. Instead i leave it as is. No exposure at all.

A comment on Illici's post.

quote:

Also tweak the exposure function for converting to RGB - using a fixed value will not give very good results - the sky is to bright at night.



I don't get it. It sounds reasonable, but in your code you don't implement it. Instead you use a constant exponent scale factor. If someone can explain a way of achieving this (exposure factor depended on sun's angle), i'd like to hear it.

The shots are (left to right, top to bottom) 7:00, 10:00, 13:00, 17:00, turbidity 3.0f, latitude and longitude for Athens (37.58, 23.43 degrees accordingly), timezone 2.0, day 200 (middle of July).



Any comments?

Thanks to davepermen for his free-to-upload page

HellRaiZer

[edited by - HellRaiZer on October 15, 2003 7:31:32 AM]

Share this post


Link to post
Share on other sites
davepermen    1047
looks great! happy to share my space for such pics!




If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

Share this post


Link to post
Share on other sites
Ilici    862
nope i dont use it - instead i used a table for the sky alpha and interpolated so at night i get nice transparent skyes and during the day i get normal bright skyes. But i still need to tweak the exposure because at sunrise / sunset the colors get screwed.

So i was thinking of a table with exposure data. Just make a 24 element table, from the time of day get the hour and interpolate.



[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/

Share this post


Link to post
Share on other sites
HellRaiZer    1001
quote:

looks great! happy to share my space for such pics!



Thanks Dave.

quote:

So i was thinking of a table with exposure data. Just make a 24 element table, from the time of day get the hour and interpolate.



What values are you going to use to fill this table? Experimental or calculated by a formula?

I took a look at "Trichromatic Model of Daylight Variation", and i have a question. To say the truth i didn''t read it all from beginning to end, just looked at the tables, equations and comments on them. That''s because they are working with xyY - Sprectal -> XYZ conversion, thing i don''t use.
The question is. They are talking about XYZ unscaled vs scaled values. If you look at their table of XYZ unscaled values, they seem like the values i (and probably the most of you) get in XYZ color space. What i can''t understand is how they manage to scale (not clamping) the values in [0, 255] field. Does somebody else read this paper? Is there an explanation for it? I mean, proper XYZ scaling, without converting to M0, M1 etc. Do i miss something important here?

Thanks for the comments.

And BlackSheep sorry for "destroying" your thread. I didn''t mean to

HellRaiZer

Share this post


Link to post
Share on other sites
Ilici    862
I''m gonna do it experimentally because i dont like all those mathematical formulas



[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/

Share this post


Link to post
Share on other sites
HellRaiZer    1001
Just a note i figured out today.

BlackSheep in case to make the color more bright, one reasonable way is gamma correction. I don''t remember mentioning it somewhere in your posts thats why i say it. My images have the same darken problem as yours, but when i gamma correct the colors everything look better. Of course, with gamma correction you will see the effect of turbidity, so it it seems way to "cloudy" try to reduce it something around 1.5 - 2.0 should be good.

Hope this helps.

HellRaiZer

Share this post


Link to post
Share on other sites