My sky screenshot! One last step- shading

Started by
3 comments, last by okonomiyaki 21 years, 3 months ago
I am very proud to present the following sky in my game: There is actually a dome gradient but I didn''t turn it on for that screenshot. I haven''t gotten the gradient looking very good yet (realistic colors, etc) so I decided I liked that violet color without gradient for now. The fact is my clouds are done. Except for one thing: shading. They may look shaded but it''s actually kind of random modulating with Perlin Noise alpha values. What is the EASIEST and QUICKEST technique to shade clouds? I''ve heard of some kind of scattering techniques before but I looked up some papers but I wanted to know if that''s the way to go. I''m pretty content with my sky right now but I''d like to add a little shading that considers the direction of the sun. If there''s no quick way to do that, maybe I''ll just have to leave that off for next project. And since I''m looking for an easy way I know that it won''t look the best. I would also like any comments on my sky. It is semi-dynamic, in that it moves around but I haven''t really gotten "transforming" clouds in that new clouds are generated on the fly with noise. But I''m content now and this is my first project so I want to move on to the actual logic of the program. What do you think? Anything you think I should do more to it? Critique!
Advertisement
Don''t know if you''ve read this thread, but here is a lengthy topic about all things sky related.

- James
- James
The correct sky gradient is very easy to calculate, and there is another thread in this forum with description and screenshots. Maybe you can search for it using google?

Here is some code off my hard drive. It looks more complicated than it is, since there is some code to find the sun''s exact position based on date, time and position on the Earth. Also, there''s some junk dealing with scaling, saturation, gamma-correction, displaying the sun. This makes very realistic sky gradients, except for overcast days, night (of course).

