Titan's haze
Posted: 24.06.2005, 04:09
In an attempt to port Chris's atmosphere code to my project I was thinking of ways to produce wierd and alien atmospheres....Titans latest photos show just that....
http://astrogeology.usgs.gov/HotTopics/ ... n_haze.jpg
I remember Fridger had origonally posted a thread about this some time back wondering if Celestia could be made to render atmospheres as so....I think this answeres that very question since I am using Chris's code....What I want to do eventually is slim it down into one pass....Right now my hacked version requires 4 passes including haze....
http://celestialvisions.net/gallery/dwu25.jpg
This is the code I use...I think most of it is self explanitory for those who know whats going on...
I didnt do anything that spectacular...I could probably speed things up a bit using vertex arrays....but its not slowing down my FPS that bad...
For those interested in this update to DWU...I will have it up sometime soon...
Maybe this will be seen very soon in Celestia!
http://astrogeology.usgs.gov/HotTopics/ ... n_haze.jpg
I remember Fridger had origonally posted a thread about this some time back wondering if Celestia could be made to render atmospheres as so....I think this answeres that very question since I am using Chris's code....What I want to do eventually is slim it down into one pass....Right now my hacked version requires 4 passes including haze....
http://celestialvisions.net/gallery/dwu25.jpg
This is the code I use...I think most of it is self explanitory for those who know whats going on...
Code: Select all
void solarObj::renderAtmosphere(float fade, bool lit)
{
if (planetInfo.hasSky == false)
return;
float botColor[4], topColor[4], hColor[4], sColor[4];
int i,j;
glDepthMask(GL_FALSE);
gl_EnableColorMaterial();
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND); // Enable Blending
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Point3f center = Point3f(float(planet_pos[planetInfo.planetNum][0]), float(planet_pos[planetInfo.planetNum][1]), float(planet_pos[planetInfo.planetNum][2]));
Vec3f sunDirection[16];
for(i = 0;i<number_lights;i++)
sunDirection[i] = Vec3f(float(planet_pos[planet_star[i]][0]), float(planet_pos[planet_star[i]][1]), float(planet_pos[planet_star[i]][2]));
Vec3f eyeVec = center - Point3f(float(eyeX), float(eyeY), float(eyeZ));
float centerDist = float(eyeVec.length());
// double surfaceDist = (double) centerDist - (double) radius;
Vec3f normal = eyeVec;
normal = normal / float(centerDist);
float radius = planetInfo.planetRadius;
float tangentLength = float(sqrt(float(SQUARE(centerDist)) - float(SQUARE(radius))));
float atmRadius = tangentLength * radius / float(centerDist);
float atmOffsetFromCenter = float(SQUARE(radius)) / float(centerDist);
float cosSunAngle, brightness, t, sunset, haze;
Point3f atmCenter = center - atmOffsetFromCenter * normal;
Vec3f uAxis, vAxis;
if (FABS(normal.x) < FABS(normal.y) && FABS(normal.x) < FABS(normal.z))
{
uAxis = Vec3f(1, 0, 0) ^ normal;
uAxis.normalize();
}
else if (FABS(eyeVec.y) < FABS(normal.z))
{
uAxis = Vec3f(0, 1, 0) ^ normal;
uAxis.normalize();
}
else
{
uAxis = Vec3f(0, 0, 1) ^ normal;
uAxis.normalize();
}
vAxis = uAxis ^ normal;
float height = (planetInfo.skyHeight * 0.02f) / radius;
int divisions = CLAMP(180 * (radius / distanceToPlanet[planetInfo.planetNum] * 2),90,180);
float offset = 0.00237f * float(divisions / 180.0f);
if(planetInfo.doubleAtmosphere) {
height *= 0.5f;
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= divisions; i++)
{
float theta = float(i) / float(divisions + offset) * 2.0f * float(PI);
Vec3f v = float(COS(theta)) * uAxis + float(SIN(theta)) * vAxis;
Point3f base = atmCenter + v * atmRadius;
Vec3f toCenter = base - center;
cosSunAngle = -1e9;
float getAngle = 0;
for(j=0;j<number_lights;j++) {
getAngle = (toCenter * sunDirection[j]) / radius / distanceToPlanet[planet_star[j]];
if(getAngle > cosSunAngle) cosSunAngle = getAngle;
}
brightness = 1.0f;
if (lit)
{
if (cosSunAngle < -0.2f)
{
brightness = 0;
sunset = 0;
}
else
{
t = (0.2f + cosSunAngle) * 2.5f;
brightness = CLAMP(t,0.0f,1.0f);
sunset = CLAMP(t - 0.25f,0.0f,1.0f);
}
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
topColor[0] = (topColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
topColor[1] = (topColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
topColor[2] = (topColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
}
else {
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
}
glColor4f(topColor[0], topColor[1], topColor[2], 0.35f);
glVertex(base + toCenter * (height * 1.5f));
glColor4f(topColor[0], topColor[1], topColor[2], 0.0f);
glVertex(base + toCenter * (height * 2.0f));
}
glEnd();
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= divisions; i++)
{
float theta = float(i) / float(divisions + offset) * 2.0f * float(PI);
Vec3f v = float(COS(theta)) * uAxis + float(SIN(theta)) * vAxis;
Point3f base = atmCenter + v * atmRadius;
Vec3f toCenter = base - center;
cosSunAngle = -1e9;
float getAngle = 0;
for(j=0;j<number_lights;j++) {
getAngle = (toCenter * sunDirection[j]) / radius / distanceToPlanet[planet_star[j]];
if(getAngle > cosSunAngle) cosSunAngle = getAngle;
}
brightness = 1.0f;
if (lit)
{
if (cosSunAngle < -0.2f)
{
brightness = 0;
sunset = 0;
}
else
{
t = (0.2f + cosSunAngle) * 2.5f;
brightness = CLAMP(t,0.0f,1.0f);
sunset = CLAMP(t - 0.25f,0.0f,1.0f);
}
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
topColor[0] = (topColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
topColor[1] = (topColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
topColor[2] = (topColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
}
else {
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
}
glColor4f(topColor[0], topColor[1], topColor[2], 0.0f);
glVertex(base + toCenter * (height * 1.25f));
glColor4f(topColor[0], topColor[1], topColor[2], 0.35f);
glVertex(base + toCenter * (height * 1.5f));
}
glEnd();
}
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= divisions; i++)
{
float theta = float(i) / float(divisions + offset) * 2.0f * float(PI);
Vec3f v = float(COS(theta)) * uAxis + float(SIN(theta)) * vAxis;
Point3f base = atmCenter + v * atmRadius;
Vec3f toCenter = base - center;
cosSunAngle = -1e9;
float getAngle = 0;
for(j=0;j<number_lights;j++) {
getAngle = (toCenter * sunDirection[j]) / radius / distanceToPlanet[planet_star[j]];
if(getAngle > cosSunAngle) cosSunAngle = getAngle;
}
brightness = 1.0f;
if (lit)
{
if (cosSunAngle < -0.2f)
{
brightness = 0;
sunset = 0;
}
else
{
t = (0.2f + cosSunAngle) * 2.5f;
brightness = CLAMP(t,0.0f,1.0f);
sunset = CLAMP(t - 0.25f,0.0f,1.0f);
}
sColor[0] = 1.0f - skyColor[0] * combined_light[0];
sColor[1] = 1.0f - skyColor[1] * combined_light[1];
sColor[2] = 1.0f - skyColor[2] * combined_light[2];
returnHighestColor(sColor);
sColor[0] *= planetInfo.brightness;
sColor[1] *= planetInfo.brightness;
sColor[2] *= planetInfo.brightness;
botColor[0] = (skyColor2[0] * sunset) + (sColor[0] * (1.0 - sunset));
botColor[1] = (skyColor2[1] * sunset) + (sColor[1] * (1.0 - sunset));
botColor[2] = (skyColor2[2] * sunset) + (sColor[2] * (1.0 - sunset));
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
botColor[0] = (botColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
botColor[1] = (botColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
botColor[2] = (botColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
topColor[0] = (topColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
topColor[1] = (topColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
topColor[2] = (topColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
}
else {
botColor[0] = skyColor2[0];
botColor[1] = skyColor2[1];
botColor[2] = skyColor2[2];
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
}
glColor4f(botColor[0], botColor[1], botColor[2], 1.0f);
glVertex(center + toCenter * 0.999f);
glColor4f(topColor[0], topColor[1], topColor[2], 0.0f);
glVertex(base + toCenter * height);
}
glEnd();
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= divisions; i++)
{
float theta = float(i) / float(divisions + offset) * 2.0f * float(PI);
Vec3f v = float(COS(theta)) * uAxis + float(SIN(theta)) * vAxis;
Point3f base = atmCenter + v * atmRadius;
Vec3f toCenter = base - center;
cosSunAngle = -1e9;
float getAngle = 0;
for(j=0;j<number_lights;j++) {
getAngle = (toCenter * sunDirection[j]) / radius / distanceToPlanet[planet_star[j]];
if(getAngle > cosSunAngle) cosSunAngle = getAngle;
}
brightness = 1.0f;
if (lit)
{
if (cosSunAngle < -0.2f)
{
brightness = 0;
sunset = 0;
}
else
{
t = (0.2f + cosSunAngle) * 2.5f;
brightness = CLAMP(t,0.0f,1.0f);
sunset = CLAMP(t - 0.25f,0.0f,1.0f);
}
sColor[0] = 1.0f - skyColor[0] * combined_light[0];
sColor[1] = 1.0f - skyColor[1] * combined_light[1];
sColor[2] = 1.0f - skyColor[2] * combined_light[2];
returnHighestColor(sColor);
sColor[0] *= planetInfo.brightness;
sColor[1] *= planetInfo.brightness;
sColor[2] *= planetInfo.brightness;
botColor[0] = (skyColor2[0] * sunset) + (sColor[0] * (1.0 - sunset));
botColor[1] = (skyColor2[1] * sunset) + (sColor[1] * (1.0 - sunset));
botColor[2] = (skyColor2[2] * sunset) + (sColor[2] * (1.0 - sunset));
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
botColor[0] = (botColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
botColor[1] = (botColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
botColor[2] = (botColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
topColor[0] = (topColor[0] * brightness) + (sceneAmbient[0] * (1.0 - brightness));
topColor[1] = (topColor[1] * brightness) + (sceneAmbient[1] * (1.0 - brightness));
topColor[2] = (topColor[2] * brightness) + (sceneAmbient[2] * (1.0 - brightness));
}
else {
botColor[0] = skyColor2[0];
botColor[1] = skyColor2[1];
botColor[2] = skyColor2[2];
topColor[0] = skyColor[0];
topColor[1] = skyColor[1];
topColor[2] = skyColor[2];
}
glColor4f(botColor[0], botColor[1], botColor[2], 0.0f);
glVertex(center + toCenter * 0.994f);
glColor4f(botColor[0], botColor[1], botColor[2], 1.0f);
glVertex(center + toCenter * 0.999f);
}
glEnd();
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= divisions; i++)
{
float theta = float(i) / float(divisions + 0.00237f) * 2.0f * float(PI);
Vec3f v = float(COS(theta)) * uAxis + float(SIN(theta)) * vAxis;
Point3f base = atmCenter + v * atmRadius;
Vec3f toCenter = base - center;
cosSunAngle = -1e9;
float getAngle = -1e9;
for(j=0;j<number_lights;j++) {
getAngle = (toCenter * sunDirection[j]) / radius / distanceToPlanet[planet_star[j]];
if(getAngle > cosSunAngle) cosSunAngle = getAngle;
}
brightness = 1.0f;
if (lit)
{
if (cosSunAngle < -0.2f)
{
haze = 0;
}
else
{
t = (0.2f + cosSunAngle) * 2.5f;
haze = CLAMP(t * 0.5f,0,1);
}
hColor[0] = (fogColor[0] * haze) + (sceneAmbient[0] * (1.0 - haze));
hColor[1] = (fogColor[1] * haze) + (sceneAmbient[1] * (1.0 - haze));
hColor[2] = (fogColor[2] * haze) + (sceneAmbient[2] * (1.0 - haze));
}
else {
hColor[0] = fogColor[0];
hColor[1] = fogColor[1];
hColor[2] = fogColor[2];
}
glColor4f(hColor[0], hColor[1], hColor[2], 0.0f);
glVertex(center + toCenter * 0.75f);
glColor4f(hColor[0], hColor[1], hColor[2], 0.5f * planetInfo.hazeDensity);
glVertex(center + toCenter * 0.999f);
}
glEnd();
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
I didnt do anything that spectacular...I could probably speed things up a bit using vertex arrays....but its not slowing down my FPS that bad...
For those interested in this update to DWU...I will have it up sometime soon...
Maybe this will be seen very soon in Celestia!