private static bool IsShadowing(Camera shadowCamera, Surface surface) { return surface.HasDrawProperties(DrawProperties.Shadowing) && ( surface.Boundless || shadowCamera.Contains(surface.BoundingBox) != ContainmentType.Disjoint ); }
/// <summary> /// Populate the shadowing parameters. /// </summary> /// <param name="surface">The shadow-casting surface.</param> /// <param name="surfaceWorld">The shadow-casting surface's world transform.</param> /// <param name="directionalLights">The directional lights affecting the surface.</param> public void PopulateShadowing(Surface surface, ref Matrix surfaceWorld, List<DirectionalLight> directionalLights) { XiHelper.ArgumentNullCheck(surface, directionalLights); // directional shadowing for (int i = 0; i < Constants.DirectionalShadowCount; ++i) { if (i >= directionalLights.Count) directionalShadowEnableds[i] = false; else { DirectionalLight light = directionalLights[i]; Texture2D shadowMap = light.VolatileShadowMap; Camera shadowCamera = light.ShadowCamera; Matrix shadowViewProjection; shadowCamera.GetViewProjection(out shadowViewProjection); Matrix shadowWorldViewProjection; Matrix.Multiply(ref surfaceWorld, ref shadowViewProjection, out shadowWorldViewProjection); directionalShadowEnableds[i] = light.Enabled && light.ShadowEnabled && shadowMap != null; directionalShadowPositions[i] = shadowCamera.Position; directionalShadowWorldViewProjections[i] = shadowWorldViewProjection; if (shadowMap != null) { // only directional light 0 can have a shadow due to hardware limitations if (i == 0) SetDirectionalShadow0(light.VolatileShadowMap); } } } DirectionalShadowDepthBias = Constants.DirectionalShadowDepthBias; SetDirectionalShadowEnableds(directionalShadowEnableds); SetDirectionalShadowPositions(directionalShadowPositions); SetDirectionalShadowWorldViewProjections(directionalShadowWorldViewProjections); }
/// <summary> /// Populate the lighting parameters of a BasicEffect. /// </summary> /// <param name="effect">The effect.</param> /// <param name="surface">The lit surface.</param> /// <param name="ambientLights">The ambient lights affecting the lit material.</param> /// <param name="directionalLights">The directional lights affecting the lit material.</param> /// <param name="pointLights">The point lights affecting the lit material.</param> public static void PopulateLighting( this BasicEffect effect, Surface surface, List<AmbientLight> ambientLights, List<DirectionalLight> directionalLights, List<PointLight> pointLights) { XiHelper.ArgumentNullCheck(surface, ambientLights, directionalLights, pointLights, effect); // lighting enabled effect.LightingEnabled = surface.LightingEnabled; // per-pixel lighting effect.PreferPerPixelLighting = true; // MAGICVALUE // material effect.DiffuseColor = surface.DiffuseColor.ToVector3(); effect.SpecularColor = surface.SpecularColor.ToVector3(); effect.SpecularPower = surface.SpecularPower; // ambient lighting Vector3 ambientLightColor = Vector3.Zero; foreach (AmbientLight ambientLight in ambientLights) if (ambientLight.Enabled) ambientLightColor += ambientLight.Color.ToVector3(); effect.AmbientLightColor = ambientLightColor; // directional lights for (int i = 0; i < Constants.DirectionalLightCount; ++i) { BasicDirectionalLight effectLight; switch (i) { case 0: effectLight = effect.DirectionalLight0; break; case 1: effectLight = effect.DirectionalLight1; break; case 2: effectLight = effect.DirectionalLight2; break; default: continue; } if (i >= directionalLights.Count) effectLight.Enabled = false; else { DirectionalLight directionalLight = directionalLights[i]; effectLight.Enabled = directionalLight.Enabled; effectLight.DiffuseColor = directionalLight.DiffuseColor.ToVector3(); effectLight.SpecularColor = directionalLight.SpecularColor.ToVector3(); effectLight.Direction = directionalLight.Direction; } } // point lights emulated as directional lights Vector3 surfaceCenter = surface.BoundingBox.GetCenter(); pointLights.DistanceSort(surfaceCenter, SpatialSortOrder.NearToFar); for (int i = 0; i < Constants.PointLightCount; ++i) { BasicDirectionalLight effectLight; switch (i + directionalLights.Count) { case 0: effectLight = effect.DirectionalLight0; break; case 1: effectLight = effect.DirectionalLight1; break; case 2: effectLight = effect.DirectionalLight2; break; default: continue; } if (i >= pointLights.Count) effectLight.Enabled = false; else { PointLight pointLight = pointLights[i]; effectLight.Enabled = pointLight.Enabled; effectLight.DiffuseColor = pointLight.DiffuseColor.ToVector3(); effectLight.SpecularColor = pointLight.SpecularColor.ToVector3(); effectLight.Direction = Vector3.Normalize(surface.BoundingBox.GetCenter() - pointLight.Position); } } }
/// <summary> /// Populate the lighting parameters for normal drawing. /// </summary> /// <param name="surface">The lit surface.</param> /// <param name="ambientLights">The ambient lights affecting the lit material.</param> /// <param name="directionalLights">The directional lights affecting the lit material.</param> /// <param name="pointLights">The point lights affecting the lit material.</param> public void PopulateLighting( Surface surface, List<AmbientLight> ambientLights, List<DirectionalLight> directionalLights, List<PointLight> pointLights) { XiHelper.ArgumentNullCheck(surface, ambientLights, directionalLights, pointLights); // lighting enabled LightingEnabled = surface.LightingEnabled; // material DiffuseColor = surface.DiffuseColor.ToVector4(); SpecularColor = surface.SpecularColor.ToVector3(); SpecularPower = surface.SpecularPower; // ambient lighting bool ambientLightEnabled = false; Vector3 ambientLightColor = Vector3.Zero; foreach (AmbientLight ambientLight in ambientLights) { if (ambientLight.Enabled) { ambientLightColor += ambientLight.Color.ToVector3(); ambientLightEnabled = true; } } this.AmbientLightEnabled = ambientLightEnabled; this.AmbientLightColor = ambientLightColor; // directional lights for (int i = 0; i < Constants.DirectionalLightCount; ++i) { if (i >= directionalLights.Count) directionalLightEnableds[i] = false; else { DirectionalLight directionalLight = directionalLights[i]; directionalLightDirections[i] = directionalLight.Direction; directionalLightEnableds[i] = directionalLight.Enabled; directionalLightDiffuseColors[i] = directionalLight.DiffuseColor.ToVector3(); directionalLightSpecularColors[i] = directionalLight.SpecularColor.ToVector3(); } } SetDirectionalLightEnableds(directionalLightEnableds); SetDirectionalLightDirections(directionalLightDirections); SetDirectionalLightDiffuseColors(directionalLightDiffuseColors); SetDirectionalLightSpecularColors(directionalLightSpecularColors); // point lights Vector3 surfaceCenter = surface.BoundingBox.GetCenter(); pointLights.DistanceSort(surfaceCenter, SpatialSortOrder.NearToFar); for (int i = 0; i < Constants.PointLightCount; ++i) { if (i >= pointLights.Count) pointLightEnableds[i] = false; else { PointLight pointLight = pointLights[i]; pointLightPositions[i] = pointLight.Position; pointLightEnableds[i] = pointLight.Enabled; pointLightDiffuseColors[i] = pointLight.DiffuseColor.ToVector3(); pointLightSpecularColors[i] = pointLight.SpecularColor.ToVector3(); pointLightRanges[i] = pointLight.Range; pointLightFalloffs[i] = pointLight.Falloff; } } SetPointLightEnableds(pointLightEnableds); SetPointLightPositions(pointLightPositions); SetPointLightDiffuseColors(pointLightDiffuseColors); SetPointLightSpecularColors(pointLightSpecularColors); SetPointLightRanges(pointLightRanges); SetPointLightFalloffs(pointLightFalloffs); }