2012-11-27 33 views
3

我有一个640x480 rendertarget(它的主要backbuffer)。全屏四像素着色器有屏幕坐标吗?

即时传递一个全屏四边形顶点着色器,全屏四具有[-1,1]为X和Y,这意味着,我只通过坐标转换的像素着色器,没有计算坐标之间:

struct VSInput 
{ 
    float4 Position : SV_POSITION0; 
}; 

struct VSOutput 
{ 
    float4 Position : SV_POSITION0; 
}; 

VSOutput VS(VSInput input) 
{ 
    VSOutput output = (VSOutput)0; 
    output.Position = input.Position; 
    return output; 
} 

,但是,从像素着色器,所述x和y坐标的每个片段的屏幕空间(0 < X < 640和0 <ÿ< 480)。 这是为什么?我一直认为坐标将在插值到像素着色器的途中插入到-1,1之间,在这种情况下更是如此,因为我在顶点着色器上硬编码了-1和1之间的坐标。

但事实是,这个像素着色器的工作原理:

float x = input.Position.x; 

if(x < 200) 
    output.Diffuse = float4(1.0, 0.0, 0.0, 1.0); 
else if(x > 400) 
    output.Diffuse = float4(0.0, 0.0, 1.0, 1.0); 
else 
    output.Diffuse = float4(0.0, 1.0, 0.0, 1.0); 

return output; 

它输出我的呈现窗口上3周色的条纹,但如果我改变从屏幕空间(从上面的代码中的200和400)将这些值-1,1空格,并使用类似if(x < 0.5)它不会工作。

我已经尝试过

浮子X = input.Position.x/input.Position.w;

因为我读的地方,我可以得到-1,1之间的值,但它也不工作。

在此先感谢。

回答

4

从MSDN上Semantics -page约SV_POSITION:

当在像素着色器中使用,SV_Position描述了像素位置。

所以你看到了预期的行为。

最好的解决方案是将屏幕空间坐标作为附加参数传递。我喜欢用这种“全屏幕三角”顶点着色器:

struct VSQuadOut { 
    float4 position : SV_Position; 
    float2 uv: TexCoord; 
}; 

// outputs a full screen triangle with screen-space coordinates 
// input: three empty vertices 
VSQuadOut VSQuad(uint vertexID : SV_VertexID){ 
    VSQuadOut result; 
    result.uv = float2((vertexID << 1) & 2, vertexID & 2); 
    result.position = float4(result.uv * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f); 
    return result; 
} 

(原始来源:Full screen quad without vertex buffer?

+0

非常感谢,这完美地工作,并没有顶点缓冲区需要它,甚至更好。 – sap