public EnvironmentLightSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; _graphicsScreen = new DeferredGraphicsScreen(Services); _graphicsScreen.DrawReticle = true; GraphicsService.Screens.Insert(0, _graphicsScreen); GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services)); Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer); Services.Register(typeof(IScene), null, _graphicsScreen.Scene); // Add gravity and damping to the physics Simulation. Simulation.ForceEffects.Add(new Gravity()); Simulation.ForceEffects.Add(new Damping()); // Add a custom game object which controls the camera. var cameraGameObject = new CameraObject(Services); GameObjectService.Objects.Add(cameraGameObject); _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode; GameObjectService.Objects.Add(new GrabObject(Services)); GameObjectService.Objects.Add(new GroundObject(Services)); GameObjectService.Objects.Add(new DudeObject(Services)); var lavaBallsObject = new LavaBallsObject(Services); GameObjectService.Objects.Add(lavaBallsObject); GameObjectService.Objects.Add(new ObjectCreatorObject(Services)); GameObjectService.Objects.Add(new FogObject(Services)); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3(0, 0, -2)))); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3(3, 0, 0), Quaternion.CreateRotationY(MathHelper.ToRadians(-20))))); GameObjectService.Objects.Add(new StaticSkyObject(Services)); // Add a few palm trees. Random random = new Random(12345); for (int i = 0; i < 10; i++) { Vector3 position = new Vector3(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5)); Matrix orientation = Matrix.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi)); float scale = random.NextFloat(0.5f, 1.2f); GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation))); } // Add some more dynamic objects. for (int i = 0; i < 5; i++) { lavaBallsObject.Spawn(); GameObjectService.Objects.Add(new ProceduralObject(Services)); GameObjectService.Objects.Add(new DynamicObject(Services, 7)); } // To show the effect of the EnvironmentLight in isolation, disable all other light sources. //foreach (var light in _graphicsScreen.Scene.GetDescendants().OfType<LightNode>()) // light.IsEnabled = false; // Add the environment light. var environmentLight = new EnvironmentLight { Color = new Vector3(0.1f), DiffuseIntensity = 0, SpecularIntensity = 1, EnvironmentMap = ContentManager.Load <TextureCube>("Sky2"), }; var environmentLightNode = new LightNode(environmentLight) { Name = "Environment", }; _graphicsScreen.Scene.Children.Add(environmentLightNode); // The EnvironmentLight is a new light type. We have to register a light renderer // for this light in the LightRenderer of the DeferredGraphicsScreen. _graphicsScreen.LightBufferRenderer.LightRenderer.Renderers.Add(new EnvironmentLightRenderer(GraphicsService)); // EnvironmentLight.fx uses the specular power of the materials to determine // which mip map level of the cube is reflected. // In reality, a high specular power is necessary to reflect the cube map // with all its detail. To reflect a cube map level with 512 texels size, we // need a specular power of ~200000. // To make the reflection effects more obvious, let's change some material properties // and make the more reflective. // ProceduralObject: var proceduralObjects = _graphicsScreen.Scene .GetDescendants() .OfType <MeshNode>() .Where(mn => mn.Mesh.Name == "ProceduralObject") .Select(mn => mn.Mesh); foreach (var mesh in proceduralObjects) { foreach (var material in mesh.Materials) { material["GBuffer"].Set("SpecularPower", 10000f); material["Material"].Set("DiffuseColor", new Vector3(0.01f)); material["Material"].Set("SpecularColor", new Vector3(1)); } } // Frame of GlassBox: var glassBoxes = _graphicsScreen.Scene .GetDescendants() .OfType <ModelNode>() .Where(mn => mn.Name == "GlassBox") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in glassBoxes) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 100000f); material["Material"].Set("DiffuseColor", new Vector3(0.0f)); material["Material"].Set("SpecularColor", new Vector3(1)); } } // LavaBall: var lavaBalls = _graphicsScreen.Scene .GetDescendants() .OfType <ModelNode>() .Where(mn => mn.Name == "LavaBall") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in lavaBalls) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 10000f); material["Material"].Set("DiffuseColor", new Vector3(0.0f)); material["Material"].Set("SpecularColor", new Vector3(10)); material["Material"].Set("EmissiveColor", new Vector3(0.0f)); } } // Ground plane: var groundPlanes = _graphicsScreen.Scene .GetDescendants() .OfType <ModelNode>() .Where(mn => mn.Name == "Ground") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in groundPlanes) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 200000.0f); material["Material"].Set("DiffuseColor", new Vector3(0.5f)); material["Material"].Set("SpecularColor", new Vector3(0.4f)); } } // Please note, XNA does not filter cube maps over cube map borders. Therefore, reflections // of low resolution mip map levels might show obvious borders between the cube map // sides. In this case you can change the EnvironmentLight.fx effect to always reflect // the mip map level 0. // This is not a problem with MonoGame because DirectX automatically filters cube map borders. }
public EnvironmentLightSample(Microsoft.Xna.Framework.Game game) : base(game) { SampleFramework.IsMouseVisible = false; _graphicsScreen = new DeferredGraphicsScreen(Services); _graphicsScreen.DrawReticle = true; GraphicsService.Screens.Insert(0, _graphicsScreen); GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services)); Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer); Services.Register(typeof(IScene), null, _graphicsScreen.Scene); // Add gravity and damping to the physics Simulation. Simulation.ForceEffects.Add(new Gravity()); Simulation.ForceEffects.Add(new Damping()); // Add a custom game object which controls the camera. var cameraGameObject = new CameraObject(Services); GameObjectService.Objects.Add(cameraGameObject); _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode; GameObjectService.Objects.Add(new GrabObject(Services)); GameObjectService.Objects.Add(new GroundObject(Services)); GameObjectService.Objects.Add(new DudeObject(Services)); var lavaBallsObject = new LavaBallsObject(Services); GameObjectService.Objects.Add(lavaBallsObject); GameObjectService.Objects.Add(new ObjectCreatorObject(Services)); GameObjectService.Objects.Add(new FogObject(Services)); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Barrier", 0.9f, new Pose(new Vector3F(0, 0, -2)))); GameObjectService.Objects.Add(new StaticObject(Services, "Barrier/Cylinder", 0.9f, new Pose(new Vector3F(3, 0, 0), QuaternionF.CreateRotationY(MathHelper.ToRadians(-20))))); GameObjectService.Objects.Add(new StaticSkyObject(Services)); // Add a few palm trees. Random random = new Random(12345); for (int i = 0; i < 10; i++) { Vector3F position = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5)); Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi)); float scale = random.NextFloat(0.5f, 1.2f); GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation))); } // Add some more dynamic objects. for (int i = 0; i < 5; i++) { lavaBallsObject.Spawn(); GameObjectService.Objects.Add(new ProceduralObject(Services)); GameObjectService.Objects.Add(new DynamicObject(Services, 7)); } // To show the effect of the EnvironmentLight in isolation, disable all other light sources. //foreach (var light in _graphicsScreen.Scene.GetDescendants().OfType<LightNode>()) // light.IsEnabled = false; // Add the environment light. var environmentLight = new EnvironmentLight { Color = new Vector3F(0.1f), DiffuseIntensity = 0, SpecularIntensity = 1, EnvironmentMap = ContentManager.Load<TextureCube>("Sky2"), }; var environmentLightNode = new LightNode(environmentLight) { Name = "Environment", }; _graphicsScreen.Scene.Children.Add(environmentLightNode); // The EnvironmentLight is a new light type. We have to register a light renderer // for this light in the LightRenderer of the DeferredGraphicsScreen. _graphicsScreen.LightBufferRenderer.LightRenderer.Renderers.Add(new EnvironmentLightRenderer(GraphicsService)); // EnvironmentLight.fx uses the specular power of the materials to determine // which mip map level of the cube is reflected. // In reality, a high specular power is necessary to reflect the cube map // with all its detail. To reflect a cube map level with 512 texels size, we // need a specular power of ~200000. // To make the reflection effects more obvious, let's change some material properties // and make the more reflective. // ProceduralObject: var proceduralObjects = _graphicsScreen.Scene .GetDescendants() .OfType<MeshNode>() .Where(mn => mn.Mesh.Name == "ProceduralObject") .Select(mn => mn.Mesh); foreach (var mesh in proceduralObjects) { foreach (var material in mesh.Materials) { material["GBuffer"].Set("SpecularPower", 10000f); material["Material"].Set("DiffuseColor", new Vector3(0.01f)); material["Material"].Set("SpecularColor", new Vector3(1)); } } // Frame of GlassBox: var glassBoxes = _graphicsScreen.Scene .GetDescendants() .OfType<ModelNode>() .Where(mn => mn.Name == "GlassBox") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in glassBoxes) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 100000f); material["Material"].Set("DiffuseColor", new Vector3(0.0f)); material["Material"].Set("SpecularColor", new Vector3(1)); } } // LavaBall: var lavaBalls = _graphicsScreen.Scene .GetDescendants() .OfType<ModelNode>() .Where(mn => mn.Name == "LavaBall") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in lavaBalls) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 10000f); material["Material"].Set("DiffuseColor", new Vector3(0.0f)); material["Material"].Set("SpecularColor", new Vector3(10)); material["Material"].Set("EmissiveColor", new Vector3(0.0f)); } } // Ground plane: var groundPlanes = _graphicsScreen.Scene .GetDescendants() .OfType<ModelNode>() .Where(mn => mn.Name == "Ground") .Select(mn => ((MeshNode)mn.Children[0]).Mesh); foreach (var mesh in groundPlanes) { foreach (var material in mesh.Materials.Where(m => m.Contains("GBuffer"))) { material["GBuffer"].Set("SpecularPower", 200000.0f); material["Material"].Set("DiffuseColor", new Vector3(0.5f)); material["Material"].Set("SpecularColor", new Vector3(0.4f)); } } // Please note, XNA does not filter cube maps over cube map borders. Therefore, reflections // of low resolution mip map levels might show obvious borders between the cube map // sides. In this case you can change the EnvironmentLight.fx effect to always reflect // the mip map level 0. // This is not a problem with MonoGame because DirectX automatically filters cube map borders. }