#include "stdneb.h" #include "Atmosphere.h" namespace Sky { __ImplementClass( Atmosphere, 'ATMO', Core::RefCounted); Atmosphere::Atmosphere() : m_Options(Options()), m_LigntingMode(LM_LDR) { } Atmosphere::~Atmosphere() { } const float Atmosphere::_Scale(const float &cos, const float &uScaleDepth) const { float x = 1.0f - cos; return uScaleDepth * Math::n_exp(-0.00287f + x*(0.459f + x*(3.83f + x*(-6.80f + x*5.25f)))); } const Math::float3 Atmosphere::GetColorAt(const Math::float3 &Direction) const { if (Direction.y() < 0) { return Math::float3(0.0, 0.0, 0.0); } // Parameters float Scale = 1.0f / (m_Options.OuterRadius - m_Options.InnerRadius), ScaleDepth = (m_Options.OuterRadius - m_Options.InnerRadius) / 2.0f, ScaleOverScaleDepth = Scale / ScaleDepth, Kr4PI = float(m_Options.RayleighMultiplier * 4.0f * PI), KrESun = m_Options.RayleighMultiplier * m_Options.SunIntensity, Km4PI = float(m_Options.MieMultiplier * 4.0f * PI), KmESun = m_Options.MieMultiplier * m_Options.SunIntensity; // --- Start vertex program simulation --- Math::float3 uLightDir = - GetSunDirection(), v3Pos = Direction, uCameraPos = Math::float3(0.0f, m_Options.InnerRadius + (m_Options.OuterRadius - m_Options.InnerRadius) * m_Options.HeightPosition, 0.0f), uInvWaveLength = Math::float3( 1.0f / Math::n_pow(m_Options.WaveLength.x(), 4.0f), 1.0f / Math::n_pow(m_Options.WaveLength.y(), 4.0f), 1.0f / Math::n_pow(m_Options.WaveLength.z(), 4.0f) ); // Get the ray from the camera to the vertex, and it's length (far point) v3Pos.y() += m_Options.InnerRadius; Math::float3 v3Ray = v3Pos - uCameraPos; float fFar = v3Ray.length(); v3Ray /= fFar; // Calculate the ray's starting position, then calculate its scattering offset Math::float3 v3Start = uCameraPos; float fHeight = uCameraPos.y(), fStartAngle = v3Ray.dotProduct(v3Start) / fHeight, fDepth = Math::n_exp(ScaleOverScaleDepth * (m_Options.InnerRadius - uCameraPos.y())), fStartOffset = fDepth * _Scale(fStartAngle, ScaleDepth); // Init loop variables float fSampleLength = fFar / static_cast (m_Options.NumberOfSamples), fScaledLength = fSampleLength * Scale, fHeight_, fDepth_, fLightAngle, fCameraAngle, fScatter; Math::float3 v3SampleRay = v3Ray * fSampleLength, v3SamplePoint = v3Start + v3SampleRay * 0.5, color, v3Attenuate; // Loop the ray for (IndexT i = 0; iB) { if (X -0.5f) { y *= 2; } else { y = -(1 + y) * 2.0f; } } else { y = (X-A)/(B-A); if (y < 0.5f) { y *= 2.0f; } else { y = (1 - y) * 2.0f; } } Math::float2 East = m_Options.EastPosition; East = Math::float2::normalize(East); if (X > A && X < B) { if (X > (A + AB_/2)) { East = -East; } } else { if (X