一些简单的XNA/HLSL问题

11

最近我开始涉足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个回答

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这样的顶点时,该顶点包含位置和颜色,但如果您想定义一个具有两种颜色的自定义顶点,则需要一种区分两种颜色的方法...即通道。

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


它确切地分配给寄存器中的哪个样本呢?我没有指定它从哪个寄存器中获取样本,所以我猜它会默认抓取s0而不需要任何代码规范?另外,你提出了另一个问题:sampler是否与sampler2D一样有效? - inline
无论您进行什么绘制操作,请使用那些寄存器。如果您之前已经使用过SpriteBatch或基本效果来处理该纹理,则已经内在地完成了这些操作... - Blau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接