2011-10-01 74 views
11

我最近一直在进入HLSL编程,我很好奇我的一些工作实际上是如何工作的。例如,这里有一个非常简单的着色器,可以将任何深青色的像素着色为红色。一些简单的XNA/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甚至有任何数据。我没有设置或传入纹理,但它神奇地包含了我的纹理数据。

而且,是什么样的事物之间的区别: COLORCOLOR0TEXCOORDTEXCOORD0

我可以把一个逻辑的猜测,说COLOR0是组装注册表保存当前使用的像素颜色在GPU中。 (这可能是完全错误的,我只是说明了我的想法)

如果是这样,那么这是否意味着指定类似float2 texCoords : TEXCOORD0的内容默认情况下会抓取GPU正在处理的当前位置?

回答

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,但是如果你想用两种颜色定义一个自定义顶点,你需要一种方法来区分两种颜色......通道。

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

+0

尽管它在哪里被分配到寄存器中的样本?我没有指定它从哪个寄存器抓取样本,所以我想它会在没有任何代码规范的情况下默认抓取s0? 另外,您还提出了另一个问题:'sampler'的工作方式与'sampler2D'相同吗? – inline

+0

无论你做什么绘制操作,使用那个寄存器,如果你在使用spritebatch或基本效果之前使用那个纹理,它本质上是做的... – Blau

+0

甜。感谢您为我清理一些东西。 :) – inline