前面介绍了暗面的计算方式,接下来是高光的计算效果。高光计算比较简单,采用了Blinn-Phong的光照模型,明暗计算的时候采用了lambert的光照模型。
问题来了,高光是否可以控制呢?崩坏采用了两张遮罩图处理高光,一张是高光的遮罩图,一张是高光系数,分别存储在B,R通道。
B通道图如下:
通道值从1到0,受高光影响越来越小,为0时则完全不受高光影响。
R通道图如下:
什么??我绝对不是复制粘贴的,确实和B通道有点像,但是两个通道的意义却有本质的区别,一个是阀值,一个是系数。
//---高光区域计算
fixed3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 worldHalfVec = normalize(worldViewDir + _WorldSpaceLightPos0.xyz);
fixed3 worldNormal = normalize(i.worldNormal);
//高光计算--
fixed spec = pow(saturate(dot(worldNormal, worldHalfVec)), _Shininess);
//计算高光遮罩--根据光照的数据进行高光计算。贴图中为1表示高光区域
spec = step(1.0f - lightTexColor.b, spec);
//lightTexColor.r定义了高光的系数。
fixed3 specularColor = _LightSpecColor * _SpecMulti *lightTexColor.r * spec;
float3 shadowEndColor = specularColor + diffuseColor;
代码很简单,主要是对于两张遮罩图的处理方式。实现的效果就是美术可以自己控制高光区域,并且控制高光的系数。
至此明暗和高光都已经完成处理。
擦。。居然不能上传短视频,那就看图吧,我们看下这有明暗和高光的处理。图中1,2,3,4均为高光部分,我们可以看到通过控制_Shininess我们可以控制高光形状,如果不了解pow函数制造的是怎么样函数曲线,可以观看我的另一篇文章 .,我们可以看到1,2处的高光强度的对比是通过哪里控制的?答不上来从头看吧~~~通过高光遮罩我们实现比较丰富的动态变化,比如右腿膝盖外侧的色彩部分,等等。。动起来效果会比较好~
崩坏的Dither效果实现起来还是比较好理解的。效果如图:
代码处理也很简单,由于之前没玩过崩坏(。。。。确实没玩过,我的舰长就是到了获得芽衣),后来玩发现游戏里的Dither效果。。
float4x4 _RowAccess = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
float2 pos = (i.screenPos.xy/ i.screenPos.w)*_ScreenParams.xy;
clip(0.9 - _RowAccess[floor(fmod(pos.x, 4))][floor(fmod(pos.y, 4))]);
主要是剔除,_RowAccess这个矩阵是外部传递的,我们稍微改变下矩阵就实现不一样的效果,比如这种:
有点恶心啊····密集恐惧症,改的时候居然没发现。。。当然还有很多种实现Dither的效果,只不过这种计算相对简单。。
边缘光也是卡通渲染的一大主题因素,也是很简单的计算,菲涅尔效应处理即可:
float colorRadio= _RGScale*pow(clamp((1.0 - dot(worldViewDir, worldNormal)), 0.0, 1.0), _RGShininess) + _RGBias;
float Fresnel= clamp(colorRadio, 0.0, 1.0);
col.xyz = lerp(shadowEndColor, colorRadio * _RGColor, Fresnel * _RGRatio);
可以看到有了边缘光的效果,这里我想说两点:1.这个边缘光并没有对明暗做单独处理,亮不部的边缘会有强烈的光源,暗部边缘的光源较弱或者为没有。2.身体使用边缘光后,大家注意看胸部的位置(。。。),相比之前的是不是变大了。。。因为计算的是法线和视角点积,所以在胸部这种地方就会有层次感了,看着很好,但是二次元表现所需要的。综合以上两点,我发现正常情况下,缇娅娜是没有整个效果的,所以他的边缘光应该是作为某种状态的时候出现的。
参数分析:
名称 | 含义 |
---|---|
_RGShininess | 控制边缘光范围 |
_RGScale | 边缘光范围系数 |
_RGBias | 边缘光偏移 |
_RGColor | 边缘光颜色 |
_RGRatio | 边缘光和默认色的比例系数 |
这里的参数比较多,我们提前看下:
特殊状态主要有特殊状态问题,特殊状态CubeMap,以及噪声图组成,然后有一个过渡控制系数。其中Bloom暂时忽略,之后会有。
首先是贴图的采样,注意这里的噪声图的UV坐标,使用的是物体的局部坐标,另外这个CubeMap的采样,是这样的(不知道是不是我理解的有问题。。)
float3 cubeMapView = normalize(worldViewDir - _WorldSpaceCameraPos.xyz);
cubeMapView = cubeMapView + spNoiseBaseColor.xyz*_SPCubeMapNoiseIntensity + _SPCubeMapOffset.xyz;
//计算反射
float3 cubeNormal= reflect(cubeMapView, i.worldNormal);
//采样CubeMap
float3 cubeMapColor = texCUBE(_SPCubeMap, cubeNormal).xyz;
然后就是cubemap和噪声图和过渡的控制,这里用到的算法还是很有意思的,这里就不做详细的解说了,直接上代码,具体的解释可以 参考这篇.
float transitonRadio = _SPNoiseScaler * _SPTransition;
//------_SPNoiseScaler*(_SPTransition*1.7-1.99*spNoiseBaseColor.x)+1
float transitonColorRadio = transitonRadio * 1.7000000 +1- spNoiseBaseColor.x *1.99*_SPNoiseScaler;
//return step(_SPNoiseScaler,spNoiseBaseColor.x) ;
//---这个*10表示只留下了之前0-0.1的部分作为过渡了
transitonColorRadio = clamp(transitonColorRadio*10,0.0, 1.0);
//---特殊颜色和过度色的差值计算--这个差值计算解析一下
//---因为噪声系数是不固定的为0-1,所以对于transitonRadio的有效值范围为[0-0.1],
//-----此时spNoiseBaseColor.x为0的地方为spcolor
float3 lerpTemp = lerp(spColor.xyz, _SPTransitionColor.xyz * _SPTransitionEmissionScaler, transitonColorRadio);
float2 tempTransitonRadio = transitonRadio * float2(1.7, 1.5) - 1.99*spNoiseBaseColor.x*_SPNoiseScaler+1;
//--非0即1,和噪声图的a通道做的比较
tempTransitonRadio = max(0, step(0, tempTransitonRadio));
//float3 spMixColor = (transitonColorRadio != 0) ? spColor.xyz : lerpTemp;
float3 spMixColor = (tempTransitonRadio.y != 0) ? spColor.xyz : lerpTemp;
float lerpBloom = lerp(_SPTransitionBloomFactor, _BloomFactor, transitonColorRadio);
//--计算颜色--tempTransitonRadio.x与第一次计算的系数相同,为1.7,而这里做的限定为x!=0
spMixColor = (tempTransitonRadio.x != 0) ? spMixColor : spColor.xyz; //spColor.xyz
//--与二分色计算出的阴影效果做叠加
spMixColor.xyz= lerp(shadowEndColor, spMixColor, _SPIntensity*tempTransitonRadio.x);
效果如图:
(图中是去除了rim的效果),特殊状态还有个扭曲的效果,等着下次吧,还没看完。
联系上之前几次讲的,第一个shader我们解析的已经接近尾声了(除了LUT部分,这个不打算进行),还差一个Bloom的效果,这个需要做后期,所以也会排的比较靠后。后期计划:接下来还有脸,头发,部分特殊效果,matcap的应用。最近看了下关于卡炫和PBR组合的方式,如下效果:
问了身边程序的同事说效果很好,美术几乎不怎么喜欢觉得有点奇怪。但是程序就是群众啊,群众喜欢的就是大众的。所以之后还是想研究下卡通渲染中加入PBR,毕竟现在的游戏没有点PBR都不好意思说效果好(也不知道为什么。。)。另外这个CSDN还是很友好的嘛~~还给我整了几个机器人关注,不会吧不会吧,他不会真的以为我信了吧。 生而为人,我很抱歉-------网易云