引言
在 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、目标平台等)是否都如预期。
注:每当着色器库被编译,所有自动生成着色器都会从源着色器中完全重建。 因此无法对它们进行手动修改(改动将会丢失)。
|
- 浏览: 41058 次
- 性别:
- 来自: 杭州
相关推荐
中文 µVision3 IDE用户指南 本用户指南描述了µVision3 IDE/Debugger,包含如下内容: 1.µVision3 综述 描述了µVision3 IDE及集成的调试器的主要...12.命令行调用介绍了如何从命令行或批文件中调用µVision3功能。
NI Vision Assistant中文入门教程,是学习NI Vision Assistant的好帮手
NI Vision Assistant中文入门教程,原帖地址(http://www.gsdzone.net/index.php/Home/Index/Index/index/cat_id/2841771288/t/3/id/805),现转为高清PDF版。
LabVIEW--中文Vision各模块说明 LabVIEW--中文Vision各模块说明
KEIL C51 Vision2 中文入门教程!!!!!!!!!!!!!!!!
详细介绍NI Vision Assistant软件安装,功能介绍的一本很好教程!
NI Vision Assistant中文入门教程(带书签)
OpenGL-Vision OpenGL-Vision OpenGL-Vision
GigE Vision 是一种通信接口标准,可用于各种网络拓扑上的视觉软件与视频流设备间的交互。...本说明中,设备指的是一个GigE Vision兼容的可控设备,而应用程序指运行在一台主机上的一个与GigE Vision兼容的控制程序。
NI Vision Assistant助手的基本函数介绍以及使用,有例子演示,适合想入门NI视觉的同学。
NIVISION头文件,做机器视觉的朋友可以参考下,添加到所需的工程文件中
影像介绍,关于在处理视觉上,有很大的帮助,功能很强大。
MATLAB 中Computer vision system toolbox的官网指南和用户手册
vision doc, you can download it Vision引擎文档机器人
usb3 vision spec usb3 vision spec usb3 vision spec usb3 vision spec usb3 vision spec
海康(VisionMaster定位方案)
VisionMaster FT雷达界面操作指南
ViT的全文翻译,结构同原文保持一致。 1.全文翻译的markdown原文件 2.全文翻译的PDF 3..ViT的原文 4.知识点总结的博客http://t.csdn.cn/PLzkf 逐字逐句翻译Vision in Transformer
在NI Vision Builder AI中使用RS232进行通讯,程序接收到外部发送的RS232命令后进行一次触发拍照处理。