一些简单的XNA / HLSL问题

时间:2011-10-01 00:53:30

标签: c# xna shader hlsl

我最近一直在进行HLSL编程,我很好奇我正在做的一些事情是如何工作的。

例如,我在这里有一个非常简单的着色器,可以将任何蓝绿色的像素变为红色。

sampler2D mySampler;

float4 MyPixelShader(float2 texCoords : TEXCOORD0): COLOR
{
    float4 Color;
    Color = tex2D(mySampler, texCoords.xy);

    if(Color.r == 0 && Color.g == 1.0 && Color.b == 1.0)
    {
        Color.r = 1.0;
        Color.g = 0.5;
        Color.b = 0.5;
    }
    return Color;
}

technique Simple
{
    pass pass1
    {
        PixelShader = compile ps_2_0 MyPixelShader();
    }
}

我知道tex2D函数在指定位置抓取像素的颜色,但我不明白的是mySampler甚至有任何数据。我根本没有设置或传入纹理,但它神奇地包含了我的纹理数据。

另外,有什么区别: COLORCOLOR0 要么 TEXCOORDTEXCOORD0

我可以采取逻辑推测,并说COLOR0是装配中的注册表,其中包含GPU中当前使用的像素颜色。 (这可能完全错了,我只是陈述我的想法)

如果是这样,那是否意味着指定像float2 texCoords : TEXCOORD0这样的东西,默认情况下,会抓住GPU正在处理的当前位置?

1 个答案:

答案 0 :(得分:7)

mySampler被命名为样本寄存器,第一个是S0。

SpriteBatch使用相同的寄存器来绘制纹理,因此您必须先确定它。

此寄存器与GraphicDevice.Textures和GraphicDevice.SamplerStates数组有关。

事实上,在你的着色器中你可以使用这句话:

 sampler TextureSampler : register(s0);

编辑:

如果你需要在着色器中使用第二个纹理,你可以这样做:

 HLSL
      sampler MaskTexture : register(s1);

 C#:
      GraphicsDevice.Textures[1] = MyMaskTexture;
      GraphicsDevice.SamplerStates[1].AddresU = TextureAddresMode....

Color0不是注册表,不保留当前像素颜色。它是指你正在使用的顶点结构。

当你定义像VertexPositionColor这样的顶点时,顶点包含一个Position和一个Color,但是如果你想用两种颜色定义一个自定义顶点,你需要一种方法来区分两种颜色...

数字后缀表示您在当前顶点中引用的通道。