MAYA的材质体系是非常优秀的,它把程序的逻辑思想直接体现在高效的操作中。在MAYA中编辑材质其实很象在编写一段程序。这是有别于MAX的方法。
所以MAYA独特的思考方法令人难以理解。
掌握MAYA的材质系统不仅仅是创造完美的shader,Maya是一个将感性和理性完美融合的动画软件,如果熟练地掌握了Maya材质编辑系统独特的工作方式,会令我们在材质的设计能力上获得巨大的技术突破。
因为Maya的“Utilities”工具的能力非凡,并且要想灵活使用这些工具需要较强的逻辑能力,所以我试图把MAYA的Utilities用我自己的理解解释一下。
Maya自带的Help文件非常系统和完善,是最好的学习资料。因此这里的文字和帮助内容重复是不可避免的。
但我担心我没有大段的时间来做这种工作,虎头蛇尾的话,朋友们不要埋怨。
另:在接触三维动画软件的渲染系统时,很容易碰到“Shader”这个术语。目前国内对这个术语的翻译有很多种,比如:阴影、材质、明暗生成器等等,我自己更倾向于“明暗生成器”这种译法。
常规工具节点:
Array Mapper
Array Mapper节点一般是嵌入在粒子系统中用的,粒子通过Array Mapper节点调用Maya的Texture。
Bump Utilities
有两种方法在一个表面上创建Bump(凹凸)效果。
应用一个Bump贴图,从而在表面产生凹凸感觉。
使用置换(Displacement)贴图建立凹凸感,置换贴图是真实地移动物体表面的几何结构。
这两种方法各有利弊。Bump贴图渲染效率更高,但物体表面边缘实现不了凹凸效果,还有一点是Bump贴图只能创建轻微的凹凸效果,不能实现极凹凸的感觉。
置换(Displacement)贴图实际上是移动物体表面的几何特性,所以是效果最真实的方法,但应用这种方法的物体的UV段数必须足够多,所以这种方法的计算量非常大,最后渲染成品的时候比Bump贴图要慢很多。
Bump 2d 和Bump 3d的公共属性
Bump Filter和Bump Offset是用来改善Bump贴图的细节。如果着色后的图像中凹凸区域有明显的锯齿和闪烁,可以通过调节Bump Filter或者Bump Offset的值来改善。Bump Filter的缺省情况下值为1,当其大于1的时候,凹凸的渲染趋向于平滑;小于1的时候,凹凸的渲染效果趋向于尖锐。
Bump Offset的缺省值为0,把它理解为在Bump Filter效果的基础上相对地放大更通俗一些。缺省情况下,把Bump Offset的值增加很小的一部分就能起到很大的模糊作用。要想精确地看到Bump Offset效果,可以把Bump Filter的值设为0,然后增大Bump Offset的值。
Bump Depth控制凹凸效果的程度。
使用Bump贴图的方法:
建立一个Bump 2d 或者Bump 3d节点,在Connection Editor中将Bump 2d或者Bump 3d节点的OutNormal连接到材质(比如:Blinn)的NormalCamera上。
将Texture的OutAlpha连接到Bump节点的BumpValue上。
Bump 2d
Bump 2d节点用来转换一个2D Texture在表面上产生凹凸效果。用前面提过的方法可以很轻易地做出凹凸效果来。
有必要提的是,如果材质上要有混合两种以上的2D texture的凹凸效果时,如何来实现这种材质外观?Maya4.0的Help里讲述了方法。这里用一个样例简单介绍一下。
1、建立两个2D Texture,一个是Cloth,一个是Fractal;
2、建立两个Bump 2d节点和一个Blinn材质;
3、将Cloth1的outAlpha连接到Bump 2d1的bumpValue上,并将Bump 2d1的outNormal连接到Blinn1的normalCamera上。
4、同样,将Fractal1的outAlpha连接到Bump 2d2的bump Value性上,并将bump 2d2的outNormal连接到bump 2d1的normalCamera上。
5、把Blinn1指定给所需要的物体对象。
还有一个问题就是:如果同时指定了Bump贴图和环境贴图(Environment Texture)到物体后,你会发现由环境贴图生成的反射会不真实。原因是Bump贴图的信息没有传递到环境贴图上。有两种方法来解决:一是用鼠标拖放操作将Bump贴图的outNormal属性连接到环境贴图的normalCamera属性上;二是利用Maya提供的一个MEL命令来实现,在命令行中输入以下命令:
cnctBumpProjNormal shader-name
其中shader-name是材质的名称。
Bump 2d节点还有两个参数是Adjust Edges和Provide3d Info。
Adjust Edges用来改善边界效果。缺省情况下,在两个相接地并指定了Bump贴图的表面之间的接缝处渲染后会有一些杂乱,打开Adjust Edges选项后可以解决这个问题。
如果在一个材质网络中,凹凸效果由一个2D Texture和一个3D Texture嵌套生成,那么应该打开Provide3d Info选项,这样,3D Texture的效果才能实现。
Bump 3d
Bump 3d节点的使用方法和Bump 2d节点基本一样,所不同的是Bump 3d节点是用来转换一个3D Texture在表面上产生凹凸效果。
Condition
Condition节点的原理可以按以下形式写出:
If ( A operation B )
Outcolor = Color1
else
Outcolor = Color2
Condition节点输出的颜色值是根据预定的条件产生的。Condition节点通过比较A值与B值来发现A值是否大于、小于、等于、不等于、大于等于或小于等于B值,如果条件为真,则Outcolor输出Color1;否则,Outcolor输出Color2。
如果懂一点编程的常识,就不难理解Condition节点的原理。
Condition节点总是和其它节点结合使用,它可以使Shader网络在一种情况下用一种形式工作,而在另一种情况下用另一种形式工作。
Condition节点的这种智能性的可以自动判断的工作方式极具灵活性,在设计材质时非常有价值。
Light Info
Light Info节点在某种角度上说,其功能有点儿象Sampler Info节点。Sampler Info节点提供物体表面的信息,而Light Info节点提供场景中灯光的信息。
Light Info节点需要嵌套在其它节点中起作用,主要提供灯光的位置、方向和距离等灯光信息。
下面的一个简单样例可以感性地理解一下Light Info节点的作用:
1、建立一个Nurbs Plane并进行缩放操作使其与Maya透视视图中缺省的Grid差不多大小;
2、建立一个Spot Light并调整位置和角度:
3、选择Spot Light,按Ctra+A叫出属性编辑器,在Light Effects部分,单击Intensity Curve旁边的Create按纽。则Maya创建了一个强度曲线节点,并把它连接到Intensity上。
4、选择Spot Light,在Hypershade中显示出上、下游节点,可以看到刚才的操作创建了两个节点,一个是Light Info节点,一个是IntensityCurve节点。Maya的这个功能允许用户使用强度曲线来创建自定义的亮度衰减。
5、在Hypershade中选择spotLightShape1节点,打开Graph Editor,可以看到方才创建的强度曲线。在这里,可以自由地编辑灯光的强度。为了容易理解和简化操作,删除中间的所有编辑点,只保留首尾两个编辑点。
6、这里X轴为取样距离,Y轴为灯光的强度。将末尾的编辑点Y轴的值设为1,开始的编辑点Y轴的值设为2。利用Maya的IPR渲染场景,以便在改变强度的数值时,可以在渲染视图中实时地看到调节后的效果。
这个节点网络的连接情况是这样:
spotLightShape1.worldMatrix[0]输出到Light Info.worldMatrix;
Light Info.sampleDistance输出到IntensityCurve.input;
IntensityCurve.output输出到spotLightShape1.intensity。
Multiply Divide
Multiply Divide(乘除)节点有三部分——两个Input属性和一个Operation(操作)选项。Operation选项给Input1和Input2提供Multiply(乘)、Divide(除)或者Power(幂)的运算规则,然后通过Output将运算的结果输出。
不同的运算规则产生的结果可以用以下的公式解释:
Multiply
OutputX = Input1X *Iinput2X
OutputY = Input1Y * Input2Y
OutputZ = Input1Z * Input2Z
Divide
OutputX = Input1X /Iinput2X
OutputY = Input1Y / Input2Y
OutputZ = Input1Z / Input2Z
Power
OutputX = Input1X Iinput2X
OutputY = Input1Y Input2Y
OutputZ = Input1Z Input2Z
需要注意的是Multiply Divide节点不能进行矢量运算,如果需要进行矢量运算,应该用的是Vector Product节点。
Plus Minus Average
Plus Minus Average节点顾名思义,是对Input属性列中进行Plus(加)、Minus(减)和Average(平均值)运算。Plus Minus Average节点有一些区别于其它工具节点的特性。
首先,它可以输入多个连接;
其次,Plus Minus Average节点的Input1D、Input2D和Input3D部分的输入值必须分别是相对应的一个值、两个值和三个值。比方说,要把“Stucco”的Outcolor输入到Plus Minus Average节点中,应该连接到Plus Minus Average节点的Input3D中,而不是Input1D和Input2D。因为“Stucco”的Outcolor包括Outcolor R、OutcolorG和OutcolorB三个值。
Projection
Projection节点应用频率很高,通常是用来把2D Texture投影到3D表面上。这个节点原理比较容易理解,和其它三维软件的同类功能相近,很容易掌握,这里不过多解释。
Stencil
Stencil节点可以用来创建诸如酒瓶上的标签这样的效果。因为Stencil节点的Mask(遮罩)能非常有效地控制表面纹理哪一部分是透明的。值得一提的事Stencil节点甚至还能对表面纹理根据进行抠像。Stencil节点有它自己独特的合成材质的作用。
Reverse
在某些情况下,可能需要将材质或纹理的效果反转,Reverse节点可以提供这种能力。Reverse节点的原理可以用如下公式表示:
Output = 1 - Input
用实际例子似乎更能提高兴趣。
现在来制作一个卡通材质来理解MAYA的材质系统的能力。这个材质是在国外网站上下载的,好象有人写过类似的教程。我理清了一下思路。
首先,建立以下几个节点:
一个Blinn材质(不要带Shading Group);
一个Surface Shader节点(带Shading Group);
一个Ramp节点(不要带Placement);
一个SampleInfo节点;
一个Clamp节点;
一个Condition节点。
我们用Blinn控制场景物体上的高光区域。将Blinn的Color设置为灰度。
场景对象的颜色用Ramp的颜色队列(我是指Ramp上的颜色标签)来实现。Blinn将通过后面要讲到的方法将它的灰度值重新映射到Ramp的Color中,以达到控制Ramp的强度的目的。
SampleInfo是用来实现卡通材质的“勾边儿”效果的。
将Blinn的OutColor连接到Clamp的Input属性中。
Clamp节点的作用是将某个值控制在一定的范围内。
在这里是准备将最后的强度值减到不大于1。在实际渲染结果中,有些高光区域也许会过于“白”了,为了事先准备好,这里设置一个Clamp节点,可以去掉多余的强度。
将Clamp的MAX文字框中的R值设为1,就是最左边的那个。
Clamp节点属性面板中的Min、Max和Input的文字框从左到右分别代表R、G、B。因为单独一个通道就可以表现强度值,所以这里不妨选择R,选择别的也可以。MinR的值为0,
MaxR的值为1。
这样,Blinn Color的颜色强度(注意现在为灰度)被Clamp控制在0——1之间。
连接Clamp的OutputR到Ramp的Vcoord属性中,确认Ramp的模式为VType Ramp。这样,Ramp的颜色强度可以用Blinn Color的灰度控制在0——1之间,前面说的映射就是指这个。
将Ramp OutColor连接到Condition节点的Color1中。
同样,将SampleInfo的Facing Ration连接到Condition的First Term中。
Sampler Info节点也是不容易理解的节点,然而,Sampler Info节点的作用在Maya的材质编辑中极为重要,经常会用到。Sampler Info节点必须与其它节点嵌套才能发挥作用。
Sampler Info节点主要的功用是提供物体表面上任意一点的各种空间信息,如位置、方向和相切特性等等。
需要指出的是,Sampler Info节点返回的信息是针对于“相机空间坐标”进行定位的。在Maya中,存在“相机空间坐标”和“世界空间坐标”两种概念。“世界空间坐标”和“世界空间坐标”的关系可以这样理解:
假设你就是MAYA场景中的物体,有一个操作MAYA的人在显示器外面看着你。“相机空间坐标”的Z轴方向和“世界空间坐标”的Z轴方向相反。
Facing Ratio的值受场景物体朝向相机的表面的法线和相机目光方向之间角度的影响。
值在0——1之间。
如果物体表面上的某个位置的法线同相机的目光方向的角度为90度,刚Facing Ratio=0;
如果角度为0,则Facing Ratio=1。
在Surface Shader中增加以下四个自定义属性。
Thickness:最小值为0,最大值为1,默认值为0.3;
Line R
Line G
Line B
皆为Float 、Scalar属性。
将Thickness属性连接到Conditionr 的Secong Term中;
其余的三个依次连接到Color2的R、G、B通道中。
设置Condition的Operation为Greater Than。
Thickness控制最后渲染效果的“勾边儿”厚度。其余三个属性分别控制“勾边儿”的颜色。
最后连接Condition的OutColor到Surface Shader的OutColor中。
这个Surface Shader材质网络即为我们需要的卡通材质。
讲一下材质的实现原理:
在Condition中,
如果First Term(就是SampleInfo的Facing Ratio)>Second Term(自定义的Thickness);
则输出Color1(就是Ramp的颜色);
否则,输出Color2(由LineR、LineG、LineB实现,这里我们用黑色)
而Thickness的值可以随意更改,这样,就能控制“勾边儿”的厚度。
卡通材质的颜色同Ramp来决定,卡通上色效果中不同颜色区域之间的过渡是“硬边儿”。
所以要把Ramp的Interpolation设置为None。
Blinn也可以给一个Bump Map看看是什么效果,也可以换一个别的材质。
Ramp的设置如图:
材质的连接方式如图:
我用《MAYA从入门到精通》里的小狗渲染了一下。效果如图:
有朋友建议我用实例来解释各个节点的作用,这样更好理解。
实际上也是这个道理,只是机械地看参数,看完了也不知道怎么用。
所以以后的教程我都用实例来讲解MAYA的材质节点。MAYA的有些节点如果用语言来描述它的作用的话是非常麻烦的,远不如简单地操作几步来得直接。
我准备的实例有些是从国外的网站下载的,有些是自己制作的,原则是根据内容需要来选用。所以有的内容可能会看着“眼熟”。
这一节探讨BlendColor节点和surfaceLuminance节点。
两个节点从字面意义上都很好理解。
BlendColor节点是以Blender参数为条件,然后混合它的Color1和Color2输出。
surfaceLuminance节点顾名思义,作用是解决表面受光的问题。它可以控制表面的饱和度、对比等等。
首先在MAYA中生成一个简单的NurbsPlane,然后指定一个Lambert Shader,再指定一个file贴图。这里我用了Luis的一幅幻想画的局部。
在NurbsPlane前面用一个pointLight提供照明。
将pointLight的Intensity设置为3,渲染一下。
我们看到渲染效果“曝光”过度了。如图:
这是经常会碰到的情况,想要提高场景的照明,但离光源近的地方又会出现图中的问题
现在来解决这个问题。
建立一个BlendColor节点;
建立一个surfaceLuminance节点。
连接情况是这样的:
surfaceLuminance.OutValue输出到BlendColor.Blender;
BlendColor.Output输出到file.ColorGain。
并调整BlendColor节点的Color1和Color2的颜色如图:
调节一下BlendColor节点的颜色值,可以看到不同的效果。
当然也可以将BlendColor.Output输出到别的参数里。
常规工具节点(续)
Set Range
Set Range节点将一段范围内的值,重新映射到另一段范围内,然后输出。
注意它和Clamp节点的区别,Clamp节点是专门针对颜色值的。
举一个MAYA帮助中的小例子可以理解Set Range节点的作用。
建立一个nurbsSphere,然后指定一个Blinn材质。
生成一个Set Range节点。
我们下面要做的是用nurbsSphere的X、Y、Z轴向的旋转来控制Blinn的ColorR、ColorG、ColorB。
换句话说,是将0——360这一范围的值,重新映射到0——1这一范围内。
打开Connection Editor,
将nurbsSphere的RotateX、RotateY、RotateZ、分别连接到Set Range节点的ValueX、ValueY、ValueZ上。
把Set Range.OutValue输出到Blinn.Color上。然后设置Set Range节点的各项值如图:
现在说明一下Set Range节点的各项参数:
Min和Max的值是我们所希望得到的,在这个例子里是Min=0,Max=1;
而Old Min和Old Max代表原来范围的值,在这里是Old Min=0,Old Max=360。
Value可以理解为输入值的接口。
Set Range节点的工作原理可以由如下公式来解释:
OutValue = Min + (((Value-OldMin)/(OldMax-OldMin)) * (Max-Min))
现在,我们旋转nurbsSphere,它的颜色就会根据旋转的方向和角度变化。