Author Topic: Elegant solution for skyline color  (Read 26384 times)

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Elegant solution for skyline color
« on: November 20, 2009, 07:02:43 PM »
Anyone can come up with an elegant function to transform {time of the day} into a RGB value, including dawn and sunset?

Ex

  • IRC Communications Delegate
  • Rogueliker
  • ***
  • Posts: 313
  • Karma: +0/-0
    • View Profile
Re: Elegant solution for skyline color
« Reply #1 on: November 21, 2009, 02:06:30 AM »
I'd like to see this too. I know that the colors of the various times of day are very well known by artists, but I don't think I've ever seen a simple function to calculate it. Anyone know? This would be pretty cool!

Etinarg

  • Rogueliker
  • ***
  • Posts: 424
  • Karma: +1/-1
  • Idea archivist and game tinkerer.
    • View Profile
    • Gedankenweber Blog (German)
Re: Elegant solution for skyline color
« Reply #2 on: November 21, 2009, 11:09:40 AM »
In the old Bards Tale III game there was such an effect and it was very nice.

I think the easiest way to do it, is a table with a few RGB colors, maybe one for each hour, and then interpolate exact time in between those table entries.

I'd search my own photo archive, or google for photos and pick the colors from there.

Etinarg

  • Rogueliker
  • ***
  • Posts: 424
  • Karma: +1/-1
  • Idea archivist and game tinkerer.
    • View Profile
    • Gedankenweber Blog (German)
Re: Elegant solution for skyline color
« Reply #3 on: November 25, 2009, 11:15:56 AM »
I hoped this topic would spawn more answers since I got the idea of procedurally generating not only a uniformly colored sky, but a gradient colored skyline - and the trick would be that it can be done for different types of atmospheres and suns, in order to simulate a day passing on a foreign planet.

In this case I cannot pick colors from photos ... but must calculate them from sun spectrum and atmosphere :o

Any ideas?

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #4 on: November 25, 2009, 11:59:22 AM »
Yeah, that's more what I'm looking for...

PseudoJava:
Code: [Select]
class RadialPosition {
  int distance;
  Angle angle; //We are talking 2D here
}

class ColorGradient {
  Angle direction; //We are talking 2D here
  Color start, end;
}

// Used for suns and mons
class SkyBody {
  Color projectedColor;
  int luminescense;
  RadialPosition position; //Relative to the planet
}

class World {
  Atmosphere atmosphere;
  SkyBody[] skyBodies;
  Gradient getSky(); // <--- Magic happens here
}

What do you think? I am thinking towards having a single gradient as a result, although we may also think on multiple combined gradients... but that will make thinks more complex than we need :)

Etinarg

  • Rogueliker
  • ***
  • Posts: 424
  • Karma: +1/-1
  • Idea archivist and game tinkerer.
    • View Profile
    • Gedankenweber Blog (German)
Re: Elegant solution for skyline color
« Reply #5 on: November 25, 2009, 12:53:23 PM »
One gradient most likely will do, more than two seem not to be needed. I think sometimes the gradient changes at some point in the middle.

Maybe it will work if the atmosphere gets a filter component (a color), and the sun has a light color.

Then I'd try to have something like (0.9 * filterColor + 0.1 * sunColor) for the horizon, and (0.1 * filterColor + 0.9 * sunColor) for the high atmosphere. (E.g. Range from dark blue to light blue for our planet)

Also, a second filter might be needed for the sun itself. Near the horizon it's red-orange usually and up in the sky it's yellow-white.

And then, we need to link that to daytime ... filter colors depend on daytime maybe?

Haven't tried that yet. Just writing down a few thoughts.

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #6 on: November 26, 2009, 09:45:29 PM »
I am thinking more on this: (quick draft)

Code: [Select]
Atmosphere{
   Color diffraction; // RGB diffraction caused by gases and stuff
   Color base = BLACK; // Sky is dark by default
}

CelestialBody{
   int lightStrength(int timeOfTheDay);
   Color baseLight; //Base light is almost always WHITE
}

World {
   // Brightness is modified by the
   // light strength of the celestial bodies, and color is
   // affected by the atmosphere.
   List<CelestialBody> bodies;
   Atmosphere atmosphere;

   int timeOfTheDay();

   Color skyColor(){
      skyColor = atmosphere.base;
      for (CelestialBody body in bodies){
         skyColor = skyColor + body.baseLight * base.lightStrength(timeOfTheDay) * atmosphere.diffraction;
      }
   }

}

