为什么HLSL有语义?

gma*_*man 13 glsl hlsl

在HLSL中,我必须使用语义将信息从顶点着色器传递到片段着色器.在GLSL中,不需要语义.语义的客观利益是什么?

示例:GLSL

顶点着色器

varying vec4 foo
varying vec4 bar;

void main() {
  ...
  foo = ...
  bar = ...
}
Run Code Online (Sandbox Code Playgroud)

片段着色器

varying vec4 foo
varying vec4 bar;

void main() {
  gl_FragColor = foo * bar;
}
Run Code Online (Sandbox Code Playgroud)

示例:HLSL

顶点着色器

struct VS_OUTPUT
{
   float4  foo : TEXCOORD3;
   float4  bar : COLOR2;
}

VS_OUTPUT whatever()
{
  VS_OUTPUT out;

  out.foo = ...
  out.bar = ...

  return out;
}
Run Code Online (Sandbox Code Playgroud)

像素着色器

void main(float4 foo : TEXCOORD3,
          float4 bar : COLOR2) : COLOR
{
    return foo * bar;
}
Run Code Online (Sandbox Code Playgroud)

我看到如何foo以及bar在片段着色器中VS_OUTPUT连接到foobarmain.我没有得到的是为什么我手动选择语义来携带数据.为什么像GLSL一样,DirectX只能找出放置数据的位置并在连接着色器时连接它?

是否有一些更具体的优势来手动指定语义,还是只是从汇编语言着色器时代遗留下来?选择说TEXCOORD4而不是COLOR2或BINORMAL1有一些速度优势吗?

我认为语义可以暗示意义,没有任何意义foo或者bar它们也可以模糊意义只要foo不是TEXCOORD并且bar不是颜色就好了.我们没有将语义放在C#或C++或JavaScript变量上,为什么HLSL需要它们呢?

cat*_*ier 13

简单地说,(旧)glsl使用这种变量来命名变量(请注意,现在已经弃用了变量).

语义的一个明显好处是,您不需要在各阶段之间使用相同的变量名称,因此DirectX管道通过语义而不是变量名称进行匹配,并且只要您具有兼容的布局,就会重新排列数据.

如果您通过foo2重命名foo,则需要在可能的所有着色器(以及最终的着色器)中替换此名称.使用语义,您不需要这个.

此外,由于您不需要精确匹配,因此可以更轻松地分离着色器阶段.

例如:

你可以有一个像这样的顶点着色器:

struct vsInput
{
float4 PosO : POSITION;
float3 Norm: NORMAL;
float4 TexCd : TEXCOORD0;
};

struct vsOut
{
float4 PosWVP : SV_POSITION;
float4 TexCd : TEXCOORD0;
float3 NormView : NORMAL;
};

vsOut VS(vsInput input)
{ 
     //Do you processing here
}
Run Code Online (Sandbox Code Playgroud)

像这样的像素着色器:

struct psInput
{
    float4 PosWVP: SV_POSITION;
    float4 TexCd: TEXCOORD0;
};
Run Code Online (Sandbox Code Playgroud)

由于顶点着色器输出提供了像素着色器所需的所有输入,因此这是完全有效的.法线将被忽略,不会提供给像素着色器.

但是,您可以交换到可能需要法线的新像素着色器,而无需另外使用Vertex Shader.您也可以仅交换PixelShader,从而节省一些API调用(Separate Shader Objects扩展是OpenGL的等价物).

因此,在某些方面,语义为您提供了一种在阶段之间封装输入/输出的方法,并且由于您引用了其他语言,这将等同于使用属性/设置器/指针地址...

速度方面根据命名没有区别(你可以用你想要的任何方式命名语义,当然除了系统之外).不同的布局位置确实意味着一个打击(管道将为您重新组织,但也会发出警告,至少在DirectX中).

OpenGL还提供了大致相同的布局限定符(它在技术上有点不同,但遵循或多或少相同的概念).

希望有所帮助.