概述

1. 这套方案很容易掌握,几乎可以瞬间做出大片草(适合中景);
2. 渲染时间10-30min不等,看时间成本和质量成本而定;
3. 控制方法很多,包括动态的控制,能够达到多种视觉效果;


test.image1


test.image2


backlight test.image1

我做草的思路其实比较简单:用面片。
这里有两个方法,我觉得都是值得应用的
一者是用例子替代particle instance,另一者是用插件shave & a hair cut。
两者都有很强大的控制力,如果制作者对particle不感冒,我建议用particle instance。
我这里介绍的是用shave & a hair cut控制面片,思路都是一样的,可以举一反三。
举一反三指得是方法和实现对象。
比如,方法上可以衍生倒用bonus tools里面的工具摆模型,可以用painteffect整体控制;
而实现对象可以衍生到动物羽毛等等。

下面是这次的主角shave & a hair cut。
我个人对这个插件很有感情,至于到了什么程度……
有时,hair能解算的东西,我第一时间会考虑用shave来解算。(只是玩笑)
欢迎大家加入Joe(Shave作者)的讨论组(yahoo Group)。
我个人最喜欢的shave版本是4.0v25 forMaya7.0,很稳定。


shave.image1

step1

做一个地板,铺上shave。


step1.image1

做一个面片,这个面平用来贴草的贴图,
面片稍微带一点点弧度,能使得它对光线更敏感一些。


step1.image2

把面片做为shave的instance。


step1.image3

step2

开一个新的场景制作贴在面片上的素材,做一把草。
输出3个通道:
Color/occlusion/Normal(tangent space)。

输出细节要求:
1. 尺寸根据镜头来
2. 摄像机角度和镜头中摄像机角度尽量保持一直
3. 最终草地的细节程度和风格基本上这部就能看出来了:
  输出的草越真实,最后结果也越真实;
  输出的草越风格化,最后结果也越风格化。
4. 时间和质量可以在这步得到平衡:
  输出草的规模越大,做草的面片数量可以越少,渲染速度越快,质量??(要看情况)
  反之亦然。


step2.image1

通过照片,我们发现大片草地比较扎眼的种群就1-2种,


step2.image2

这里,我再做了一组以丰富草群,这步不是必要的。


step2.image3

step3

把step2中做好的素材应用到shave instance。
shadenetwork怎么连都可以,关键有几点:
1. 透明的地方不产生高光;
2. ambient occlusion的地方不产生高光;
3. ambient occlusion的地方不受灯光影响;
4. 高光色对视觉效果有较大影响。

特别说一下4.
eg.如果想得到比较好的黄昏草地的效果,
就要仔细设置一下specular,
因为这个时候的物体故有色将被弱化,而光源色将被强化。
请参见 http://www.tgjay.com/htms/tutorial/insidetNatureLights.htm
设置使得specular color(ramp4控制),从下到上、从里到外都有一些变化。


step3.image1

Step4

这步将如何控制面片形态,
图中所示的绿色线条是shave的control guide,
粉色的面片是通过这些control guide差值得到的,
这就是shave四两拨千斤的原理。


step4.image1

shaveNode中可以控制的参数很多
但是一旦把它的hair转成instance以后
material下的参数就不起作用了
控制面片的关键参数有这么几个:
1. hair count控制面片数量(最终渲染的时候要把这个参数打上去)
2. density map控制哪里该长草 哪里不该长草
3. scale控制面片的大小(包括长和宽)
4. rand scale控制面片的随机大小
5. root thickness控制面片的宽度
6. displacement控制面平群相对于地面的整体偏移

关于其他参数的一些说明:
如果没什么特殊的需求segment和pass就定死在3和1
原因就是杀鸡不用牛刀
cut map我实在无法把它和草地制作联系在一起 所以一并打入冷宫
tip thickness在shave instance化以后就失效了


step4.image2

step4 bonus

上面说到了控制面片形态的参数,虽说不多,但讲究不少。

面片最终的长和高是怎么决定的?
高= guideLength * scale * scaleMap * (1 - randSeed)
长= guideLength * scale * scaleMap * (1 - randSeed) * thickness * thicknessMap
大家仔细琢磨一下吧,其实不复杂,如果用户想精确控制每片草的大小就得想这个事情。

大家再看step4下面那张图可以发觉scaleMap和thicknessMap是由一张noise控制的。
为什么已经有rand scale这个选项,还要用noise来控制面片的随机大小?
这要说到maya中两个命令的rand和noise(大家可以去查一下help)。
如果大家能明白rand和noise的区别,就能明白为什么已经有了rand还要加noise。
其实草原中每株草的大小不是完全随即的,这不符合生态学。正常生态中草分部应该是:
1.自然>美观;
2.大植株的植物排布不是均匀的,也不是随即的,而是三五成群 这样有利于生存;
3.小株植物会有群聚效应,就是扎堆生长;
4.大株植物周围肯定会伴有较多小植物,他们是合作关系;
5.其他小株植物会拣阳光相对多的地方生长 就是阳光能透过草地照到的地方;
6.之前说的是水平差异,还是另一封面是垂直差异,两三成群的大植株其中毕有一棵是占主导的,其他体型稍小,这样看上去高低错落有致,十分影响视觉效果。
这些只是冰山一角,如果最终的草地效果不满意(不真实),就要在生态学的方面多找原因。
这里我只是用noise很简单粗糙得控制植株的大小,大家最好用maya paint tool或者bodypaint仔细处理一下。