It may work with some tweaking, probably.

Also, it produces a single color but I guess one could simple dither it into the horizon...

What do you think?

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #7 on: November 26, 2009, 09:52:59 PM »
Also, the atmosphere diffraction may be affected by weather and other mundane things

Etinarg

  • Rogueliker
  • ***
  • Posts: 424
  • Karma: +1/-1
  • Idea archivist and game tinkerer.
    • View Profile
    • Gedankenweber Blog (German)
Re: Elegant solution for skyline color
« Reply #8 on: November 26, 2009, 10:26:27 PM »
What do you think?

Looks good as a starting point. I haven't coded anything in this direction yet, but I'm sure with some experimentation your code can developed into a solutions that produces nice results.

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #9 on: November 27, 2009, 12:58:52 AM »
Check http://www.santiagoz.com/share/sky.htm

It seems to work pretty well..

Vanguard

  • Rogueliker
  • ***
  • Posts: 1112
  • Karma: +0/-0
    • View Profile
Re: Elegant solution for skyline color
« Reply #10 on: November 27, 2009, 09:18:42 AM »
Hey, that's pretty cool.

Etinarg

  • Rogueliker
  • ***
  • Posts: 424
  • Karma: +1/-1
  • Idea archivist and game tinkerer.
    • View Profile
    • Gedankenweber Blog (German)
Re: Elegant solution for skyline color
« Reply #11 on: November 27, 2009, 09:47:22 AM »
Works very well for me. Seems you got the formula right :)

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #12 on: November 30, 2009, 02:27:35 AM »
Seemingly so :)

I polished it a bit and added a function to calculate the sun and moon strenght based on the time of the day.

All now at http://www.santiagoz.com/share/sky.htm

I left the ugly one at http://www.santiagoz.com/share/skyfull.htm

Ex

  • IRC Communications Delegate
  • Rogueliker
  • ***
  • Posts: 313
  • Karma: +0/-0
    • View Profile
Re: Elegant solution for skyline color
« Reply #13 on: November 30, 2009, 03:46:33 AM »
Very nicely done, slashie! Earth's atmosphere scatters different colors of light based on the position of the sun in the sky. It scatters blue much more heavily than red, namely, which means that when the sun is directly overhead, the sky will be very blue. This is because the blue light is scattered just enough to be everywhere, where as the red light is mostly unscattered. At sunset, the blue light is scattered so much that it is very dim, where as the red light finally begins to be scattered as the blue light was at noon, resulting in a redish sunset and sunrise.

Pseudo C:

struct Atmosphere
{
  float RScatter,GScatter,BScatter; //How much R, G and B are scattered at noon.
  float Density;
}
struct Sun
{
  float RColor,GColor,BColor;
  float Intensity;
  float HeightInSky; //1 = directly overhead, 0 and 2 are on the horizon.
}

SkyRColor = Sun.Intensity*Sun.RColor*(Atmosphere.RScatter*(abs(1-Sun.HeightInSky)+Atmosphere.Density));
SkyGColor = Sun.Intensity*Sun.GColor*Atmosphere.GScatter;
SkyBColor = Sun.Intensity*Sun.BColor*(Atmosphere.BScatter*(1-(abs(1-Sun.HeightInSky)+Atmosphere.Density)));

I'm sure there are some improvements that can be made, but that's my general idea.
« Last Edit: November 30, 2009, 03:58:39 AM by Elig »

Slash

  • Creator of Roguetemple
  • Administrator
  • Rogueliker
  • *****
  • Posts: 1203
  • Karma: +4/-1
    • View Profile
    • Slashie.net
    • Email
Re: Elegant solution for skyline color
« Reply #14 on: November 30, 2009, 04:04:02 AM »
Yeah, I made it using some info I googled :)

I tried to model sunset too, but the thing is... the sunset doesnt spread over all the sky, but rather along a very limited zone around the sun!

So this model is more for the general sky color, leaving out interesting phenomena such as sunset and sunrise...

It may be worth extending it to calculate 3 regions of the sky, and then interpolate between those... each one would have different color absortion/scatter (so the middle part would have big blue absortion, while the other ones may have higher red absortion), and would get different sun strength along the day (the left one gets a lot of strength on 5PM to 7PM, the right one from 5 to 7 AM).

I think it would work pretty well...