private void RenderReach(SkyboxNode node, RenderContext context) { var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; graphicsDevice.BlendState = node.EnableAlphaBlending ? BlendState.AlphaBlend : BlendState.Opaque; graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; // Change viewport to render all pixels at max z. var originalViewport = graphicsDevice.Viewport; var viewport = originalViewport; viewport.MinDepth = viewport.MaxDepth; graphicsDevice.Viewport = viewport; var cameraNode = context.CameraNode; var view = cameraNode.View; view.Translation = Vector3F.Zero; var projection = cameraNode.Camera.Projection; var basicEffect = (BasicEffect)_effect; basicEffect.View = (Matrix)view; basicEffect.Projection = projection; basicEffect.DiffuseColor = (Vector3)node.Color; basicEffect.Alpha = node.EnableAlphaBlending ? node.Alpha : 1; // Scale skybox such that it lies within view frustum: // distance of a skybox corner = √3 // √3 * scale = far // => scale = far / √3 // (Note: If near > far / √3 then the skybox will be clipped.) float scale = projection.Far * 0.577f; var orientation = node.PoseWorld.Orientation; // Positive X basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.PositiveX); basicEffect.World = (Matrix)new Matrix44F(orientation * scale, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); // Negative X // transform = scale * rotY(180°) var transform = new Matrix33F(-scale, 0, 0, 0, scale, 0, 0, 0, -scale); basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.NegativeX); basicEffect.World = (Matrix)new Matrix44F(orientation * transform, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); // Positive Y // transform = scale * rotX(90°) * rotY(90°) transform = new Matrix33F(0, 0, scale, scale, 0, 0, 0, scale, 0); basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.PositiveY); basicEffect.World = (Matrix)new Matrix44F(orientation * transform, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); // Negative Y // transform = scale * rotX(-90°) * rotY(90°) transform = new Matrix33F(0, 0, scale, -scale, 0, 0, 0, -scale, 0); basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.NegativeY); basicEffect.World = (Matrix)new Matrix44F(orientation * transform, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); // Cube maps are left-handed, where as the world is right-handed! // Positive Z (= negative Z in world space) // transform = scale * rotY(90°) transform = new Matrix33F(0, 0, scale, 0, scale, 0, -scale, 0, 0); basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.PositiveZ); basicEffect.World = (Matrix)new Matrix44F(orientation * transform, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); // Negative Z (= positive Z in world space) // transform = scale * rotY(-90°) transform = new Matrix33F(0, 0, -scale, 0, scale, 0, scale, 0, 0); basicEffect.Texture = GetTexture2D(graphicsDevice, node.Texture, CubeMapFace.NegativeZ); basicEffect.World = (Matrix)new Matrix44F(orientation * transform, Vector3F.Zero); basicEffect.CurrentTechnique.Passes[0].Apply(); graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _faceVertices, 0, 2); graphicsDevice.Viewport = originalViewport; savedRenderState.Restore(); }
// OnLoad() is called when the GameObject is added to the IGameObjectService. protected override void OnLoad() { var content = _services.GetInstance<ContentManager>(); _skyboxNode = new SkyboxNode(content.Load<TextureCube>("Sky2")) { Color = new Vector3F(SkyExposure), }; // The ambient light. var ambientLight = new AmbientLight { Color = new Vector3F(0.9f, 0.9f, 1f), HdrScale = 0.1f, Intensity = 0.5f, HemisphericAttenuation = 0.8f, }; _ambientLightNode = new LightNode(ambientLight) { Name = "Ambient", }; // The main directional light. var sunlight = new DirectionalLight { Color = new Vector3F(1, 0.9607844f, 0.9078432f), HdrScale = 0.4f, DiffuseIntensity = 1, SpecularIntensity = 1, }; _sunlightNode = new LightNode(sunlight) { Name = "Sunlight", Priority = 10, // This is the most important light. PoseWorld = new Pose(QuaternionF.CreateRotationY(-1.4f) * QuaternionF.CreateRotationX(-0.6f)), // This light uses Cascaded Shadow Mapping. Shadow = new CascadedShadow { #if XBOX PreferredSize = 512, #else PreferredSize = 1024, #endif Prefer16Bit = true, } }; // Add a lens flare for the key light. var lensFlare = new LensFlare(true) { QuerySize = 0.2f, Size = 0.2f, Name = "Sun Flare" }; var lensFlareTexture = content.Load<Texture2D>("LensFlare/LensFlares"); var circleTexture = new PackedTexture("Circle", lensFlareTexture, new Vector2F(0, 0), new Vector2F(0.25f, 0.5f)); var glowTexture = new PackedTexture("Glow", lensFlareTexture, new Vector2F(0.25f, 0), new Vector2F(0.25f, 0.5f)); var ringTexture = new PackedTexture("Ring", lensFlareTexture, new Vector2F(0.5f, 0), new Vector2F(0.25f, 0.5f)); var haloTexture = new PackedTexture("Halo", lensFlareTexture, new Vector2F(0.75f, 0), new Vector2F(0.25f, 0.5f)); var sunTexture = new PackedTexture("Sun", lensFlareTexture, new Vector2F(0, 0.5f), new Vector2F(0.25f, 0.5f)); var streaksTexture = new PackedTexture("Streaks", lensFlareTexture, new Vector2F(0.25f, 0.5f), new Vector2F(0.25f, 0.5f)); var flareTexture = new PackedTexture("Flare", lensFlareTexture, new Vector2F(0.5f, 0.5f), new Vector2F(0.25f, 0.5f)); lensFlare.Elements.Add(new LensFlareElement(-0.2f, 0.55f, 0.0f, new Color(175, 175, 255, 20), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 0.9f, 0.0f, new Color(255, 255, 255, 255), new Vector2F(0.5f, 0.5f), sunTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 1.8f, 0.0f, new Color(255, 255, 255, 128), new Vector2F(0.5f, 0.5f), streaksTexture)); lensFlare.Elements.Add(new LensFlareElement(0.0f, 2.6f, 0.0f, new Color(255, 255, 200, 64), new Vector2F(0.5f, 0.5f), glowTexture)); lensFlare.Elements.Add(new LensFlareElement(0.5f, 0.12f, 0.0f, new Color(60, 60, 180, 35), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.55f, 0.46f, 0.0f, new Color(100, 100, 200, 60), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.6f, 0.17f, 0.0f, new Color(120, 120, 220, 40), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(0.85f, 0.2f, 0.0f, new Color(60, 60, 255, 100), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.2f, 0.0f, new Color(255, 60, 60, 130), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(0.15f, 0.15f, 0.0f, new Color(255, 60, 60, 90), new Vector2F(0.5f, 0.5f), flareTexture)); lensFlare.Elements.Add(new LensFlareElement(1.3f, 0.6f, 0.0f, new Color(60, 60, 255, 180), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.4f, 0.2f, 0.0f, new Color(220, 80, 80, 98), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.5f, 0.1f, 0.0f, new Color(220, 80, 80, 85), new Vector2F(0.5f, 0.5f), circleTexture)); lensFlare.Elements.Add(new LensFlareElement(1.6f, 0.5f, 0.0f, new Color(60, 60, 255, 80), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(1.8f, 0.3f, 0.0f, new Color(90, 60, 255, 110), new Vector2F(0.5f, 0.5f), ringTexture)); lensFlare.Elements.Add(new LensFlareElement(1.95f, 0.5f, 0.0f, new Color(60, 60, 255, 120), new Vector2F(0.5f, 0.5f), haloTexture)); lensFlare.Elements.Add(new LensFlareElement(2.0f, 0.15f, 0.0f, new Color(60, 60, 255, 85), new Vector2F(0.5f, 0.5f), circleTexture)); // Add lens flare as a child of the sunlight. var lensFlareNode = new LensFlareNode(lensFlare); _sunlightNode.Children = new SceneNodeCollection(); _sunlightNode.Children.Add(lensFlareNode); // Add scene nodes to scene graph. var scene = _services.GetInstance<IScene>(); scene.Children.Add(_skyboxNode); scene.Children.Add(_ambientLightNode); scene.Children.Add(_sunlightNode); }
private void RenderHiDef(SkyboxNode node, RenderContext context) { var graphicsDevice = context.GraphicsService.GraphicsDevice; var savedRenderState = new RenderStateSnapshot(graphicsDevice); graphicsDevice.RasterizerState = RasterizerState.CullNone; graphicsDevice.DepthStencilState = DepthStencilState.DepthRead; graphicsDevice.BlendState = node.EnableAlphaBlending ? BlendState.AlphaBlend : BlendState.Opaque; bool sourceIsFloatingPoint = TextureHelper.IsFloatingPointFormat(node.Texture.Format); // Set sampler state. (Floating-point textures cannot use linear filtering. (XNA would throw an exception.)) if (sourceIsFloatingPoint) graphicsDevice.SamplerStates[0] = SamplerState.PointClamp; else graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; var cameraNode = context.CameraNode; Matrix44F view = cameraNode.View; Matrix44F projection = cameraNode.Camera.Projection; // Cube maps are left handed --> Sample with inverted z. (Otherwise, the // cube map and objects or texts in it are mirrored.) var mirrorZ = Matrix44F.CreateScale(1, 1, -1); Matrix33F orientation = node.PoseWorld.Orientation; _parameterWorldViewProjection.SetValue((Matrix)(projection * view * new Matrix44F(orientation, Vector3F.Zero) * mirrorZ)); Vector4 color = node.EnableAlphaBlending ? new Vector4((Vector3)node.Color * node.Alpha, node.Alpha) // Premultiplied : new Vector4((Vector3)node.Color, 1); // Opaque _parameterColor.SetValue(color); _textureParameter.SetValue(node.Texture); if (node.Encoding is RgbEncoding) { _parameterTextureSize.SetValue(node.Texture.Size); if (context.IsHdrEnabled()) _passRgbToRgb.Apply(); else _passRgbToSRgb.Apply(); } else if (node.Encoding is SRgbEncoding) { if (!sourceIsFloatingPoint) { if (context.IsHdrEnabled()) _passSRgbToRgb.Apply(); else _passSRgbToSRgb.Apply(); } else { throw new GraphicsException("sRGB encoded skybox cube maps must not use a floating point format."); } } else if (node.Encoding is RgbmEncoding) { float max = GraphicsHelper.ToGamma(((RgbmEncoding)node.Encoding).Max); _parameterRgbmMaxValue.SetValue(max); if (context.IsHdrEnabled()) _passRgbmToRgb.Apply(); else _passRgbmToSRgb.Apply(); } else { throw new NotSupportedException("The SkyBoxRenderer supports only RgbEncoding, SRgbEncoding and RgbmEncoding."); } _submesh.Draw(); savedRenderState.Restore(); }
// OnUnload() is called when the GameObject is removed from the IGameObjectService. protected override void OnUnload() { _skyboxNode.Parent.Children.Remove(_skyboxNode); _skyboxNode.Dispose(false); _skyboxNode = null; _ambientLightNode.Parent.Children.Remove(_ambientLightNode); _ambientLightNode.Dispose(false); _ambientLightNode = null; _sunlightNode.Parent.Children.Remove(_sunlightNode); _sunlightNode.Dispose(false); _sunlightNode = null; }