public static void ApplyLightTo(Item item) { if ((item.ItemData.Flags & TileFlag.LightSource) == 0) { return; // not a light source } int itemID = item.ItemID; for (int i = 0; i < m_Entries.Length; ++i) { LightEntry entry = m_Entries[i]; int[] toMatch = entry.m_ItemIDs; bool contains = false; for (int j = 0; !contains && j < toMatch.Length; ++j) { contains = itemID == toMatch[j]; } if (contains) { item.Light = entry.m_Light; return; } } }
/// <summary> /// Select which lights can actually cast shadows /// </summary> private void SelectShadowCasters() { _lightShadowCasters.Clear(); for (int i = 0; i < _lightEntries.Count; i++) { LightEntry entry = _lightEntries[i]; if (_lightEntries[i].light.CastShadows) { //only spot and directional lights can cast shadows right now if (entry.light.LightType == Light.Type.Spot) { entry.spotShadowMap = _shadowRenderer.GetFreeSpotShadowMap(); entry.castShadows = entry.spotShadowMap != null; //if we dont have that many shadow maps, it cannot cast shadows if (entry.castShadows) { _lightShadowCasters.Add(entry); } } } //assign it back, since it's a struct _lightEntries[i] = entry; } }
private void BuildLightEntries(Camera camera) { _lightEntries.Clear(); for (int index = 0; index < _visibleLights.Count; index++) { LightEntry lightEntry = new LightEntry(); lightEntry.light = _visibleLights[index]; _lightEntries.Add(lightEntry); } }
/// <summary> /// Generate the shadow maps and matrixes for the visible lights. We should limit /// our shadow-casters based on number of available shadow maps (we could use some /// performance-related heuristic here too) /// </summary> /// <param name="camera"></param> /// <param name="meshes"></param> /// <param name="renderWorld"></param> private void GenerateShadows(Camera camera, BaseSceneGraph sceneGraph) { for (int index = 0; index < _lightShadowCasters.Count; index++) { LightEntry light = _lightShadowCasters[index]; //only spot if (light.light.LightType == Light.Type.Spot) { _shadowRenderer.GenerateShadowTextureSpotLight(this, sceneGraph, light.light, light.spotShadowMap); } } }
public void RenderShadowMaps(Camera camera) { Microsoft.Xna.Framework.Graphics.RasterizerState originalState = this.main.GraphicsDevice.RasterizerState; Microsoft.Xna.Framework.Graphics.RasterizerState reverseCullState = new Microsoft.Xna.Framework.Graphics.RasterizerState { CullMode = Microsoft.Xna.Framework.Graphics.CullMode.CullClockwiseFace }; this.main.GraphicsDevice.RasterizerState = reverseCullState; this.shadowMapIndices.Clear(); if (this.maxShadowedSpotLights > 0) { // Collect spot lights foreach (SpotLight light in SpotLight.All) { if (light.Enabled && !light.Suspended && light.Shadowed && light.Attenuation > 0.0f && camera.BoundingFrustum.Intersects(light.BoundingFrustum)) { float score = (light.Position.Value - camera.Position.Value).LengthSquared() / light.Attenuation; if (score < LightingManager.lightShadowThreshold) { this.spotLightEntries.Add(new LightEntry <SpotLight> { Light = light, Score = score }); } } } this.spotLightEntries.Sort(this.spotLightComparer); // Render spot shadow maps for (int i = 0; i < this.spotLightEntries.Count; i++) { LightEntry <SpotLight> entry = this.spotLightEntries[i]; this.shadowMapIndices[entry.Light] = i; this.RenderSpotShadowMap(entry.Light, i); if (i >= this.maxShadowedSpotLights - 1) { break; } } this.spotLightEntries.Clear(); } this.main.GraphicsDevice.RasterizerState = originalState; // Render global shadow map if (this.EnableGlobalShadowMap && this.globalShadowLight != null) { this.RenderGlobalShadowMap(camera); } }
private void SortLights(List<Light> visibleLights, Camera.Camera camera) { _lightEntries.Clear(); Vector3 camPos = camera.Transform.Translation; for (int index = 0; index < visibleLights.Count; index++) { LightEntry lightEntry = new LightEntry(); lightEntry.light = visibleLights[index]; lightEntry.sqrDistanceToCam = Math.Max(1, Vector3.Distance(lightEntry.light.Transform.Translation, camPos)); //compute a value to determine light order lightEntry.priority = 1000 * lightEntry.light.Radius / Math.Max(1, lightEntry.sqrDistanceToCam); _lightEntries.Add(lightEntry); } _lightEntries.Sort(delegate(LightEntry p1, LightEntry p2) { return (int)(p2.priority - p1.priority); }); }
void UpdateEditor() { LightEntry e = LightData.Get(mCurrentLight); lightNameTxt.Text = e.mAreaLightName; lightInterpolate.Value = Convert.ToDecimal(e.Get <int>("Interpolate")); #region Player Light playerLight0ColorR.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight0ColorR")); playerLight0ColorG.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight0ColorG")); playerLight0ColorB.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight0ColorB")); playerLight0ColorA.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight0ColorA")); playerLight0Color.BackColor = Color.FromArgb((byte)playerLight0ColorR.Value, (byte)playerLight0ColorG.Value, (byte)playerLight0ColorB.Value); playerLight1ColorR.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight1ColorR")); playerLight1ColorG.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight1ColorG")); playerLight1ColorB.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight1ColorB")); playerLight1ColorA.Value = Convert.ToDecimal(e.Get <byte>("PlayerLight1ColorA")); playerLight1Color.BackColor = Color.FromArgb((byte)playerLight1ColorR.Value, (byte)playerLight1ColorG.Value, (byte)playerLight1ColorB.Value); playerLightAmbientR.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientR")); playerLightAmbientG.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientG")); playerLightAmbientB.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientB")); playerLightAmbientA.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientA")); playerLightAmbient.BackColor = Color.FromArgb((byte)playerLightAmbientR.Value, (byte)playerLightAmbientG.Value, (byte)playerLightAmbientB.Value); playerLight0X.Value = Convert.ToDecimal(e.Get <float>("PlayerLight0PosX")); playerLight0Y.Value = Convert.ToDecimal(e.Get <float>("PlayerLight0PosY")); playerLight0Z.Value = Convert.ToDecimal(e.Get <float>("PlayerLight0PosZ")); playerLight1X.Value = Convert.ToDecimal(e.Get <float>("PlayerLight1PosX")); playerLight1Y.Value = Convert.ToDecimal(e.Get <float>("PlayerLight1PosY")); playerLight1Z.Value = Convert.ToDecimal(e.Get <float>("PlayerLight1PosZ")); playerLightAlpha2.Value = Convert.ToDecimal(e.Get <byte>("PlayerAlpha2")); playerLight0FollowCamera.Checked = e.Get <int>("PlayerLight0FollowCamera") != 0; playerLight1FollowCamera.Checked = e.Get <int>("PlayerLight1FollowCamera") != 0; #endregion #region Strong Light strongLight0ColorR.Value = Convert.ToDecimal(e.Get <byte>("StrongLight0ColorR")); strongLight0ColorG.Value = Convert.ToDecimal(e.Get <byte>("StrongLight0ColorG")); strongLight0ColorB.Value = Convert.ToDecimal(e.Get <byte>("StrongLight0ColorB")); strongLight0ColorA.Value = Convert.ToDecimal(e.Get <byte>("StrongLight0ColorA")); strongLight0Color.BackColor = Color.FromArgb((byte)strongLight0ColorR.Value, (byte)strongLight0ColorG.Value, (byte)strongLight0ColorB.Value); strongLight1ColorR.Value = Convert.ToDecimal(e.Get <byte>("StrongLight1ColorR")); strongLight1ColorG.Value = Convert.ToDecimal(e.Get <byte>("StrongLight1ColorG")); strongLight1ColorB.Value = Convert.ToDecimal(e.Get <byte>("StrongLight1ColorB")); strongLight1ColorA.Value = Convert.ToDecimal(e.Get <byte>("StrongLight1ColorA")); strongLight1Color.BackColor = Color.FromArgb((byte)strongLight1ColorR.Value, (byte)strongLight1ColorG.Value, (byte)strongLight1ColorB.Value); strongLightAmbientR.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientR")); strongLightAmbientG.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientG")); strongLightAmbientB.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientB")); strongLightAmbientA.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientA")); strongLightAmbient.BackColor = Color.FromArgb((byte)strongLightAmbientR.Value, (byte)strongLightAmbientG.Value, (byte)strongLightAmbientB.Value); strongLight0X.Value = Convert.ToDecimal(e.Get <float>("StrongLight0PosX")); strongLight0Y.Value = Convert.ToDecimal(e.Get <float>("StrongLight0PosY")); strongLight0Z.Value = Convert.ToDecimal(e.Get <float>("StrongLight0PosZ")); strongLight1X.Value = Convert.ToDecimal(e.Get <float>("StrongLight1PosX")); strongLight1Y.Value = Convert.ToDecimal(e.Get <float>("StrongLight1PosY")); strongLight1Z.Value = Convert.ToDecimal(e.Get <float>("StrongLight1PosZ")); strongLightAlpha2.Value = Convert.ToDecimal(e.Get <byte>("PlayerAlpha2")); strongLight0FollowCamera.Checked = e.Get <int>("StrongLight0FollowCamera") != 0; strongLight1FollowCamera.Checked = e.Get <int>("StrongLight1FollowCamera") != 0; #endregion #region Weak Light weakLight0ColorR.Value = Convert.ToDecimal(e.Get <byte>("WeakLight0ColorR")); weakLight0ColorG.Value = Convert.ToDecimal(e.Get <byte>("WeakLight0ColorG")); weakLight0ColorB.Value = Convert.ToDecimal(e.Get <byte>("WeakLight0ColorB")); weakLight0ColorA.Value = Convert.ToDecimal(e.Get <byte>("WeakLight0ColorA")); weakLight0Color.BackColor = Color.FromArgb((byte)weakLight0ColorR.Value, (byte)weakLight0ColorG.Value, (byte)weakLight0ColorB.Value); weakLight1ColorR.Value = Convert.ToDecimal(e.Get <byte>("WeakLight1ColorR")); weakLight1ColorG.Value = Convert.ToDecimal(e.Get <byte>("WeakLight1ColorG")); weakLight1ColorB.Value = Convert.ToDecimal(e.Get <byte>("WeakLight1ColorB")); weakLight1ColorA.Value = Convert.ToDecimal(e.Get <byte>("WeakLight1ColorA")); weakLight1Color.BackColor = Color.FromArgb((byte)weakLight1ColorR.Value, (byte)weakLight1ColorG.Value, (byte)weakLight1ColorB.Value); weakLightAmbientR.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientR")); weakLightAmbientG.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientG")); weakLightAmbientB.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientB")); weakLightAmbientA.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientA")); weakLightAmbient.BackColor = Color.FromArgb((byte)weakLightAmbientR.Value, (byte)weakLightAmbientG.Value, (byte)weakLightAmbientB.Value); weakLight0X.Value = Convert.ToDecimal(e.Get <float>("WeakLight0PosX")); weakLight0Y.Value = Convert.ToDecimal(e.Get <float>("WeakLight0PosY")); weakLight0Z.Value = Convert.ToDecimal(e.Get <float>("WeakLight0PosZ")); weakLight1X.Value = Convert.ToDecimal(e.Get <float>("WeakLight1PosX")); weakLight1Y.Value = Convert.ToDecimal(e.Get <float>("WeakLight1PosY")); weakLight1Z.Value = Convert.ToDecimal(e.Get <float>("WeakLight1PosZ")); weakLightAlpha2.Value = Convert.ToDecimal(e.Get <byte>("PlayerAlpha2")); weakLight0FollowCamera.Checked = e.Get <int>("WeakLight0FollowCamera") != 0; weakLight1FollowCamera.Checked = e.Get <int>("WeakLight1FollowCamera") != 0; #endregion #region Planet Light planetLight0ColorR.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight0ColorR")); planetLight0ColorG.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight0ColorG")); planetLight0ColorB.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight0ColorB")); planetLight0ColorA.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight0ColorA")); planetLight0Color.BackColor = Color.FromArgb((byte)planetLight0ColorR.Value, (byte)planetLight0ColorG.Value, (byte)planetLight0ColorB.Value); planetLight1ColorR.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight1ColorR")); planetLight1ColorG.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight1ColorG")); planetLight1ColorB.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight1ColorB")); planetLight1ColorA.Value = Convert.ToDecimal(e.Get <byte>("PlanetLight1ColorA")); planetLight1Color.BackColor = Color.FromArgb((byte)planetLight1ColorR.Value, (byte)planetLight1ColorG.Value, (byte)planetLight1ColorB.Value); planetLightAmbientR.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientR")); planetLightAmbientG.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientG")); planetLightAmbientB.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientB")); planetLightAmbientA.Value = Convert.ToDecimal(e.Get <byte>("PlayerAmbientA")); planetLightAmbient.BackColor = Color.FromArgb((byte)planetLightAmbientR.Value, (byte)planetLightAmbientG.Value, (byte)planetLightAmbientB.Value); planetLight0X.Value = Convert.ToDecimal(e.Get <float>("PlanetLight0PosX")); planetLight0Y.Value = Convert.ToDecimal(e.Get <float>("PlanetLight0PosY")); planetLight0Z.Value = Convert.ToDecimal(e.Get <float>("PlanetLight0PosZ")); planetLight1X.Value = Convert.ToDecimal(e.Get <float>("PlanetLight1PosX")); planetLight1Y.Value = Convert.ToDecimal(e.Get <float>("PlanetLight1PosY")); planetLight1Z.Value = Convert.ToDecimal(e.Get <float>("PlanetLight1PosZ")); planetLightAlpha2.Value = Convert.ToDecimal(e.Get <byte>("PlayerAlpha2")); planetLight0FollowCamera.Checked = e.Get <int>("PlanetLight0FollowCamera") != 0; planetLight1FollowCamera.Checked = e.Get <int>("PlanetLight1FollowCamera") != 0; #endregion }
private void RenderLights(Camera camera) { _lighting.Parameters["GBufferPixelSize"].SetValue(new Vector2(0.5f / _width, 0.5f / _height)); _lighting.Parameters["DepthBuffer"].SetValue(_depthBuffer); _lighting.Parameters["NormalBuffer"].SetValue(_normalBuffer); //just comment this line if you dont want to reconstruct the zbuffer ReconstructZBuffer(camera); _lighting.Parameters["TanAspect"].SetValue(new Vector2(camera.TanFovy * camera.Aspect, -camera.TanFovy)); for (int i = 0; i < _lightEntries.Count; i++) { LightEntry lightEntry = _lightEntries[i]; Light light = lightEntry.light; //convert light position into viewspace Vector3 viewSpaceLPos = Vector3.Transform(light.Transform.Translation, camera.EyeTransform); Vector3 viewSpaceLDir = Vector3.TransformNormal(Vector3.Normalize(light.Transform.Backward), camera.EyeTransform); _lighting.Parameters["LightPosition"].SetValue(viewSpaceLPos); _lighting.Parameters["LightDir"].SetValue(viewSpaceLDir); Vector4 lightColor = light.Color.ToVector4() * light.Intensity; lightColor.W = light.SpecularIntensity; _lighting.Parameters["LightColor"].SetValue(lightColor); float invRadiusSqr = 1.0f / (light.Radius * light.Radius); _lighting.Parameters["InvLightRadiusSqr"].SetValue(invRadiusSqr); _lighting.Parameters["FarClip"].SetValue(camera.FarClip); switch (light.LightType) { case Light.Type.Point: case Light.Type.Spot: if (light.LightType == Light.Type.Point) { //check if the light touches the near plane BoundingSphere boundingSphereExpanded = light.BoundingSphere; boundingSphereExpanded.Radius *= 1.375f; //expand it a little, because our mesh is not a perfect sphere PlaneIntersectionType planeIntersectionType; camera.Frustum.Near.Intersects(ref boundingSphereExpanded, out planeIntersectionType); if (planeIntersectionType != PlaneIntersectionType.Back) { GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; GraphicsDevice.DepthStencilState = _ccwDepthState; } else { GraphicsDevice.RasterizerState = RasterizerState.CullClockwise; GraphicsDevice.DepthStencilState = _cwDepthState; } Matrix lightMatrix = Matrix.CreateScale(light.Radius); lightMatrix.Translation = light.BoundingSphere.Center; _lighting.Parameters["WorldViewProjection"].SetValue(lightMatrix * camera.EyeProjectionTransform); _lighting.CurrentTechnique = _lighting.Techniques[1]; _lighting.CurrentTechnique.Passes[0].Apply(); _sphereRenderer.BindMesh(GraphicsDevice); _sphereRenderer.RenderMesh(GraphicsDevice); } else { //check if the light touches the far plane Plane near = camera.Frustum.Near; near.D += 3; //give some room because we dont use a perfect-fit mesh for the spot light PlaneIntersectionType planeIntersectionType = near.Intersects(light.Frustum); if (planeIntersectionType != PlaneIntersectionType.Back) { GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; GraphicsDevice.DepthStencilState = _ccwDepthState; } else { GraphicsDevice.RasterizerState = RasterizerState.CullClockwise; GraphicsDevice.DepthStencilState = _cwDepthState; } float tan = (float)Math.Tan(MathHelper.ToRadians(light.SpotAngle)); Matrix lightMatrix = Matrix.CreateScale(light.Radius * tan, light.Radius * tan, light.Radius); lightMatrix = lightMatrix * light.Transform; _lighting.Parameters["WorldViewProjection"].SetValue(lightMatrix * camera.EyeProjectionTransform); float cosSpotAngle = (float)Math.Cos(MathHelper.ToRadians(light.SpotAngle)); _lighting.Parameters["SpotAngle"].SetValue(cosSpotAngle); _lighting.Parameters["SpotExponent"].SetValue(light.SpotExponent / (1 - cosSpotAngle)); if (lightEntry.castShadows) { _lighting.CurrentTechnique = _lighting.Techniques[4]; _lighting.Parameters["MatLightViewProjSpot"].SetValue(lightEntry.spotShadowMap.LightViewProjection); _lighting.Parameters["DepthBias"].SetValue(light.ShadowDepthBias); Vector2 shadowMapPixelSize = new Vector2(0.5f / lightEntry.spotShadowMap.Texture.Width, 0.5f / lightEntry.spotShadowMap.Texture.Height); _lighting.Parameters["ShadowMapPixelSize"].SetValue(shadowMapPixelSize); _lighting.Parameters["ShadowMapSize"].SetValue(new Vector2(lightEntry.spotShadowMap.Texture.Width, lightEntry.spotShadowMap.Texture.Height)); _lighting.Parameters["ShadowMap"].SetValue(lightEntry.spotShadowMap.Texture); _lighting.Parameters["CameraTransform"].SetValue(camera.Transform); } else { _lighting.CurrentTechnique = _lighting.Techniques[3]; } _lighting.CurrentTechnique.Passes[0].Apply(); _spotRenderer.BindMesh(GraphicsDevice); _spotRenderer.RenderMesh(GraphicsDevice); } break; default: throw new ArgumentOutOfRangeException(); } } _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; }