`
plmkome
  • 浏览: 41058 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Vision引擎中着色器界面介绍

 
阅读更多
引言
在 vForge 中编写和配置着色器是一项繁琐的工作。 不同平台要求不同的代码来完成设置顶点流等任务 此外,还必须在 vForge 中指定应给着色器绑定哪些顶点流,这些顶点流又应针对哪种 Shader Model 进行编译。
 
加上着色器排列组合系统会从一个源着色器自动生成新着色器,设置所有属性会是一项困难的工作。 因此,Vision 引擎具有一些功能,可以让配置工作更加轻松。
 
自动流蒙版设置
引擎需要了解一个着色器需要哪些顶点流,从而才能有效地仅绑定这些流。 例如,通常一个着色器会使用位置和基底纹理坐标顶点流。 因此,在 vForge 中,该着色器必须经过配置,在流蒙版中加入这些位元,如下图所示:

如果设置不正确,着色器很有可能无法按预期工作。
 
若着色器是通过排列组合系统生成的,可能某个排列组合需要特定顶点流,而另一个则不需要。 但是,如果简单地对所有排列组合启用所有可能需要的顶点流,又会对性能造成影响。
 
这一问题有个简单的解决办法,以着色器编译器可以提取的方式,将该信息植入到着色器代码中:
struct VS_IN
{
  float3 ObjPos   : V_VERTEX_STREAM_POSITION;
 
  $ifdef VMATERIAL_VERTEXCOLOR
    float4 VertColor : V_VERTEX_STREAM_COLOR;
  $endif
 
  float3 Normal : V_VERTEX_STREAM_NORMAL;
  float2 UV0 : V_VERTEX_STREAM_BASETEXCOORD;
 
  $if defined (VMATERIAL_LIGHTMAP) || defined (VMATERIAL_LIGHTMAPDOT3)
    float2 UV1 : V_VERTEX_STREAM_LIGHTMAPCOORD;
  $endif
 
  $ifdef VMATERIAL_NORMALMAP
    float3 Tangent : V_VERTEX_STREAM_TANGENT;
  $endif
};
这段代码显示了一个顶点着色器的输入结构。 每个变量的语义告诉着色器编译器此变量应绑定到哪个顶点流。 同时,编译器可以自动设置流蒙版。
 
Vision 引擎支持以下顶点着色器流语义:
 
  V_VERTEX_STREAM_POSITION(映射到 'POSITION')
  V_VERTEX_STREAM_BASETEXCOORD(映射到 'TEXCOORD0')
  V_VERTEX_STREAM_LIGHTMAPCOORD(映射到 'TEXCOORD1')
  V_VERTEX_STREAM_NORMAL(映射到 'NORMAL')
  V_VERTEX_STREAM_TANGENT(映射到 'TEXCOORD2')
  V_VERTEX_STREAM_COLOR(映射到 'COLOR0')
  V_VERTEX_STREAM_SECONDARDYCOLOR(映射到 'COLOR1')
  V_VERTEX_STREAM_BONEINDEX(包含某个顶点受哪些骨骼影响的索引,映射到 'TEXCOORD3')
  V_VERTEX_STREAM_BONEWEIGHT(包含某个顶点受每个骨骼影响的权重,映射到 'TEXCOORD4')
  V_VERTEX_STREAM_UV0(映射到 'TEXCOORD0')
  V_VERTEX_STREAM_UV1(映射到 'TEXCOORD1')
  V_VERTEX_STREAM_UV2(映射到 'TEXCOORD2')
  ……一直以此类推,直到:
 
  V_VERTEX_STREAM_UV15(映射到 'TEXCOORD15')
 
  注:其中部分语义实际上映射到同一个顶点流。 例如, V_VERTEX_STREAM_BASETEXCOORD 映射到 TEXCOORD0,V_VERTEX_STREAM_LIGHTMAPCOORD 映射到 TEXCOORD1,而 V_VERTEX_STREAM_UV0 和 V_VERTEX_STREAM_UV1 也一样。 所以,如果您确实使用通用纹理坐标语义提供额外数据,请注意不要无意中使用被其他语义映射的流。 大部分情况下,最好只使用 V_VERTEX_STREAM_UV5 和更高语义来自定义顶点流。
 
如果着色器以这些语义写成,着色器编译器会负责为其自动设置流蒙版。
   注:当某个着色器使用上述某个语义来描述顶点着色器输入流,着色器编译器会忽略 vForge 中进行的一切设置(并替换这些设置)。 两者不会合并。 因此,一个着色器或为所有输入变量使用上述语义,或者完全不用。 例如,如下设置会产生错误:
 
struct VS_IN
{
  float3 ObjPos    : V_VERTEX_STREAM_POSITION;
  float4 VertColor : V_VERTEX_STREAM_COLOR;
  float2 UV0       : TEXCOORD0;
};
当着色器编译器检测到 V_VERTEX_STREAM_xxx 语义被使用,就会忽略 vForge 中所作的一切设置。 然后,编译器将设置流蒙版。 在上例中,编译器会设置流蒙版,使其包含位置和颜色流,但会忽略纹理坐标,因为那和 V_VERTEX_STREAM_BASETEXCOORD 不同。 哪怕在 vForge 中手动启用了纹理坐标 0 的流,在编译该着色器后,该流也将被流蒙版移除。 一个着色器被编译后,可查看 vForge 中的流蒙版设置来确认移除。
 
  注:着色器编译器仅检查任何此类语义在一个着色器中是否存在(在评估着色器排列组合之后)。 但不确认其具体使用位置。 因此,在宏中使用这些语义是个坏主意,因为在宏里使用顶点流语义关键词就将启用该流,无论此宏事后是否确实被代码引用。
而且,着色器编译器会进行检查,确保这些语义没有被用在像素着色器中,因为那将产生错误。 也就是说,您必须将顶点和像素着色器分隔到不同的文件中。 如果两个源都在同一个文件中,着色器编译器会发出提示,告诉您无法在像素着色器中使用这些语义。
 
自动 Shader Model 调整
一些着色器执行多种不同功能,这些功能也许无法全部在所有平台上工作。 例如,光照着色器往往实现一个基本光照模型,可在所有 Shader Model 2.0 硬件(缩写为 SM20)上工作。 一些更高级的效果可能需要 Shader Model 3.0,添加多重采样后,一些着色器可能只能在 Shader Model 4.0 或 4.1 上工作。
 
在 vForge 中,您可以选择着色器编译所针对的 Shader Model。

  注:目前,您可以为每个着色器阶段分别指定 Shader Model,也就是说,您可以针对 SM20 编译顶点着色器、针对 SM41 编译像素着色器。 由于 DirectX 未必支持,Vision 引擎会确保所有阶段中最高版本的 Shader Model 被用来编译每个着色器。 因此,在上例中,顶点着色器也会针对 SM41 进行编译。
 
如果您的着色器为非排列组合着色器,设置是很简单的。 但当您从同一个源着色器中创建了不同的排列组合之后,设置的局限会很大,因为您只能指定源着色器的 Shader Model,该着色器生成的所有排列组合都会使用同一个 Shader Model。 也就是说,您可能不得不将源着色器设为 SM41,尽管某些排列组合其实可以在 SM40_LEVEL_91 上工作。
 
Vision 引擎有一个功能,可以为此类情况启用 Shader Model 半自动配置。 着色器代码示例:
$ifdef VMATERIAL_NORMALMAPPING
  // fetch normalmap
 
  $ifdef VMATERIAL_PARALLAXMAPPING
    V_REQUIRES_SM30
 
    // do parallax mapping
  $endif
$endif
 
$ifdef DEFERRED_MSAA
  V_REQUIRES_SM41
 
$endif
通过在着色器代码中植入特殊标记的方式,可以为特定排列组合升级 Shader Model 版本。 vForge 中的设置将作为基底 Shader Model 应用于所有排列组合。 但是,如果源着色器包含以下标记之一,其排列组合就可针对更高版本的 Shader Model 编译:
 
V_REQUIRES_SM30: DX9 最低 Shader Model: SM 3.0,DX11 最低 Shader Model: SM 4.0
V_REQUIRES_SM40: DX9:禁用,DX11: SM 4.0
V_REQUIRES_SM41: DX9:禁用,DX11: SM 4.1
V_REQUIRES_SM50: DX9:禁用,DX11: SM 5.0
DirectX 9 和主机不支持 Shader Model 4.0+,也就是说,一个包含该标记的着色器在除了 DirectX 11 以外的所有平台上都会被禁用。
 
V_REQUIRES_SM30 的运作方式略有不同。 在 DirectX 9 上,它将 Shader Model 设为SM30。 但在 DirectX 11 上,它将 Shader Model 设为 SM40,因为 SM40_LEVEL_93 实际上(在 DX11 中)不如 SM30 (在 DX9 中)强大。
 
一个标记在着色器代码中出现的频率或顺序没有意义。 是否出现两种不同标记也无关紧要。 将被采用的是要求最高的 Shader Model。
  注:生成排列组合后,Vision 引擎只搜索着色器代码中是否存在这些标记。 它会评估 HLSL 预处理器指令。 也就是说,您不能使用 #ifdef ABC \ V_REQUIRES_SMxx \ #endif 来选择性地升级 Shader Model,而只能使用排列组合系统的 $ifdef's。 但您可以为这些标记添加注释,因为在处理着色器之前,注释通常会从源代码中被去除。
 
确认自动调整
在着色器代码中插入这些标记,就表示您指示 Vision 引擎着色器编译器自动调整特定设置。 如果您给非排列组合着色器插入这些标记,就可以在着色器编译后在 vForge 中直接看到这些变化。 因此,您可以确认所作的调整是否准确。 如果您使用排列组合着色器(用于生成其他不同着色器),那些其他着色器将被添加到着色器库中,但通常不在 vForge 中显示。
 
您可以启用”Show Auto-Generated Shaders / Techniques(显示自动生成的着色器 / 技术)“来显示这些着色器。

蓝色文件夹代表非排列组合技术。 黄色文件夹代表排列组合技术。 绿色文件夹代表从黄色排列组合技术中自动生成的技术。 绿色也用来表示着色器:

因为自动生成着色器的数量有时相当多,所以只在特别要求时才会显示。
 
自动生成着色器被显示后,您可以像选择任何其他着色器那样选择它们,检查属性(流蒙版、Shader Model、目标平台等)是否都如预期。
 
  注:每当着色器库被编译,所有自动生成着色器都会从源着色器中完全重建。 因此无法对它们进行手动修改(改动将会丢失)。

转自:project anarchy中文社区

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics