/// <summary> /// Apply this material. /// </summary> override protected void MaterialSpecificApply(bool wasLastMaterial) { // set world matrix if (IsDirty(MaterialDirtyFlags.World)) { _effect.World = World; } // if it was last material used, stop here - no need for the following settings if (wasLastMaterial) { return; } // set all effect params if (IsDirty(MaterialDirtyFlags.TextureParams)) { _effect.Texture = Texture; } if (IsDirty(MaterialDirtyFlags.Alpha)) { _effect.Alpha = Alpha; } if (IsDirty(MaterialDirtyFlags.AmbientLight)) { _effect.AmbientLightColor = AmbientLight.ToVector3(); } if (IsDirty(MaterialDirtyFlags.EmissiveLight)) { _effect.EmissiveColor = EmissiveLight.ToVector3(); } if (IsDirty(MaterialDirtyFlags.MaterialColors)) { _effect.DiffuseColor = DiffuseColor.ToVector3(); _effect.SpecularColor = SpecularColor.ToVector3(); _effect.SpecularPower = SpecularPower; } if (_currBones != null && (IsDirty(MaterialDirtyFlags.Bones))) { _effect.SetBoneTransforms(_currBones); } }
/// <summary> /// Apply light sources on this material. /// </summary> /// <param name="lights">Array of light sources to apply.</param> /// <param name="worldMatrix">World transforms of the rendering object.</param> /// <param name="boundingSphere">Bounding sphere (after world transformation applied) of the rendering object.</param> override protected void ApplyLights(Lights.LightSource[] lights, ref Matrix worldMatrix, ref BoundingSphere boundingSphere) { // set global light params if (IsDirty(MaterialDirtyFlags.EmissiveLight)) { _effectParams["EmissiveColor"].SetValue(EmissiveLight.ToVector3()); } if (IsDirty(MaterialDirtyFlags.AmbientLight)) { _effectParams["AmbientColor"].SetValue(AmbientLight.ToVector3()); } if (IsDirty(MaterialDirtyFlags.LightSources)) { _effectParams["MaxLightIntensity"].SetValue(1.0f); } // do we need to update light sources data? bool needUpdate = false; // iterate on lights and apply only the changed ones int lightsCount = Math.Min(MaxLightsCount, lights.Length); for (int i = 0; i < lightsCount; ++i) { // only if light changed if (_lastLights[i] != lights[i] || _lastLightVersions[i] != lights[i].ParamsVersion) { // mark that an update is required needUpdate = true; // get current light var light = lights[i]; // set lights data _lightsColArr[i] = light.Color.ToVector3(); _lightsPosArr[i] = light.IsDirectionalLight ? Vector3.Normalize(light.Direction.Value) : light.Position; _lightsIntensArr[i] = light.Intensity; _lightsRangeArr[i] = light.IsInfinite ? 0f : light.Range; _lightsSpecArr[i] = light.Specular; // store light in cache so we won't copy it next time if it haven't changed _lastLights[i] = lights[i]; _lastLightVersions[i] = lights[i].ParamsVersion; } } // update active lights count if (_activeLightsCount != lightsCount) { _activeLightsCount = lightsCount; _effect.Parameters["ActiveLightsCount"].SetValue(_activeLightsCount); } // count directional lights int directionalLightsCount = 0; foreach (var light in lights) { if (!light.IsDirectionalLight) { break; } directionalLightsCount++; } // update directional lights count if (_directionalLightsCount != directionalLightsCount) { _directionalLightsCount = directionalLightsCount; var dirCount = _effect.Parameters["DirectionalLightsCount"]; if (dirCount != null) { dirCount.SetValue(_directionalLightsCount); } } // if we need to update lights, write their arrays if (needUpdate) { if (_lightsCol != null) { _lightsCol.SetValue(_lightsColArr); } if (_lightsPos != null) { _lightsPos.SetValue(_lightsPosArr); } if (_lightsIntens != null) { _lightsIntens.SetValue(_lightsIntensArr); } if (_lightsRange != null) { _lightsRange.SetValue(_lightsRangeArr); } if (_lightsSpec != null) { _lightsSpec.SetValue(_lightsSpecArr); } } }