2010-04-10 56 views

回答

2

好的,基於你的代碼(here),它與ColorMatrix不太一樣(但是這應該會給你一個關於如何添加完整矩陣功能的好主意),下面是一個版本,它將會在XNA工作:

首先,下載Sprite Effects sample。這將節省我通過設置的東西。我只是要取代去飽和效應。

以下是與您自己的幾乎相同的像素着色器。這種替換 「desaturate.fx」 的內容:

sampler TextureSampler : register(s0); 

float4 colorMultiply = float4(1, 1, 1, 1); 
float4 colorAdd = float4(0, 0, 0, 0); 

float4 PixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 
{ 
    // Look up the texture color. 
    float4 tex = tex2D(TextureSampler, texCoord); 

    // Perform scaling and addition and return 
    return color * tex * colorMultiply + colorAdd; 
} 

technique ColorMatrix { pass Pass1 { PixelShader = compile ps_2_0 PixelShader(); } } 

現在更換DrawDesaturate功能與此:

(喬爾·馬丁內斯提到,在XNA 4 this code becomes much neater

void DrawDesaturate(GameTime gameTime) 
{ 
    Effect colorMulAddEffect = desaturateEffect; // reusing desaturateEffect to keep this short! 
    float pulsate = Pulsate(gameTime, 4, 0, 1); 

    spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None); 

    colorMulAddEffect.Parameters["colorMultiply"].SetValue(new Vector4(1.5f, 1f, pulsate, 1f)); 
    colorMulAddEffect.Parameters["colorAdd"].SetValue(new Vector4(-0.5f, 1-pulsate, 0f, 0f)); 
    colorMulAddEffect.Begin(); 
    colorMulAddEffect.CurrentTechnique.Passes[0].Begin(); 

    spriteBatch.Draw(glacierTexture, FullscreenRectangle(), Color.White); 

    spriteBatch.End(); 
    colorMulAddEffect.CurrentTechnique.Passes[0].End(); 
    colorMulAddEffect.End(); 
} 

現在有一個主要條件與此代碼 - 不同colorMultiply和colorAdd值,你不能批量精靈! (其實colorMultiply有點多餘,因爲你可以使用sprite的顏色作爲colorMultiply,你可以改變每個精靈)。

所以如果每個精靈都有不同的加/乘值,你必須做整個SpriteBatch.Begin,Effect.Begin,繪製東西,SpriteBatch.End,Effect.End每個精靈的東西。

這樣做的原因是,像素着色器和它的參數只能每批次as explained in this blog post設置一次。

做每批一個精靈將是緩慢的,如果你有很多的精靈!

解決這個(如果你需要那樣的表現)會做一些針對性的精靈配料,用自定義的頂點着色器,可以通過對像素着色器通過不止一種顏色。這是可能的,雖然不重要。一個好的起點是source code for the shaders used by SpriteBatch

+0

非常好 - 謝謝! – Charles 2010-06-21 20:19:37

1

您可以使用自定義像素着色器非常容易地做這種顏色操作的。例如,取像素着色器是這樣的:在XNA 4.0

sampler2D sampler; 

float4 PixShader(float2 tex : TEXCOORD0) : COLOR0 
{ 
    float4 color; 
    color = tex2D(sampler, tex); 

    //do anything you want to the colors 
    color.r = color.r * 2; // intensify the red component 
    color.g = color.g * 0.5; // cut all green values in half 
    // etc. 

    return color; 
} 

和使用自定義着色器與SpriteBatch類是哦這麼多簡單:
SpriteBatch and custom shaders in XNA Game Studio 4.0肖恩哈格里夫斯

1

這裏有一個可與Silverlight和WPF一起使用的解決方案:

sampler2D input : register(s0); 

/// <defaultValue>1.0</defaultValue> 
float RMul : register(C0); 
/// <defaultValue>1.0</defaultValue> 
float GMul : register(C1); 
/// <defaultValue>1.0</defaultValue> 
float BMul : register(C2); 
/// <defaultValue>1.0</defaultValue> 
float AMul : register(C3); 

/// <defaultValue>0</defaultValue> 
float RAdd : register(C4); 
/// <defaultValue>0</defaultValue> 
float GAdd : register(C5); 
/// <defaultValue>0</defaultValue> 
float BAdd : register(C6); 
/// <defaultValue>0</defaultValue> 
float AAdd : register(C7); 

float4 main(float2 uv : TEXCOORD) : COLOR 
{ 
    float4 color = tex2D(input, uv); 
    color = color.rgba * float4(RMul, GMul, BMul, AMul) + float4(RAdd, GAdd, BAdd, AAdd); 
    return color; 
} 

我會給第一個perso ñ調整它在XNA上工作。