基於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

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