身体渲染 高光Dither效果Rim特殊状态小结
高光
前面介绍了暗面的计算方式,接下来是高光的计算效果。高光计算比较简单,采用了Blinn-Phong的光照模型,明暗计算的时候采用了lgdc的光照模型。
问题来了,高光是否可以控制呢?崩坏采用了两张遮罩图处理高光,一张是高光的遮罩图,一张是高光系数,分别存储在B,R通道。
B通道图如下:
通道值从1到0,受高光影响越来越小,为0时则完全不受高光影响。
R通道图如下:
什么??我绝对不是复制粘贴的,确实和B通道有点像,但是两个通道的意义却有本质的区别,一个是阀值,一个是系数。
代码很简单,主要是对于两张遮罩图的处理方式。实现的效果就是美术可以自己控制高光区域,并且控制高光的系数。
至此明暗和高光都已经完成处理。
擦。。居然不能上传短视频,那就看图吧,我们看下这有明暗和高光的处理。图中1,2,3,4均为高光部分,我们可以看到通过控制_小巧的海燕我们可以控制高光形状,如果不了解pow函数制造的是怎么样函数曲线,可以观看我的另一篇文章 .,我们可以看到1,2处的高光强度的对比是通过哪里控制的?答不上来从头看吧~~~通过高光遮罩我们实现比较丰富的动态变化,比如右腿膝盖外侧的色彩部分,等等。。动起来效果会比较好~
崩坏的Dither效果实现起来还是比较好理解的。效果如图:
代码处理也很简单,由于之前没玩过崩坏(。。。。确实没玩过,我的舰长就是到了获得芽衣),后来玩发现游戏里的Dither效果。。
主要是剔除,_RowAccess这个矩阵是外部传递的,我们稍微改变下矩阵就实现不一样的效果,比如这种:
有点恶心啊····密集恐惧症,改的时候居然没发现。。。当然还有很多种实现Dither的效果,只不过这种计算相对简单。。
边缘光也是卡通渲染的一大主题因素,也是很简单的计算,菲涅尔效应处理即可:
float colorRadio= _RGScale*pow(clamp((1.0 - dot(worldViewDir, worldNormal)), 0.0, 1.0), _RG小巧的海燕) + _RGBias;float Fresnel= clamp(colorRadio, 0.0, 1.0);col.xyz = lerp(shadowEndColor, colorRadio * _RGColor, Fresnel * _RGRatio);
可以看到有了边缘光的效果,这里我想说两点:1.这个边缘光并没有对明暗做单独处理,亮不部的边缘会有强烈的光源,暗部边缘的光源较弱或者为没有。2.身体使用边缘光后,大家注意看胸部的位置(。。。),相比之前的是不是变大了。。。因为计算的是法线和视角点积,所以在胸部这种地方就会有层次感了,看着很好,但是二次元表现所需要的。综合以上两点,我发现正常情况下,专注的铃铛是没有整个效果的,所以他的边缘光应该是作为某种状态的时候出现的。
参数分析:
这里的参数比较多,我们提前看下:
特殊状态主要有特殊状态问题,特殊状态CubeMap,以及噪声图组成,然后有一个过渡控制系数。其中Bloom暂时忽略,之后会有。
首先是贴图的采样,注意这里的噪声图的UV坐标,使用的是物体的局部坐标,另外这个CubeMap的采样,是这样的(不知道是不是我理解的有问题。。)
然后就是cubemap和噪声图和过渡的控制,这里用到的算法还是很有意思的,这里就不做详细的解说了,直接上代码,具体的解释可以 参考这篇.
float transitonRadio = _SPNoiseScaler * _SPTransition;//------_SPNoiseScaler*(_SPTransition*1.7-1.99*spNoiseBaseColor.x)+1float 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的地方为spcolorfloat3 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!=0spMixColor = (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还是很友好的嘛~~还给我整了几个机器人关注,不会吧不会吧,他不会真的以为我信了吧。 生而为人,我很抱歉-------网易云