static void initSunlight(void) { getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, 0.0f, 0.0f, sunDirection); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); glLightfv(GL_LIGHT0, GL_DIFFUSE, sunColor); glLightfv(GL_LIGHT0, GL_POSITION, sunDirection); glEnable(GL_LIGHT0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, surfaceColor); }
static void motionCB(int x, int y) { if (moving) { switch (adjustMode) { case 0: /* move globe */ if (!mapMode) { angle = angle + (x - startx); angle2 = angle2 + (y - starty); glutPostRedisplay(); } break; case 1: /* change day of year */ timeOfYear = timeOfYear + (y - starty) / 365.0; while (timeOfYear < 0) timeOfYear += 1.0; while (timeOfYear >= 1.0) timeOfYear -= 1.0; getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, 0.0f, 0.0f, sunDirection); glutPostRedisplay(); break; case 2: /* change time of day (by 4 minute increments (24 hrs / 360)) */ timeOfDay = timeOfDay + (y - starty) / 360.0; while (timeOfDay < 0) timeOfDay += 1.0; while (timeOfDay >= 1.0) timeOfDay -= 1.0; getSunDirection(epoch + timeOfDay + 365.0 * timeOfYear, 0.0f, 0.0f, sunDirection); glutPostRedisplay(); break; } startx = x; starty = y; } }
void setLightsBasedOnDayTime(void) { //On active la light 0 glEnable(GL_LIGHT0); //On recup la direciton du soleil bool nuit = getSunDirection(g_sun_dir, g_mn_lever, g_mn_coucher); //On définit une lumière directionelle (un soleil) float position[4] = { g_sun_dir.X,g_sun_dir.Y,g_sun_dir.Z,0 }; ///w = 0 donc c'est une position a l'infini glLightfv(GL_LIGHT0, GL_POSITION, position); //Pendant la journée if (!nuit) { //On definit la couleur NYColor sunColor(1, 1, 0.8, 1); NYColor skyColor(0, 181.f / 255.f, 221.f / 255.f, 1); NYColor downColor(0.9, 0.5, 0.1, 1); sunColor = sunColor.interpolate(downColor, (abs(g_sun_dir.X))); skyColor = skyColor.interpolate(downColor, (abs(g_sun_dir.X))); g_renderer->setBackgroundColor(skyColor); float color[4] = { sunColor.R,sunColor.V,sunColor.B,1 }; glLightfv(GL_LIGHT0, GL_DIFFUSE, color); float color2[4] = { sunColor.R,sunColor.V,sunColor.B,1 }; glLightfv(GL_LIGHT0, GL_AMBIENT, color2); g_sun_color = sunColor; } else { //La nuit : lune blanche et ciel noir NYColor sunColor(1, 1, 1, 1); NYColor skyColor(0, 0, 0, 1); g_renderer->setBackgroundColor(skyColor); float color[4] = { sunColor.R / 3.f,sunColor.V / 3.f,sunColor.B / 3.f,1 }; glLightfv(GL_LIGHT0, GL_DIFFUSE, color); float color2[4] = { sunColor.R / 7.f,sunColor.V / 7.f,sunColor.B / 7.f,1 }; glLightfv(GL_LIGHT0, GL_AMBIENT, color2); g_sun_color = sunColor; } }
void LLSky::propagateHeavenlyBodies(F32 dt) { if (!mOverrideSimSunPosition) { LLVector3 curr_dir = getSunDirection(); LLVector3 diff = mSunTargDir - curr_dir; const F32 dist = diff.normVec(); if (dist > 0) { const F32 step = llmin (dist, 0.00005f); //const F32 step = min (dist, 0.0001); diff *= step; curr_dir += diff; curr_dir.normVec(); if (mVOSkyp) { mVOSkyp->setSunDirection(curr_dir, LLVector3()); } } } }
WFMath::Vector<3> CaelumSun::getMainLightDirection() const { return Convert::toWF<WFMath::Vector<3>>(getSunDirection()); }
AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(const Vector3 &direction) { AtmosphereDefinition *definition; Vector3 sun_direction, sun_position, camera_location; Color base; definition = getDefinition(); camera_location = parent->getCameraLocation(VECTOR_ZERO); sun_direction = getSunDirection(); Vector3 direction_norm = direction.normalize(); sun_position = sun_direction.scale(SUN_DISTANCE_SCALED); base = COLOR_BLACK; // Get night sky base = base.add(parent->getNightSky()->getColor(camera_location.y, direction_norm)); // Get sun shape /*if (v3Dot(sun_direction, direction) >= 0) { double sun_radius = definition->sun_radius * SUN_RADIUS_SCALED * 5.0; // FIXME Why should we multiply by 5 ? Vector3 hit1, hit2; int hits = euclidRayIntersectSphere(camera_location, direction, sun_position, sun_radius, &hit1, &hit2); if (hits > 1) { double dist = v3Norm(v3Sub(hit2, hit1)) / sun_radius; // distance between intersection points (relative to radius) Color sun_color = definition->sun_color; sun_color.r *= 100.0; sun_color.g *= 100.0; sun_color.b *= 100.0; if (dist <= 0.05) { sun_color.r *= 1.0 - dist / 0.05; sun_color.g *= 1.0 - dist / 0.05; sun_color.b *= 1.0 - dist / 0.05; } base = sun_color; } }*/ // Get scattering AtmosphereResult result; Vector3 location = camera_location.add(direction_norm.scale(6421.0)); switch (definition->model) { case AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON: result = model->getSkyColor(camera_location, direction_norm, sun_position, base); break; default: result = BaseAtmosphereRenderer::applyAerialPerspective(location, result.base); } // Apply god rays ponderation result.inscattering = parent->getGodRaysSampler()->apply(COLOR_BLACK, result.inscattering, location); // Apply weather effects _applyWeatherEffects(definition, &result); return result; }
void AtmosphereManager::_update(const Options& NewOptions, const bool& ForceToUpdateAll) { GPUManager *mGPUManager = mSkyX->getGPUManager(); if (NewOptions.Time != mOptions.Time || NewOptions.EastPosition != mOptions.EastPosition || ForceToUpdateAll) { mOptions.Time = NewOptions.Time; mOptions.EastPosition = NewOptions.EastPosition; if (mSkyX->isStarfieldEnabled()) { mGPUManager->setGpuProgramParameter(GPUManager::GPUP_FRAGMENT, "uTime", mSkyX->_getTimeOffset()*0.5f, false); } mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uLightDir", -getSunDirection()); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_FRAGMENT, "uLightDir", -getSunDirection(), false); mSkyX->getMoonManager()->update(); } if (NewOptions.InnerRadius != mOptions.InnerRadius || NewOptions.OuterRadius != mOptions.OuterRadius || ForceToUpdateAll) { mOptions.InnerRadius = NewOptions.InnerRadius; mOptions.OuterRadius = NewOptions.OuterRadius; float Scale = 1.0f / (mOptions.OuterRadius - mOptions.InnerRadius), ScaleDepth = (mOptions.OuterRadius - mOptions.InnerRadius) / 2.0f, ScaleOverScaleDepth = Scale / ScaleDepth; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uInnerRadius", mOptions.InnerRadius); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uCameraPos", Ogre::Vector3(0, mOptions.InnerRadius + (mOptions.OuterRadius-mOptions.InnerRadius)*mOptions.HeightPosition, 0)); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uScale", Scale); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uScaleDepth", ScaleDepth); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uScaleOverScaleDepth", ScaleOverScaleDepth); } if (NewOptions.HeightPosition != mOptions.HeightPosition || ForceToUpdateAll) { mOptions.HeightPosition = NewOptions.HeightPosition; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uCameraPos", Ogre::Vector3(0, mOptions.InnerRadius + (mOptions.OuterRadius-mOptions.InnerRadius)*mOptions.HeightPosition, 0)); } if (NewOptions.RayleighMultiplier != mOptions.RayleighMultiplier || NewOptions.SunIntensity != mOptions.SunIntensity || ForceToUpdateAll) { mOptions.RayleighMultiplier = NewOptions.RayleighMultiplier; float Kr4PI = mOptions.RayleighMultiplier * 4.0f * Ogre::Math::PI, KrESun = mOptions.RayleighMultiplier * mOptions.SunIntensity; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uKr4PI", Kr4PI); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uKrESun", KrESun); } if (NewOptions.MieMultiplier != mOptions.MieMultiplier || NewOptions.SunIntensity != mOptions.SunIntensity || ForceToUpdateAll) { mOptions.MieMultiplier = NewOptions.MieMultiplier; float Km4PI = mOptions.MieMultiplier * 4.0f * Ogre::Math::PI, KmESun = mOptions.MieMultiplier * mOptions.SunIntensity; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uKm4PI", Km4PI); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uKmESun", KmESun, false); } if (NewOptions.NumberOfSamples != mOptions.NumberOfSamples || ForceToUpdateAll) { mOptions.NumberOfSamples = NewOptions.NumberOfSamples; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uNumberOfSamples", mOptions.NumberOfSamples); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uSamples", static_cast<Ogre::Real>(mOptions.NumberOfSamples)); } if (NewOptions.WaveLength != mOptions.WaveLength || ForceToUpdateAll) { mOptions.WaveLength = NewOptions.WaveLength; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_VERTEX, "uInvWaveLength", Ogre::Vector3(1.0f / Ogre::Math::Pow(mOptions.WaveLength.x, 4.0f), 1.0f / Ogre::Math::Pow(mOptions.WaveLength.y, 4.0f), 1.0f / Ogre::Math::Pow(mOptions.WaveLength.z, 4.0f))); } if (NewOptions.G != mOptions.G || ForceToUpdateAll) { mOptions.G = NewOptions.G; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_FRAGMENT, "uG", mOptions.G, false); mGPUManager->setGpuProgramParameter(GPUManager::GPUP_FRAGMENT, "uG2", mOptions.G*mOptions.G, false); } if ((NewOptions.Exposure != mOptions.Exposure || ForceToUpdateAll) && (mSkyX->getLightingMode() == SkyX::LM_LDR)) { mOptions.Exposure = NewOptions.Exposure; mGPUManager->setGpuProgramParameter(GPUManager::GPUP_FRAGMENT, "uExposure", mOptions.Exposure); } mSkyX->getCloudsManager()->_updateInternal(); }
const Ogre::Vector3 AtmosphereManager::getSunPosition() const { return mSkyX->getCamera()->getDerivedPosition() - getSunDirection()*mSkyX->getMeshManager()->getSkydomeRadius(); }
const Ogre::Vector3 AtmosphereManager::getColorAt(const Ogre::Vector3& Direction) const { if (Direction.y<0) { return Ogre::Vector3(0,0,0); } // Parameters double Scale = 1.0f / (mOptions.OuterRadius - mOptions.InnerRadius), ScaleDepth = (mOptions.OuterRadius - mOptions.InnerRadius) / 2.0f, ScaleOverScaleDepth = Scale / ScaleDepth, Kr4PI = mOptions.RayleighMultiplier * 4.0f * Ogre::Math::PI, KrESun = mOptions.RayleighMultiplier * mOptions.SunIntensity, Km4PI = mOptions.MieMultiplier * 4.0f * Ogre::Math::PI, KmESun = mOptions.MieMultiplier * mOptions.SunIntensity; // --- Start vertex program simulation --- Ogre::Vector3 uLightDir = -getSunDirection(), v3Pos = Direction, uCameraPos = Ogre::Vector3(0, mOptions.InnerRadius + (mOptions.OuterRadius-mOptions.InnerRadius)*mOptions.HeightPosition, 0), uInvWaveLength = Ogre::Vector3( 1.0f / Ogre::Math::Pow(mOptions.WaveLength.x, 4.0f), 1.0f / Ogre::Math::Pow(mOptions.WaveLength.y, 4.0f), 1.0f / Ogre::Math::Pow(mOptions.WaveLength.z, 4.0f)); // Get the ray from the camera to the vertex, and it's length (far point) v3Pos.y += mOptions.InnerRadius; Ogre::Vector3 v3Ray = v3Pos - uCameraPos; double fFar = v3Ray.length(); v3Ray /= fFar; // Calculate the ray's starting position, then calculate its scattering offset Ogre::Vector3 v3Start = uCameraPos; double fHeight = uCameraPos.y, fStartAngle = v3Ray.dotProduct(v3Start) / fHeight, fDepth = Ogre::Math::Exp(ScaleOverScaleDepth * (mOptions.InnerRadius - uCameraPos.y)), fStartOffset = fDepth * _scale(fStartAngle, ScaleDepth); // Init loop variables double fSampleLength = fFar /(double)mOptions.NumberOfSamples, fScaledLength = fSampleLength * Scale, fHeight_, fDepth_, fLightAngle, fCameraAngle, fScatter; Ogre::Vector3 v3SampleRay = v3Ray * fSampleLength, v3SamplePoint = v3Start + v3SampleRay * 0.5f, color, v3Attenuate; // Loop the ray for (int i = 0; i < mOptions.NumberOfSamples; i++) { fHeight_ = v3SamplePoint.length(); fDepth_ = Ogre::Math::Exp(ScaleOverScaleDepth * (mOptions.InnerRadius-fHeight_)); fLightAngle = uLightDir.dotProduct(v3SamplePoint) / fHeight_; fCameraAngle = v3Ray.dotProduct(v3SamplePoint) / fHeight_; fScatter = (fStartOffset + fDepth*(_scale(fLightAngle, ScaleDepth) - _scale(fCameraAngle, ScaleDepth))); v3Attenuate = Ogre::Vector3( Ogre::Math::Exp(-fScatter * (uInvWaveLength.x * Kr4PI + Km4PI)), Ogre::Math::Exp(-fScatter * (uInvWaveLength.y * Kr4PI + Km4PI)), Ogre::Math::Exp(-fScatter * (uInvWaveLength.z * Kr4PI + Km4PI))); // Accumulate color v3Attenuate *= (fDepth_ * fScaledLength); color += v3Attenuate; // Next sample point v3SamplePoint += v3SampleRay; } // Outputs Ogre::Vector3 oRayleighColor = color * (uInvWaveLength * KrESun), oMieColor = color * KmESun, oDirection = uCameraPos - v3Pos; // --- End vertex program simulation --- // --- Start fragment program simulation --- double cos = uLightDir.dotProduct(oDirection) / oDirection.length(), cos2 = cos*cos, rayleighPhase = 0.75 * (1.0 + 0.5*cos2), g2 = mOptions.G*mOptions.G, miePhase = 1.5f * ((1.0f - g2) / (2.0f + g2)) * (1.0f + cos2) / Ogre::Math::Pow(1.0f + g2 - 2.0f * mOptions.G * cos, 1.5f); Ogre::Vector3 oColor; if (mSkyX->getLightingMode() == SkyX::LM_LDR) { oColor = Ogre::Vector3( 1 - Ogre::Math::Exp(-mOptions.Exposure * (rayleighPhase * oRayleighColor.x + miePhase * oMieColor.x)), 1 - Ogre::Math::Exp(-mOptions.Exposure * (rayleighPhase * oRayleighColor.y + miePhase * oMieColor.y)), 1 - Ogre::Math::Exp(-mOptions.Exposure * (rayleighPhase * oRayleighColor.z + miePhase * oMieColor.z))); } else { oColor = rayleighPhase * oRayleighColor + miePhase * oMieColor; } // For night rendering oColor += Ogre::Math::Clamp<Ogre::Real>(((1 - std::max(oColor.x, std::max(oColor.y, oColor.z))*10)), 0, 1) * (Ogre::Vector3(0.05, 0.05, 0.1) * (2-0.75f*Ogre::Math::Clamp<Ogre::Real>(-uLightDir.y, 0, 1)) * Ogre::Math::Pow(1-Direction.y, 3)); // --- End fragment program simulation --- // Output color return oColor; }