private void DrawSolidObjects(Camera camera, Matrix lightView, bool enableShadows) { _device.BlendState = BlendState.Opaque; foreach (var sceneNode in _solidObjects) { var worldMatrix = sceneNode.GetWorldMatrix(camera); if (enableShadows && sceneNode.Material.ReceiveShadow) { _sceneEffect.ActivateLightingTechnique(true); _sceneEffect.LightWorldViewProjection = worldMatrix*lightView; _sceneEffect.ShadowMap = _shadowMap; } else { _sceneEffect.ActivateLightingTechnique(false); } _sceneEffect.World = worldMatrix; _sceneEffect.DiffuseTexture = sceneNode.Material.DiffuseTexture; foreach (var pass in _sceneEffect.CurrentTechniquePasses) { pass.Apply(); sceneNode.Mesh.Draw(); } } }
public Camera CreateCamera() { var camera = new Camera(_device.Viewport); _allCameras.Add(camera); _allNodes.Add(camera); return camera; }
private void UpdateLightMatrixForDirectionalLight(Camera camera, IList<DrawableElement> shadowCasters) { var directionNormalized = Vector3.Normalize(Direction); var lightViewMatrix = Matrix.CreateLookAt(Vector3.Zero, Direction, Vector3.Up); var mergedBox = new BoundingBox(); for (var i = 0; i < shadowCasters.Count; i++) { var drawableElement = shadowCasters[i]; mergedBox = BoundingBox.CreateMerged(mergedBox, drawableElement.BoundingBox); } var sphere = BoundingSphere.CreateFromBoundingBox(mergedBox); var edges = new Vector3[8]; edges[0] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Min.Y, mergedBox.Min.Z), lightViewMatrix); edges[1] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Min.Y, mergedBox.Min.Z), lightViewMatrix); edges[2] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Min.Y, mergedBox.Max.Z), lightViewMatrix); edges[3] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Min.Y, mergedBox.Max.Z), lightViewMatrix); edges[4] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Max.Y, mergedBox.Min.Z), lightViewMatrix); edges[5] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Max.Y, mergedBox.Min.Z), lightViewMatrix); edges[6] = Vector3.Transform(new Vector3(mergedBox.Min.X, mergedBox.Max.Y, mergedBox.Max.Z), lightViewMatrix); edges[7] = Vector3.Transform(new Vector3(mergedBox.Max.X, mergedBox.Max.Y, mergedBox.Max.Z), lightViewMatrix); var boundingBox = BoundingBox.CreateFromPoints(edges); var width = boundingBox.Max.X - boundingBox.Min.X; var height = boundingBox.Max.Y - boundingBox.Min.Y; var cameraPosition = sphere.Center - directionNormalized * sphere.Radius; var cameraPositionTarget = cameraPosition + directionNormalized; LightViewMatrix = Matrix.CreateLookAt(cameraPosition, cameraPositionTarget, Vector3.Up) * Matrix.CreateOrthographic(width, height, 0.1f, sphere.Radius * 2); }
public CameraEntityComponent(Entity referringEntity, Skybox skybox, int cameraMask = 1) : base(referringEntity) { Camera = GameInstance.GetService<SceneRenderer>().CreateCamera(cameraMask); NearClipDistance = 0.1f; FarClipDistance = 1000.0f; FieldOfView = MathHelper.PiOver4; ClearColor = Color.CornflowerBlue; Camera.Skybox = skybox; Camera.IsActive = ReferringEntity.IsActive; }
private void DrawSceneForCamera(Camera camera, Vector3 lightDirection, bool enableShadows) { _device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0); _sceneEffect.View = camera.ViewMatrix; _sceneEffect.Projection = camera.ProjectionMatrix; _sceneEffect.LightDirection = lightDirection; var lightView = BuildLightViewMatrix(lightDirection); DrawSolidObjects(camera, lightView, enableShadows); DrawTransparentObjects(camera); }
/// <summary> /// Calculates the Viewprojection Matrix of light to draw shadow map. This depends on Light Type. /// Directional: /// 1) Create a merged bounding box of all shadow casters. /// 2) create enclosing sphere of boundingbox from 1) to find out to position light by taking radius as distance to ensure see all shadow casters. /// 3) Transform AABB from 1) to viewspace of light and rebuild an AABB for this. this sets the size for orthogonal projection matrix. /// </summary> /// <param name="camera">needed for billboards.</param> /// <param name="shadowCasters">All Nodes casting a shadow for the scene.</param> internal void UpdateLightViewMatrixForCamera(Camera camera, IList<DrawableElement> shadowCasters) { switch (Type) { case LightType.Directional: UpdateLightMatrixForDirectionalLight(camera, shadowCasters); break; case LightType.Point: throw new NotImplementedException(); default: throw new ArgumentOutOfRangeException(); } }
public void OnOpening() { _scene = new Scene(Game, new WindowsSceneEffect(Game.Content)) { EnableShadows = false, LightDirection = new Vector3(0, -1, 0) }; _camera = _scene.CreateCamera(); _camera.Position = new Vector3(0.0f, 12.0f, 13.0f); _camera.RotateX(-MathHelper.PiOver4); var billboardSceneNode = _scene.CreateSceneNode(); billboardSceneNode.IsBillboard = true; billboardSceneNode.Mesh = new Mesh(Game.GraphicsDevice, Primitives.GenerateQuadForYBillboard()); billboardSceneNode.Material = new Material(Game.Content.Load<Texture2D>(ResourceNames.Textures.tileset1)) { CastShadow = false, UseTransparency = true }; billboardSceneNode.Position = new Vector3(-5, 0, -5); billboardSceneNode.Scale = new Vector3(2, 4, 1); for (var x = 0; x < 5; x++) { for(var z = 0; z < 5; z++) { if (x == 0 && z == 0) continue; var cloned = _scene.CloneNode(billboardSceneNode); cloned.Position = new Vector3(x*2-5, 0, z * 2-5); } } var quads = new GeometryData[32*32]; //2,1 var tsize = 1.0f / 16.0f; for(var x = 0; x < 32; x++) { for(var z = 0; z < 32; z++) { quads[z*32+x] = Primitives.GenerateQuadXZ(new Vector3(-16.0f + x, 0.0f, -16.0f + z), texCoordStart: new Vector2(tsize * 2.0f, tsize), texCoordScale: new Vector2(tsize, tsize)); } } var sceneNode = _scene.CreateSceneNode(); sceneNode.Mesh = new Mesh(Game.GraphicsDevice, Primitives.Merge(quads)); sceneNode.Material = new Material(Game.Content.Load<Texture2D>(ResourceNames.Textures.tileset1)); }
private void DrawTransparentObjects(Camera camera) { _device.BlendState = BlendState.AlphaBlend; foreach (var sceneNode in _transparentObjects) { var worldMatrix = sceneNode.GetWorldMatrix(camera); if (sceneNode.IsBillboard) { _sceneEffect.ActivateBillboardingTechnique(); } _sceneEffect.World = worldMatrix; _sceneEffect.DiffuseTexture = sceneNode.Material.DiffuseTexture; foreach (var pass in _sceneEffect.CurrentTechniquePasses) { pass.Apply(); sceneNode.Mesh.Draw(); } } }
public Player(World world) { var playerEntity = world.EntitySystem.CreateEntity(true); var collisionSize = new Vector3(0.35f, 0.6f, 0.35f); var collisionOffset = new Vector3(0.0f, 0.3f, 0.0f); var mesh = new Mesh(GameInstance.GraphicsDevice, Primitives.GenerateQuadForYBillboard()); var diffuseTexture = GameInstance.Content.Load<Texture2D>(ResourceNames.Textures.DefaultGuy); var material = new Material { DiffuseTexture = diffuseTexture, UseTransparency = true, TexcoordScale = diffuseTexture.GetTexcoordsFromPixelCoords(32, 32), IsUnlit = true }; playerEntity.AddComponent(new ModelEntityComponent(playerEntity, mesh, material, true)); playerEntity.AddComponent(new FigureMovementAnimationComponent(playerEntity, diffuseTexture)); playerEntity.AddComponent(new CollisionEntityComponent(playerEntity, collisionSize, collisionOffset, "Player", true)); playerEntity.Position = new Vector3(5, 0, 8); var cameraEntity = world.EntitySystem.CreateEntity(true); cameraEntity.SetParent(playerEntity); _controllerComponent = cameraEntity.AddComponent(new PlayerControllerComponent(cameraEntity)); var cameraComponent = cameraEntity.AddComponent(new CameraEntityComponent(cameraEntity, new Skybox(GameInstance) { Scale = 50, Texture = GameInstance.Content.Load<Texture2D>(ResourceNames.Textures.skybox_texture) })); cameraComponent.FarClipDistance = 50.0f; Camera = cameraComponent.Camera; var overlayCamera = cameraEntity.AddComponent(new CameraEntityComponent(cameraEntity, null, CameraMasks.UiOverlays)); overlayCamera.Camera.FarClipDistance = 100.0f; overlayCamera.Camera.ClearColor = null; overlayCamera.Camera.DepthClear = 1.0f; overlayCamera.Camera.DepthStencilState = DepthStencilState.Default; }
private Matrix CalculateBillboardMatrix(Camera currentCamera) { //I don't know why, but the scaling is getting negative calculating the billboard matrix. var bill = Matrix.CreateScale(-1,1,-1)* Matrix.CreateConstrainedBillboard(Position, currentCamera.Position, Vector3.UnitY, null, null); return Matrix.CreateScale(Scale) * bill; }
public Matrix GetWorldMatrix(Camera currentCamera) { return IsBillboard ? CalculateBillboardMatrix(currentCamera) : _world; }
private void DrawBoundingBox(Camera observer, Collider collider) { var scale = -collider.BoundingBox.Min + collider.BoundingBox.Max; var position = collider.BoundingBox.Min + scale*0.5f; var worldViewProjection = Matrix.CreateScale(scale)*Matrix.CreateTranslation(position)*observer.ViewMatrix* observer.ProjectionMatrix; _worldViewProjection.SetValue(worldViewProjection); _modulateColor.SetValue(collider.IsTrigger ? ColorTrigger : ColorCollider); _lineDrawEffect.CurrentTechnique.Passes[0].Apply(); _boundingBoxMesh.Draw(); }
public void Draw(Camera observer) { if (!DrawDebugShapes) return; GameInstance.GraphicsDevice.DepthStencilState = DepthStencilState.Default; GameInstance.GraphicsDevice.BlendState = BlendState.Opaque; var oldTechnique = _lineDrawEffect.CurrentTechnique; _lineDrawEffect.CurrentTechnique = _lineTechnique; lock (_lockObject) { for (var i = 0; i < _allTriggersAndColliders.Count; i++) { var collider = _allTriggersAndColliders[i]; if (!collider.IsActive) continue; switch (collider.Type) { case ColliderType.BoundingBox: DrawBoundingBox(observer, collider); break; } } } _lineDrawEffect.CurrentTechnique = oldTechnique; }