Esempio n. 1
0
        private void RenderDebugInfo(RenderContext context)
        {
            _debugRenderer.Clear();
            _debugRenderer.DrawAxes(Pose.Identity, 0.5f, true);

            //_debugRenderer.DrawTexture(_cloudLayerNode._renderTarget, new Rectangle(1280-512, 0, 512, 512));

#if XBOX
            _debugRenderer.DrawText(_ephemeris.Time.DateTime.ToString());
#else
            _debugRenderer.DrawText(_ephemeris.Time.ToString());
#endif

            _debugRenderer.PointSize = 10;

            var extraterrestrialSunlight = Ephemeris.ExtraterrestrialSunlight;

            Vector3F sun;
            Vector3F ambient;
            Ephemeris.GetSunlight(_scatteringSky.ObserverAltitude, 2.2f, _scatteringSky.SunDirection, out sun, out ambient);

            var scatterSun     = _scatteringSky.GetSunlight() / _scatteringSky.SunIntensity * extraterrestrialSunlight;
            var scatterAmbient = _scatteringSky.GetAmbientLight(1024);
            scatterAmbient = scatterAmbient / _scatteringSky.SunIntensity * extraterrestrialSunlight;

            var scatterFog = _scatteringSky.GetFogColor(128) / _scatteringSky.SunIntensity * extraterrestrialSunlight;
            var luminance  = Vector3F.Dot(GraphicsHelper.LuminanceWeights, scatterFog);
            scatterFog = InterpolationHelper.Lerp(scatterFog, new Vector3F(luminance), 0.7f);

            _debugRenderer.DrawText("Extraterrestrial sun intensity:" + extraterrestrialSunlight.Length);
            _debugRenderer.DrawText("Spectrum sun intensity:" + sun.Length);
            _debugRenderer.DrawText("Scatter sun intensity:" + scatterSun.Length);

            _debugRenderer.DrawText("\nSpectrum ambient intensity:" + ambient.Length);
            _debugRenderer.DrawText("Scatter ambient intensity:" + scatterAmbient.Length);

            _debugRenderer.DrawText("\nScatter fog intensity:" + scatterFog.Length);

            _debugRenderer.DrawPoint(new Vector3F(-0.5f, 0, 0), new Color((Vector3)extraterrestrialSunlight.Normalized), true);

            sun.TryNormalize();
            ambient /= ambient.Length;
            _debugRenderer.DrawPoint(new Vector3F(0, 0, 0), new Color((Vector3)sun), true);
            _debugRenderer.DrawPoint(new Vector3F(0, -0.5f, 0), new Color((Vector3)ambient), true);

            scatterSun.TryNormalize();
            scatterAmbient.TryNormalize();
            _debugRenderer.DrawPoint(new Vector3F(0.5f, 0, 0), new Color((Vector3)scatterSun), true);
            _debugRenderer.DrawPoint(new Vector3F(0.5f, -0.5f, 0), new Color((Vector3)scatterAmbient), true);

            scatterFog.TryNormalize();
            _debugRenderer.DrawPoint(new Vector3F(0, 0.5f, 0), new Color((Vector3)scatterFog), true);

            _debugRenderer.PointSize = 40f;
            _debugRenderer.Render(context);
        }