再来看看 displacement这个参数。
它的出现是因为shave要准确附在经displacement贴图处理后的模型上。
他的单位就是maya场景单位,
如果把displacement参数设成1表示shave的毛沿法线方向偏移一个单位。
现在大家回头去看一下step2的那些贴图,可以发觉草的根部不在图片的底端,
也就是说,这些草渲出来都是飞在空中的,只是密度一大看不出来而已。
要修正这个问题需要把displacement调整到一个恰当的负值。
另外还需要配合一张displacementMap让块头小的草偏移地小一些,块头大的草偏移地大一些。

step5

在控制好面平形态以后, 就可以控制整体的颜色了,
有一个快速讨巧的办法就是用平面投射。
我用一个noise和ramp生成一些随机的色块,
这些色块的色相和饱和度都有所不同,
通过这个方法可以很方便的做出上面 test.image1的效果


step5.image1

既然说到了投射,我想大家一定会涌现出各种好的想法,
比如,把地面的灯光信息bake下来,然后投到草上……


step5.image2

step6

颜色控制好就可以开始打灯,渲染。
这个和传统的打灯,渲染别无二致。
只是我这里选择了maya 8.0+和mentalray,
因为要用到两个特性:
1. 直接渲染tengent space normal map
2. 用detail shadow渲染投影


step6.image1

step7

草地主要有两类动态:
1. 风吹草;
2. 物体与草地碰撞。
两者分别都有一些解决方案

风吹草
我提供三个解决方案,制作者可以结合使用,也可以只用其中一个:
1. 纹理动画,就是在做step2的时候,做成动画序列;
2. 参数动画,用这个图片序列来控制shave的frizz anim;


step7.image1

3. 用一个和地面贴合的几何体与shave control guide碰撞,几何体从地面拂过。


step7.image2

物体与草地碰撞
shave instance取消template后就是polygon了。
可以用maya中所有的控制方法来控制shave,
图中polygon已经被转化成了柔体并加了cluster。
值得注意的是shave用柔体控制后,内置的firzz控制就失效了。


step7.image3

Guru Skills

shave导出mi的方法>>>
在dos下使用命令:
mayabatch -file "scene.mb" -command "shaveMayatomr -mi -file \"/path/to/scene.mi\";"
在maya中用mel导出:
shaveMayatomr -mi -file "/path/to/scene.mi";
导出的命令以我写得为准,shave manual里面得命令有一些小错误。

制作平整草地的方法>>>
首先要确保rand scale为0,
scale和root thickness无贴图控制。
然后把shave control guide专程maya curves。
用这个脚本使每更曲线的弧长保持一致:

global proc tgUniformArcLength(float $Length) {
string $curves[] = `ls -sl -l`;
string $curveInfo = `createNode curveInfo`;
for ($i=0;$i<size($curves);$i++) {
connectAttr -f ($curves[$i] + ".worldSpace[0]") ($curveInfo + ".inputCurve");
float $arcLength = `getAttr ($curveInfo + ".arcLength")`;
float $scalePivot[3] = `pointPosition -w ($curves[$i] + ".cv[0]")`;
float $scaleCoef = $Length/$arcLength;
xform -sp $scalePivot[0] $scalePivot[1] $scalePivot[2] -s $scaleCoef $scaleCoef $scaleCoef $curves[$i];
}
delete $curveInfo;
}

这个脚本是我已经写做保持汗毛长度一直的,这里正好派上用偿。
用法就是source脚本以后,选中所有curves,输入:
tgUniformArcLength(curve长度)

修正shave“刺猬bug”>>>
常用shave的人肯定没少遇到过这样的bug,
guide to curves以后curve的末端会有刺突,
我把它称为“刺猬bug”。
仔细看看还是有规律的,
所有突出的点的序列都是一样的,
把他们用scirpt挪回去,
或者偷懒一点的话,删除即可。
脚本我不提供了,很简单,大家各显神通。


guru.image1

用maya dynamic curve控制shave guide>>>
先把shave的guide转成curve,
再把curve转成dynamic curve。
在pre render mel里面输入一个脚本,好比叫tgRenderDynCurves
内容如下:

global proc tgRenderDynCurves() {
select -r shaveNode1;//需要被控制的shaveNode
select -r shaveCurveGroup1;//含有dynamic curve的组
shaveCombFromCurves;
}

 

Copyright T.G.Jay © 2004-2007. All rights reserved.