示例#1
0
        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;
        }