由于semantic的使用,我们有理由相信 vertex shader的output 和 pixel shader的input是按照semantic来匹配的,而跟传入顺序无关。印象dx9时代是这样。
虽然习惯上使用共用的sruct (VS_OUTPUT)来保证senamtic修改的同步,便于维护,但这个不是必须的。
但是最近工作中,在UE4的dx11上写自定义shader,因为VS和PS分开两文件,所以干脆没有用struct,而是直接写到parameter 里,但是遇到一个诡异的问题:参数的值不匹配!
最后发现是 虽然参数semantic匹配,但是参数顺序不匹配导致的。
所以查了一下文档:Shader Signatures
https://msdn.microsoft.com/en-us/library/windows/desktop/bb509650(v=vs.85).aspx
In Direct3D 10, adjacent stages effectively share a register array, where the output shader (or pipeline stage) writes data to specific locations in the register array and the input shader must read from the same locations. The API uses shader signatures to bind shader outputs with inputs without the overhead of semantic resolution
也就是说d3d10以上,为了提升性能,相邻的stage不做semantic resolution,直接按参数顺序绑定。
所以建议使用公共声明的struct。。
如果想用分开的struct (或者直接用parameter list),注意下面的是兼容的 (元素个数不同但参数顺序一致)
// Vertex Shader Output Signature Struct VSOut { float4 Pos: SV_Position; float3 MyNormal: Normal; float2 MyTex : Texcoord0; } // Pixel Shader Input Signature Struct PSInWorks { float4 Pos: SV_Position; float3 MyNormal: Normal; }
下面的不兼容 (顺序不一致)
// Vertex Shader Output Signature Struct VSOut { float4 Pos: SV_Position; float3 MyNormal: Normal; float2 MyTex : Texcoord0; } // Pixel Shader Input Signature Struct PSInFails { float3 MyNormal: Normal; float4 Pos: SV_Position; }
以上两个例子在上面的链接中有。
MSDN在这里也有简单的说明:
Direct3D 9 to Direct3D 10 Considerations (Porting Shaders: Shader Signatures and Linkage)