protected override void OnUpdate(RenderContext context) { var effectBinding = context.MaterialBinding; if (effectBinding == null) { throw new EffectBindingException("MaterialBinding not set in render context."); } // Get ambient light and number of directional lights. Vector3 ambientLight = Vector3.Zero; int numberOfDirectionalLights = 0; if (context.Scene != null && context.SceneNode != null) { // Note: XNA stock effect lights are always global. var query = context.Scene.Query <GlobalLightQuery>(context.CameraNode, context); if (query.AmbientLights.Count > 0) { var light = (AmbientLight)query.AmbientLights[0].Light; ambientLight = (Vector3)light.Color * light.Intensity; } numberOfDirectionalLights = query.DirectionalLights.Count; } // ----- Special: We have to add the ambient light to the emissive color. var diffuseBinding = effectBinding.ParameterBindings["DiffuseColor"] ?? effectBinding.EffectEx.ParameterBindings["DiffuseColor"]; var emissiveBinding = effectBinding.ParameterBindings["EmissiveColor"] ?? effectBinding.EffectEx.ParameterBindings["EmissiveColor"]; Vector4 diffuse = BasicEffectTechniqueBinding.GetColor4(diffuseBinding); Vector3 emissive = BasicEffectTechniqueBinding.GetColor3(emissiveBinding); // Premultiply emissive and add ambient lighting. (Diffuse is already premultiplied.) float alpha = diffuse.W; _effectiveEmissive.X = emissive.X * alpha + ambientLight.X * diffuse.X; _effectiveEmissive.Y = emissive.Y * alpha + ambientLight.Y * diffuse.Y; _effectiveEmissive.Z = emissive.Z * alpha + ambientLight.Z * diffuse.Z; // ----- Select shader. int shaderIndex = 0; bool fresnelEnabled = true; bool specularEnabled = true; // Check value of "FresnelFactor" parameter binding. var fresnelBinding = effectBinding.ParameterBindings["FresnelFactor"] as EffectParameterBinding <float>; if (fresnelBinding != null) { fresnelEnabled = (fresnelBinding.Value != 0); } var specularBinding = effectBinding.ParameterBindings["EnvironmentMapSpecular"] as EffectParameterBinding <Vector3>; if (specularBinding != null) { specularEnabled = (specularBinding.Value != Vector3.Zero); } if (!((IStockEffectBinding)effectBinding).FogEnabled) { shaderIndex += 1; } if (fresnelEnabled) { shaderIndex += 2; } if (specularEnabled) { shaderIndex += 4; } if (numberOfDirectionalLights <= 1) // Optimized path if there are no more than one directional lights. { shaderIndex += 8; } Id = (byte)shaderIndex; }
protected override void OnUpdate(RenderContext context) { var effectBinding = context.MaterialBinding as SkinnedEffectBinding; if (effectBinding == null) { throw new EffectBindingException("SkinnedEffectBinding not found in render context."); } // Get ambient light and number of directional lights. Vector3 ambientLight = Vector3.Zero; int numberOfDirectionalLights = 0; if (context.Scene != null && context.SceneNode != null) { // Note: XNA stock effect lights are always global. var query = context.Scene.Query <GlobalLightQuery>(context.CameraNode, context); if (query.AmbientLights.Count > 0) { var light = (AmbientLight)query.AmbientLights[0].Light; ambientLight = (Vector3)light.Color * light.Intensity; } numberOfDirectionalLights = query.DirectionalLights.Count; } // ----- Special: We have to add the ambient light to the emissive color. var diffuseBinding = effectBinding.ParameterBindings["DiffuseColor"] ?? effectBinding.EffectEx.ParameterBindings["DiffuseColor"]; var emissiveBinding = effectBinding.ParameterBindings["EmissiveColor"] ?? effectBinding.EffectEx.ParameterBindings["EmissiveColor"]; Vector4 diffuse = BasicEffectTechniqueBinding.GetColor4(diffuseBinding); Vector3 emissive = BasicEffectTechniqueBinding.GetColor3(emissiveBinding); // Premultiply emissive and add ambient lighting. (Diffuse is already premultiplied.) float alpha = diffuse.W; _effectiveEmissive.X = emissive.X * alpha + ambientLight.X * diffuse.X; _effectiveEmissive.Y = emissive.Y * alpha + ambientLight.Y * diffuse.Y; _effectiveEmissive.Z = emissive.Z * alpha + ambientLight.Z * diffuse.Z; // ----- Select shader. int shaderIndex = 0; if (!((IStockEffectBinding)effectBinding).FogEnabled) { shaderIndex += 1; } if (effectBinding.WeightsPerVertex == 2) { shaderIndex += 2; } else if (effectBinding.WeightsPerVertex == 4) { shaderIndex += 4; } if (effectBinding.PreferPerPixelLighting) { shaderIndex += 12; } else if (numberOfDirectionalLights <= 1) // Optimized path if there are no more than one directional lights. { shaderIndex += 6; } Id = (byte)shaderIndex; }