Пример #1
0
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);
}
Пример #2
0
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;
  }
}
Пример #3
0
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;
	}
}
Пример #4
0
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());
			}
		}
	}
}
Пример #5
0
WFMath::Vector<3> CaelumSun::getMainLightDirection() const
{
	return Convert::toWF<WFMath::Vector<3>>(getSunDirection());
}
Пример #6
0
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;
	}