//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <inheritdoc/> public void Reset() { ReferenceNode = null; _referencePosition = null; DirectionalLights.Clear(); AmbientLights.Clear(); PointLights.Clear(); Spotlights.Clear(); ProjectorLights.Clear(); ImageBasedLights.Clear(); OtherLights.Clear(); }
private void AddNode(LightNode lightNode) { Debug.Assert(lightNode.ActualIsEnabled, "Scene query contains disabled nodes."); // Ignore light if the reference position is not in the clip geometry. if (lightNode.Clip != null && _referencePosition.HasValue) { bool haveContact = HaveContact(lightNode.Clip, _referencePosition.Value); if (lightNode.InvertClip == haveContact) { return; } } // ----- Sort by estimated light contribution. // All lights except IBL will be sorted by contribution. // Note: If we have no reference node, it still makes sense to sort the objects // by their contribution. We choose to get the light contribution at the position // of each light. Vector3F position = _referencePosition ?? lightNode.PoseWorld.Position; //lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); // Or simpler: Sort light nodes by distance. --> Use for image-based lights. // (We use distance², because it is faster.) //float distance = (position - lightNode.PoseWorld.Position).LengthSquared; //lightNode.SortTag = -distance; // minus because we use descending sort. if (lightNode.Light is AmbientLight) { AmbientLights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } else if (lightNode.Light is DirectionalLight) { DirectionalLights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } else if (lightNode.Light is PointLight) { PointLights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } else if (lightNode.Light is Spotlight) { Spotlights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } else if (lightNode.Light is ProjectorLight) { ProjectorLights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } else if (lightNode.Light is ImageBasedLight) { ImageBasedLights.Add(lightNode); float distance = (position - lightNode.PoseWorld.Position).LengthSquared; lightNode.SortTag = -distance; // minus because we use descending sort. } else { OtherLights.Add(lightNode); lightNode.SortTag = lightNode.GetLightContribution(position, 0.7f); } }
public void Set(SceneNode referenceNode, IList <SceneNode> nodes, RenderContext context) { Reset(); ReferenceNode = referenceNode; // We use the origin of the reference node as the reference position for determining // the light contribution. Alternatively we could use the closest point in/on model AABB, // but this requires valid AABBs, is more expensive, etc. if (referenceNode != null) { _referencePosition = referenceNode.PoseWorld.Position; } int numberOfNodes = nodes.Count; #if DEBUG for (int i = 0; i < numberOfNodes; i++) { Debug.Assert(nodes[i].ActualIsEnabled, "Scene query contains disabled nodes."); } #endif if (context.LodCameraNode == null) { // ----- No LOD for (int i = 0; i < numberOfNodes; i++) { var lightNode = nodes[i] as LightNode; if (lightNode != null) { AddNode(lightNode); } } } else { // ----- LOD // Get values for LOD computations. var cameraNode = context.LodCameraNode; _cameraPosition = cameraNode.PoseLocal.Position; _lodBiasOverYScale = 1 / Math.Abs(cameraNode.Camera.Projection.ToMatrix44F().M11) * cameraNode.LodBias * context.LodBias; // Add nodes and evaluate LOD groups. for (int i = 0; i < numberOfNodes; i++) { AddNodeWithLod(nodes[i], context); } } // Sort lights. if (referenceNode != null) { AmbientLights.Sort(DescendingLightNodeComparer.Instance); DirectionalLights.Sort(DescendingLightNodeComparer.Instance); PointLights.Sort(DescendingLightNodeComparer.Instance); Spotlights.Sort(DescendingLightNodeComparer.Instance); ProjectorLights.Sort(DescendingLightNodeComparer.Instance); ImageBasedLights.Sort(DescendingLightNodeComparer.Instance); OtherLights.Sort(DescendingLightNodeComparer.Instance); } }