您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 毒游小行家 于 2021-4-14 13:42 编辑
卡通风格树叶渲染方案
文/雪羽
序言:一直觉得原神的树看起不错,就研究了下制作方案。最初尝试从dxbc逆向原神的Shader,花费半天时间后放弃,还不如自己随便写个Shader来得快,于是我就随便写了个树叶渲染的Shader。 先上个效果,随意调了2种颜色。由于Shader中完全未用到Vertex Color,因此还可以使用Vertex Color制作一些额外的自定义效果,如渐变幅度更大的彩色,树叶的摇动等。
模型制作:
使用SpeedTree即可。模型的树叶法线需要特殊处理成球形或半球形,有3种方案。 - 手动修改所有树叶顶点的法线。
- 在Maya内使用球形传递法线至树叶。
- 将所有树叶模型合并为一个Mesh,轴心修改至所有树叶的中心,在Shader中使用Object Space下的Vertex Position作为法线。
贴图:
唯一需要的RGB通道贴图
R:树叶纹理 G:用处未知 B:BlueClip
Shader:
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
//将贴图纹理色彩曲线texColor.r翻转至[-1,0],并偏移回[0,1],用于抵消纹理强度。
half texColorReverse = 1 - texColor.r;
//用_TexIntensity控制贴图纹理强度,_TexIntensity为0时完全无纹理,为1时纹理完全显示。
half3 color = saturate(texColorReverse - texColorReverse * _TexIntensity + texColor.r) * _Color.rgb;
//用lambert控制色彩渐变,_ColorLambertFactor控制lambert影响强度
half colorLambert = input.lambert * _ColorLambertFactor + 1 - _ColorLambertFactor;
color *= colorLambert * 1.5;
color.rgb = MixFog(color.rgb, input.fogCoord);
//将colorLambert分为4段或任意段数,再次计算使树叶颜色跟随光照出现层次感。
float BandedNL = floor(colorLambert * BandedStep) / BandedStep;
color.rgb *= 1.5 * input.lambert * BandedNL * _ShadowColor;
float shadowAttenuation = MainLightRealtimeShadow(shadowCoord);
color.rgb *= lerp(1, shadowAttenuation, _ShadowIntensity);
最后增加深度边缘光[1],并用菲涅尔公式进行Mask,BlueClip之后完成。 //增加深度边缘光DepthRim,并用菲涅尔公式进行Mask,消除中间部分不必要的DepthRim。
DepthRim = smoothstep(_RimMaskValue, 1, fresnel) * DepthRim;
clip(texColor.b - _ClipValue);
注意:由于树叶模型为插片,Depth Pass时必须【Cull Off】,否则会由于叶片背面无深度,出现大面积边缘光。
|