基于threejs开发的卡通风格着色器(二)

        上次给球体添加了卡通风格着色器之后觉得还少些什么,仔细观察网上卡通风格的游戏发现,卡通风格的3D任务往往除了明显不平滑过渡的色块以外,还都有着黑色描边,这次我们就来修改着色器实现描边的效果。

        描边特效可以通过很多方法来实现,比如:判断每个面片的朝向,当一条棱既出现在一个面片的正面又出现在反面时,说明该楞是分界线,将其涂黑即可。或者将每个点沿着法线方向延伸一定距离,相当于一个放大了的模型,然后将其涂黑,第二次正常绘制,就会出现黑边,这里面就要用到二次绘制了~最后再说我们使用的方法:计算每一个片元的法线与视线方向的夹角,当其大于阈值时将其涂黑,这样方便快捷~(只能对于平滑过渡的物体使用,当物体表面过渡不平滑时描边会很小几乎看不到)。

        这次直接贴着色器的代码,其他与上次的代码的一样,(http://blog.csdn.net/srk19960903/article/details/67645302)。主要的区别在于片元着色器这里,我们增加了浮点型一个变量dir,它的结果是视线方向映射到法线上的长度,也就是说该点越靠近边缘,距离视线方向越远,这个值也就越小(平滑物体)。当该值小于一定程度时则说明这个片元处在边缘上,就将该片元的颜色值赋值为零也就是黑色。否则按照正常的卡通着色器赋值,这样就完成了卡通风格的着色器~

<script id="fish-fragmentShader" type="x-shader/x-vertex">
uniform vec3 light;
varying vec3 vNormal;
uniform vec3 color;
void main()
{
    float diffuse = dot(normalize(light), vNormal);
    float dir = length(vNormal * vec3(0.0, 0.0, 1.0));
    if (dir < 0.5) {
    dir = 0.0;
    gl_FragColor = vec4(dir, dir, dir, 1.0);
}
else {
    if (diffuse > 0.8) {
    diffuse = 1.0;
}
else if (diffuse > 0.5) {
    diffuse = 0.6;
}
else if (diffuse > 0.2) {
    diffuse = 0.4;
}
else {
    diffuse = 0.2;
}
    gl_FragColor = vec4( color* diffuse, 1.0);
      }
}
</script>
        下面是实现后的图片,还是很有卡通的感觉~哈哈

最后github地址:https://github.com/StringKun/ThreeJSToonShader/tree/master/ThreeJSshader2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章