コード例 #1
0
    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;
    }
コード例 #2
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;
    }