Я бы сделал это с пользовательским эффектом, предложенным 'Crappy Coding Guy', для этого требуется немного данных, отправленных на эффект, код ниже - это HLSL, который вам нужно, чтобы пиксель за пикселем затухал цвет строки между Color1 и Color2. Вы можете сделать его сплошным изменением цвета, вычтя из него .5 и насытив значение, использованное для lerp, умноженное на 10.
float4x4 Projection;
float4 Color1, Color2;
float FontHeight;
float2 Location;
Texture2D FontTexture;
sampler TextureSampler = sampler_state { texture = <FontTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = clamp; AddressV = clamp;};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 Texture : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 Texture : TEXCOORD0;
float2 OriginalPosition : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
output.OriginalPosition = input.Position;
output.Texture = input.Texture;
output.Position = mul(input.Position, Projection);
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 fontColor = lerp (Color1, Color2, (1.0 / FontHeight) * (input.OriginalPosition.y - Location.y));
return tex2D(TextureSampler, input.Texture)* fontColor;
}
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
и C # для его использования. (очевидно, вам не нужно устанавливать все параметры эффекта в каждом кадре, я просто не хотел публиковать слишком много методов, если вам нужен полный пример, я буду рад выслать его вам по электронной почте)
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
fontEffect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1));
fontEffect.Parameters["Color1"].SetValue(Color.Red.ToVector4());
fontEffect.Parameters["Color2"].SetValue(Color.Blue.ToVector4());
fontEffect.Parameters["FontHeight"].SetValue(font.LineSpacing);
FieldInfo fontTexture = typeof(SpriteFont).GetField("textureValue", BindingFlags.NonPublic | BindingFlags.Instance);
fontEffect.Parameters["FontTexture"].SetValue((Texture2D)fontTexture.GetValue(font));
fontEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin( SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, fontEffect);
spriteBatch.DrawString(font, "abcdefghijklmnopqrstuvxyz", new Vector2(10, 100), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Редактировать: Вы, вероятно, заметите, что мне пришлось извлечь текстуру из шрифта спрайта, это приватное поле, которое довольно раздражает! Если кто-нибудь знает лучший способ получить это, пожалуйста, сообщите!