Esempio n. 2
0
        private void UpdateSky()
        {
            // Update ephemeris model.
#if XBOX
            _ephemeris.Time = new DateTimeOffset(_time.Ticks, TimeSpan.Zero);
#else
            _ephemeris.Time = _time;
#endif
            _ephemeris.Update();

            // Update rotation of milky way. We also need to add an offset because the
            // cube map texture is rotated.
            _milkyWayNode.PoseWorld = new Pose(
                (Matrix33F)_ephemeris.EquatorialToWorld.Minor
                * Matrix33F.CreateRotationZ(ConstantsF.PiOver2 + -0.004f)
                * Matrix33F.CreateRotationX(ConstantsF.PiOver2 + -0.002f));

            // Update rotation of stars.
            _starfieldNode.PoseWorld = new Pose((Matrix33F)_ephemeris.EquatorialToWorld.Minor);

            // Update direction of sun.
            SunDirection = (Vector3F)_ephemeris.SunDirectionRefracted;
            var sunUp = SunDirection.Orthonormal1;
            _sunNode.LookAt(SunDirection, sunUp);

            // Update direction of moon.
            var moonDirection = (Vector3F)_ephemeris.MoonPosition.Normalized;
            var moonUp        = (Vector3F)_ephemeris.EquatorialToWorld.TransformDirection(Vector3D.Up);
            _moonNode.LookAt(moonDirection, moonUp);

            // The moon needs to know the sun position and brightness to compute the moon phase.
            _moonNode.SunDirection = (Vector3F)_ephemeris.SunPosition.Normalized;
            _moonNode.SunLight     = Ephemeris.ExtraterrestrialSunlight * SunlightScale;

            // The ScatteringSky needs the sun direction and brightness to compute the sky colors.
            _scatteringSkyNode.SunDirection = SunDirection;
            _scatteringSkyNode.SunColor     = Ephemeris.ExtraterrestrialSunlight * ScatteringSkyLightScale;

            // Update the light directions.
            _sunlightNode.LookAt(-SunDirection, sunUp);
            _moonlightNode.LookAt(-moonDirection, moonUp);

            // The ScatteringSkyNode can compute the actual sunlight.
            SunLight = _scatteringSkyNode.GetSunlight();

            // Undo the ScatteringSkyLightScale and apply a custom scale for the sunlight.
            SunLight = SunLight / ScatteringSkyLightScale * SunlightScale;

            // The ScatteringSkyNode can also compute the ambient light by sampling the
            // sky hemisphere.
            AmbientLight = _scatteringSkyNode.GetAmbientLight(256);
            AmbientLight = AmbientLight / ScatteringSkyLightScale * SunlightScale;

            // Desaturate the ambient light to avoid very blue shadows.
            AmbientLight = InterpolationHelper.Lerp(
                new Vector3F(Vector3F.Dot(AmbientLight, GraphicsHelper.LuminanceWeights)),
                AmbientLight,
                0.5f);

            // The Ephemeris model can compute the actual moonlight.
            Vector3F moonlight, moonAmbient;
            Ephemeris.GetMoonlight(
                _scatteringSkyNode.ObserverAltitude,
                2.2f,
                _ephemeris.MoonPosition,
                (float)_ephemeris.MoonPhaseAngle,
                out moonlight,
                out moonAmbient);
            moonlight   *= MoonlightScale;
            moonAmbient *= MoonlightScale;

            // Scale sun light to 0 at horizon.
            var directionalLightColor = SunLight;
            directionalLightColor *= MathHelper.Clamp(SunDirection.Y / 0.1f, 0, 1);

            var directionalLight = ((DirectionalLight)_sunlightNode.Light);
            directionalLight.Color = directionalLightColor;
            ((DirectionalLight)_moonlightNode.Light).Color = moonlight;
            ((AmbientLight)_ambientLightNode.Light).Color  = AmbientLight + moonAmbient + LightPollution;

            // Use the sunlight color to create a bright sun disk.
            var sunDiskColor = SunLight;
            sunDiskColor.TryNormalize();
            _sunNode.GlowColor0 = sunDiskColor * Ephemeris.ExtraterrestrialSunlight.Length * SunlightScale * 10;

            if (_enableClouds)
            {
                // Update lighting info of cloud layer nodes.
                _cloudLayerNode0.SunDirection = SunDirection;
                _cloudLayerNode0.SunLight     = SunLight;
                _cloudLayerNode0.AmbientLight = AmbientLight;

                // The second cloud layer uses simple unlit clouds (only ambient lighting).
                _cloudLayerNode1.SunDirection = SunDirection;
                _cloudLayerNode1.SunLight     = Vector3F.Zero;
                _cloudLayerNode1.AmbientLight = AmbientLight + SunLight;

                // Use the cloud map as the texture for the directional light to create cloud shadows.
                if (EnableCloudShadows)
                {
                    directionalLight.Texture = _cloudLayerNode0.CloudMap.Texture;
                }
                else
                {
                    directionalLight.Texture = null;
                }

                // Compute a texture offset so that the current sun position and the projected cloud
                // shadows match.
                // Since sky dome is always centered on the camera, position the sunlight node in
                // line with the camera.
                var cameraPosition = _cameraObject.CameraNode.PoseWorld.Position;
                var upVector       = Vector3F.AreNumericallyEqual(SunDirection, Vector3F.UnitZ) ? Vector3F.UnitY : Vector3F.UnitZ;
                _sunlightNode.LookAt(cameraPosition + SunDirection, cameraPosition, upVector);

                // Choose a scale for the cloud shadows.
                directionalLight.TextureScale = new Vector2F(-1000);

                // Get the scaled texture offset for the sun direction.
                directionalLight.TextureOffset = _cloudLayerNode0.GetTextureCoordinates(SunDirection) *
                                                 directionalLight.TextureScale;
            }

            // The ScatteringSkyNode can also estimate a fog color by sampling the horizon colors.
            Vector3F fogColor = _scatteringSkyNode.GetFogColor(256, FogSampleAngle);

            // Desaturate the fog color.
            fogColor = InterpolationHelper.Lerp(
                new Vector3F(Vector3F.Dot(fogColor, GraphicsHelper.LuminanceWeights)),
                fogColor,
                FogSaturation);

            // Find any FogNode in the scene and update its fog color.
            foreach (var fogNode in ((Scene)_scene).GetSubtree().OfType <FogNode>())
            {
                var fog = fogNode.Fog;
                fog.Color0             = fog.Color1 = new Vector4F(fogColor, 1);
                fog.ScatteringSymmetry = FogScatteringSymmetry;
            }

            // TODO: If the fog is dense, reduce the direct light and increase the ambient light.
        }