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; }
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; }