使用 CgFX 着色器
 
 
 

加载 CgFX 插件

  1. 选择“窗口 > 设置/首选项 > 插件管理器(Window > Settings/Preferences > Plug-in Manager)”。

    将出现“插件管理器”(Plug-in Manager)

  2. 加载插件。

    有关“插件管理器”(Plug-in Manager)的详细信息,请参见手册的基础知识(Basics)部分中的插件管理器(Plug-in Manager)

  3. 单击“关闭”(Close)

创建“CgFX 着色器”(CgFX Shader)材质

  1. “Hypershade”中,从“Maya > 表面”(Maya > Surface)列表中选择“CgFX 着色器”(CgFX Shader)材质。

    “Hypershade”中将出现新的着色材质,并且“属性编辑器”(Attribute Editor)中将出现“CgFXShader”材质节点。

  2. “CgFX 着色器”(CgFX Shader)区域中,键入需要使用的 .cgfx 文件的路径,或浏览到 .cgfx 文件。

    一旦 .cgfx 文件连接到 CgFXShader 节点,插件会自动将属性(如果存在)加载至属性编辑器的“附加属性”区域中。

  3. 打开“附加属性”(Extra Attributes)区域,然后根据需要调整任何属性。
  4. 将新的“CgFX 着色器”(CgFX Shader)材质指定给场景中的对象。有关详细信息,请参见手册的“着色”部分中的将现有材质指定给曲面
  5. 在场景视图中,启用“硬件纹理”(Hardware Texturing)着色 > 硬件纹理(Shading > Hardware Texturing))。有关详细信息,请参见手册的“基础知识”部分中的“着色 > 硬件纹理(Shading > Hardware Texturing)”。

将放置添加到 CGFX 着色器

由于 Cgfx 是一个使用可编程着色语言的节点,因此,Cgfx 着色器不会自动支持在 Maya(place2DTexture 节点或 place3DTexture 节点)内找到的纹理放置。使用此语言意味着无法从外部设定纹理变换。相反,它必须明确编码至着色器中。如果这类参数仅次于着色器中,则自动 UI 生成功能将创建 UI 元素。然后,您应将适当的属性从纹理放置节点连接到着色器内的属性。

重新加载、编辑并查看 CgFX 文件

“cgfxShader”节点的“属性编辑器”(Attribute Editor)中,可以使用“重新加载”(Reload)“编辑”(Edit)“打开”(Open)按钮来使用指定的 FX 文件。

重新加载(Reload)

从磁盘中重新加载指定的 CgFx 文件。

编辑(Edit)

在 Windows 的 Microsoft® 记事本以及 Linux 的vi 中,打开指定的 CgFx 文件进行编辑。根据需要编辑并保存文件。Maya 将自动重新加载 CgFx 文件。

打开(Open)

在 Windows 的记事本以及 Linux 的 vi 中,以只读格式打开指定的 CgFx 文件。

纹理坐标系的方向

从 Maya 2012 起,当 CgFX 插件编译 CgFX 着色器时,它会将编译宏 MAYA_TEXCOORD_ORIENTATION_OPENGL 或 MAYA_TEXCOORD_ORIENTATION_DIRECTX 设定为 1,以指定用于纹理坐标系的方向。

将 MAYA_TEXCOORD_ORIENTATION 环境变量设定为 OPENGL 或 DIRECTX,以分别定义 MAYA_TEXCOORD_ORIENTATION_OPENGL 或 MAYA_TEXCOORD_ORIENTATION_DIRECTX 宏。定义宏之后,该宏将设定为 1。

OPENGL
指定使用 OpenGL 约定。在该约定中,纹理的原点位于纹理的左下角。
DIRECTX
指定使用 DirectX 约定。在该约定中,纹理的原点位于纹理的左上角。

对于 Maya 2011 和较低版本,上述两个宏均未定义,且着色器应采用 DirectX 纹理坐标的方向。

对于 Maya 2012,MAYA_TEXCOORD_ORIENTATION_OPENGL 宏在默认情况下已设定为 1。在启动 Maya 之前,通过将环境变量 MAYA_TEXCOORD_ORIENTATION 设定为 DirectX,可以更改默认设置。

将默认渲染器或硬件渲染器与着色器(指为先前的 Maya 版本编写、且尚未经过修改、无法支持 OPENGL 纹理坐标方向的着色器)一起使用时,将 MAYA_TEXCOORD_ORIENTATION 环境变量设定为 DirectX 十分有用。在 Maya 2012 中,将 MAYA_TEXCOORD_ORIENTATION 环境变量设定为 DirectX 时,将出现以下情况:

这将会更改 UV 坐标的生成和纹理图像的加载,如果着色器使用 UV 坐标采样纹理,则渲染的图像在两个坐标系中均相同。但是,当使用着色器以程序方式生成的 UV(相对于由 Maya 生成的、来自于 UV 源流中的 UV)对纹理进行采样时,插件必须能够控制两种约定。$(MAYA_ROOT)/presets/CgFX/example 中包含的 brix.cgfx 示例举例说明了上述运行方式:

/******************** pixel shader *********************/
#ifdef MAYA_TEXCOORD_ORIENTATION_OPENGL
     float GBalanceCorr = 1.0f - GBalance;
 #else     
     float GBalanceCorr = GBalance;
#endif
    
    float v = ((float4)tex2D(stripeSampler,float2(IN.BrickUV.x,0.5))).x;
    float4 dColor1 = lerp(SurfColor1,SurfColor2,v);
    v = ((float4)tex2D(stripeSampler,float2(IN.BrickUV.x*2,GBalanceCorr))).x;   
    dColor1 = lerp(GroutColor,dColor1,v);
    v = ((float4)tex2D(stripeSampler,float2(IN.BrickUV.x+0.25,0.5))).x;  
    float4 dColor2 = lerp(SurfColor1,SurfColor2,v);
    v = ((float4)tex2D(stripeSampler,float2((IN.BrickUV.x+0.25)*2,GBalanceCorr))).x;
    dColor2 = lerp(GroutColor,dColor2,v);
    v = ((float4)tex2D(stripeSampler,float2(IN.BrickUV.y,0.5))).x;
    float4 brix = lerp(dColor1,dColor2,v);
    v = ((float4)tex2D(stripeSampler,float2(IN.BrickUV.y*2,GBalanceCorr))).x;  
    brix = lerp(GroutColor,brix,v);
       return IN.DCol * brix;
}

CgFx 状态指定

默认渲染器、硬件渲染器和 Viewport 2.0 渲染器在 CGFX 状态指定方面存在行为差异。DepthMask 状态的默认值不同。该默认值是 CGFX 着色器未指定值时使用的值。对于不同的渲染器,默认值如下所示:

  • 默认渲染器:未指定时,采用 DepthMask = true。
  • 硬件渲染器:未指定时,采用 DepthMask = false。
  • Viewport 2.0 渲染器:未指定时,采用 DepthMask = true。

因此,如果使用硬件渲染器、但为默认渲染器和 Viewport 2.0 渲染器给定错误结果,则 CgFX 着色器可能也会正常工作。在这种情况下,将 DepthMask = false 状态指定添加到某些着色器过程可能会解决该问题。

自定义 CgFX 着色器

可以使用 MAYA_CGFX 宏来自定义 CgFX 着色器,使其包括 Maya 特定的属性注释,且不破坏与其他还有可能使用同一 CgFX 着色器的应用程序的兼容性。

例如,可以使用以下代码来声明 Maya 和其他应用程序的平行光属性,且不会造成任何兼容性问题:

#if defined(MAYA_CGFX) || defined(XSI)
// Declares the « dirlight0 » with attribute annotations for Maya or XSI
float4 dirlight0 : Direction <
     string UIName =  "Distant Light 0 Direction";
     string Object = "DirectionalLight";
     string Space = "World";
> = {-1.0f, -1.0f, 0.3f, 0.0f};
#else
// Declares the « dirlight0 » with attribute annotations for another application:
....
#endif

# if (MAYA_CGFX)|VERTBAR defined(XSI)# else 之间的行只有在 Maya/XSI 加载时才会解析。

注意

使用 Viewport 2.0 时,如果启用“渲染器 > Viewport 2.0(Renderer > Viewport 2.0)> ”下的“合并世界”(Consolidate world)选项,则依赖于局部顶点位置的 CgFx 插件可能不会按预期方式运行。

在以下示例中,check3d.cgfx 着色器将 3D 棋盘格图案应用于与该对象局部空间中的曲面位置相对的对象,因此可能会在 Viewport 2.0 中生成意外的结果。同一着色器将应用于两个球体,但在“合并世界”(Consolidate world)已启用时,如果翻滚场景或选择球体,则棋盘格图案将会移动。