float PerezFunction(  float coeffs[5];  float theta, gamma;  float thetaS, lvz; ){  float A = coeffs[0], B = coeffs[1], C = coeffs[2], D = coeffs[3], E = coeffs[4];  float den = (1 + A * exp(B)) * (1 + C * exp(D * thetaS) + E * cos(thetaS)*cos(thetaS));  float num = (1 + A * exp(B / cos(theta))) * (1 + C * exp(D * gamma) + E * cos(gamma)*cos(gamma));  return (lvz * num / den);}float AngleBetween(float thetav, phiv, theta, phi) {  float cospsi = sin(thetav) * sin(theta) * cos(phi-phiv) + cos(thetav) * cos(theta);  if (cospsi > 1)  return 0;  if (cospsi < -1) return PI;  return acos(cospsi);}void sunPosition(  float timeOfDay, julianDay, latitude;  float standardMeridian, longitude;  output float thetaS, phiS; ){  float solarTime, solarDeclination, solarAltitude, opp, adj, solarAzimuth;  solarTime = timeOfDay +    (0.170 * sin(4 * PI * (julianDay - 80) / 373) - 0.129 * sin(2 * PI * (julianDay - 8) / 355)) +    (standardMeridian - longitude) / 15;  solarDeclination = (0.4093 * sin(2 * PI * (julianDay - 81) / 368));  solarAltitude = asin(sin(radians(latitude)) * sin(solarDeclination) -    cos(radians(latitude)) * cos(solarDeclination) * cos(PI * solarTime / 12));  opp = -cos(solarDeclination) * sin(PI * solarTime / 12);  adj = -(cos(radians(latitude)) * sin(solarDeclination) +	  sin(radians(latitude)) * cos(solarDeclination) *  cos(PI * solarTime / 12));  solarAzimuth = atan(opp, adj);  phiS = -solarAzimuth;  thetaS = PI / 2 - solarAltitude;}surfaceskycolor (  float timedSun = 1;  vector toSun = (1, -2, 1.5);  float timeOfDay = 12, julianDay = 180, latitude = 37;  float standardMeridian = 0, longitude = 0;  float turb = 3;  float sphericalProjection = 0;  float exposureControl = 1;  float showSun = 0;  float linearScale = 25;//50;//50//25 for T=2.5  float exponentialScale = 25;//45;//45//10 ){  toSun = normalize(toSun);  uniform float thetaS = acos(zcomp(toSun));  uniform float phiS = atan(ycomp(toSun), xcomp(toSun));  if (timedSun == 1) {    sunPosition(timeOfDay, julianDay, latitude, standardMeridian, longitude, thetaS, phiS);  }  toSun = (sin(thetaS) * cos(phiS), sin(thetaS) * sin(phiS), cos(thetaS));  uniform float theta2, theta3, T, T2, chi, zenith_Y, zenith_x, zenith_y;  uniform float perez_Y[5], perez_x[5], perez_y[5];  theta2 = thetaS * thetaS;  theta3 = theta2 * thetaS;  T = turb;  T2 = turb * turb;  chi = (4 / 9 - T / 120) * (PI - 2 * thetaS);  zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - .2155 * T + 2.4192;  //zenith_Y *= 1000;  // conversion from kcd/m^2 to cd/m^2  zenith_x =	  ( 0.00165 * theta3 - 0.00375 * theta2 + 0.00209 * thetaS + 0.0)     * T2 +	  (-0.02903 * theta3 + 0.06377 * theta2 - 0.03202 * thetaS + 0.00394) * T +	  ( 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * thetaS + 0.25886);  zenith_y =	  ( 0.00275 * theta3 - 0.00610 * theta2 + 0.00317 * thetaS + 0.0)     * T2 +	  (-0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * thetaS + 0.00516) * T +	  ( 0.15346 * theta3 - 0.26756 * theta2 + 0.06670 * thetaS + 0.26688);  perez_Y[0] =  0.17872 * T - 1.46303;  perez_Y[1] = -0.35540 * T + 0.42749;  perez_Y[2] = -0.02266 * T + 5.32505;  perez_Y[3] =  0.12064 * T - 2.57705;  perez_Y[4] = -0.06696 * T + 0.37027;  perez_x[0] = -0.01925 * T - 0.25922;  perez_x[1] = -0.06651 * T + 0.00081;  perez_x[2] = -0.00041 * T + 0.21247;  perez_x[3] = -0.06409 * T - 0.89887;  perez_x[4] = -0.00325 * T + 0.04517;  perez_y[0] = -0.01669 * T - 0.26078;  perez_y[1] = -0.09495 * T + 0.00921;  perez_y[2] = -0.00792 * T + 0.21023;  perez_y[3] = -0.04405 * T - 1.65369;  perez_y[4] = -0.01092 * T + 0.05291;// shader code starts here  color skycolor = 0;  vector Iw = normalize(transform("world", I));  float theta = acos(zcomp(Iw));  float phi = atan(ycomp(Iw), xcomp(Iw));  if (sphericalProjection == 1) {    vector Indc = transform("NDC", I);    phi = atan(xcomp(Indc) - .5, ycomp(Indc) - .5);    theta = asin(2 * length((xcomp(Indc) - .5, ycomp(Indc) - .5, 0)));  }  float gamma = AngleBetween(theta, phi, thetaS, phiS);    // Compute xyY values  float x = PerezFunction(perez_x, theta, gamma, thetaS, zenith_x);  float y = PerezFunction(perez_y, theta, gamma, thetaS, zenith_y);  float Y = PerezFunction(perez_Y, theta, gamma, thetaS, zenith_Y);  float X = (x / y) * Y;  float Z = ((1 - x - y) / y) * Y;  float R =  3.240479 * X - 1.537150 * Y - 0.498535 * Z;  float G = -0.969256 * X + 1.875992 * Y + 0.041556 * Z;  float B =  0.055648 * X - 0.204043 * Y + 1.057311 * Z;  if (exposureControl == 1) {    /*skycolor = color (                      1-exp(-(1/exponentialScale) * R),                      1-exp(-(1/exponentialScale) * G),                      1-exp(-(1/exponentialScale) * B)                     );*/    float max, min, delta, hue, saturation, value;    max = max(R, G, B);    min = min(R, G, B);    value = max;    saturation = (value != 0) ? ((max - min) / max) : 0;    if (saturation == 0) hue = 0; // undefined    else {      delta = max - min;      if (R == max) hue = (G - B) / delta;      else if (G == max) hue = 2 + (B - R) / delta;      else if (B == max) hue = 4 + (R - G) / delta;      hue *= 60;      if (hue < 0) hue += 360;      hue /= 360;    }    value = 1 - exp(-(1/exponentialScale) * value);    //value /= linearScale;    skycolor = color "hsv" (hue, saturation, value);  } else {    //skycolor = color (R, G, B) / linearScale;    float max, min, delta, hue, saturation, value;    max = max(R, G, B);    min = min(R, G, B);    value = max;    saturation = (value != 0) ? ((max - min) / max) : 0;    if (saturation == 0) hue = 0; // undefined    else {      delta = max - min;      if (R == max) hue = (G - B) / delta;      else if (G == max) hue = 2 + (B - R) / delta;      else if (B == max) hue = 4 + (R - G) / delta;      hue *= 60;      if (hue < 0) hue += 360;      hue /= 360;    }    //value = 1 - exp(-(1/exponentialScale) * value);    value /= linearScale;    skycolor = color "hsv" (hue, saturation, value);  }    // gamma correction#define gamma 2.5  skycolor = color (pow(comp(skycolor,0),1/gamma),pow(comp(skycolor,1),1/gamma),pow(comp(skycolor,2),1/gamma));  if (sphericalProjection == 0 && zcomp(Iw) < 0) skycolor = 0;  Oi = 1;  Ci = skycolor;  if (showSun == 1) {    if (sphericalProjection == 0) {      Ci = mix(Ci, color(1,0,0), pow(Iw . toSun, 256));    } else {      vector Indc = transform("NDC", I);      setzcomp(Indc, 0);      float Sradius = .5 * sin(thetaS);      vector Sndc = (sin(phiS) * Sradius + .5, cos(phiS) * Sradius + .5, 0);      if (length(Sndc - Indc) < .01) Ci = color (1, 0, 0);    }  }} 


that sky looks really cool


Sam Johnston (Samith)
Yes, I have seen that sky thread many times But I had lost the link to it so thank you very much for reminding me of it.

greeneggs: Thanks a bunch for your code. I'm looking through it and I like some of the concepts behind it. I won't use it exactly but I will implement something similar, thanks for the ideas. I have a basic gradient down it just doesn't account for the sun and doesn't look very realistic.
And thanks samith

[edited by - okonomiyaki on January 23, 2003 1:31:36 AM]

This topic is closed to new replies.

Advertisement