three中的着色器示例


其實在3D引擎/庫的幫助下,我們做webgl開發的難度已經很大大地降低了,熟悉相關API的話,開發一個簡單的3D程序可以說是很輕松的事情。

在我看來,webgl的核心就是着色器(頂點着色器、片元着色器),這兩者決定了如何在屏幕上繪制出我們想要的效果。所以,無論你是剛入門的3D開發者(我也是剛剛探索3D領域)還是該領域的資深老鳥,對着色器的了解都是至關重要的。

我們一般的軟件開發(例如一些管理系統、商城小程序),諸如這些業務邏輯性非常強的程序,都是依靠CPU的高速運算,而做WebGL(3D開發),我們寫的程序代碼是要跑在GPU上的,因為對於繪圖能力來說,GPU是遠遠高於CPU的,所以,我們做的就是GPU編程了。

今天,就以一個demo來體會一下,three.js中如何編寫自定義的着色器並運用到mesh材質上的。

(首先默認大家都已經學會three.js的一些基本操作,例如將一個three.js內置的面板PlaneGeometry放到場景中)

一、添加plane

    function addplane(){
        var planeGeometry = new THREE.PlaneGeometry(300,150)
        var meshMaterial = new THREE.MeshPhongMaterial({
            color: 0xfff000 * Math.random()
        });
        var plane = new THREE.Mesh(planeGeometry,meshMaterial);
        scene.add(plane);
    }

這個函數將會往場景中添加一個Plane,效果如下:

ok,這就是一個plane了。

二、着色器代碼

<!-- 頂點着色器 -->
<script id="vertex-shader" type="x-shader/x-vertex">
void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); } </script>
<!-- 頂點着色器 -->
<script id="fragment-shader-3" type="x-shader/x-fragment">
    uniform vec2 resolution;
      uniform float scale;


    vec2 rand(vec2 pos){
        return fract( 0.00005 * (pow(pos+2.0, pos.yx + 1.0) * 22222.0));
    }
vec2 rand2(vec2 pos){
return rand(rand(pos)); } float softnoise(vec2 pos, float scale){ vec2 smplpos = pos * scale; float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x; float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x; float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x; float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x; vec2 a = fract(smplpos); return mix( mix(c0, c1, smoothstep(0.0, 1.0, a.x)), mix(c2, c3, smoothstep(0.0, 1.0, a.x)), smoothstep(0.0, 1.0, a.y)
); }
void main(void){ vec2 pos = gl_FragCoord.xy / resolution.y; pos.x += time * 0.1; float color = 0.0; float s = 1.0; for(int i = 0; i < 8; i++){ color += softnoise(pos+vec2(i)*0.02, s * 4.0) / s / 2.0; s *= 2.0; } gl_FragColor = vec4(color); } </script>

頂點着色器中,進行了一系列的矩陣變換,將圖形的頂點轉換為屏幕上的像素點;

模型矩陣: 將頂點從局部坐標系轉換到世界坐標系中;

視圖矩陣: 將頂點從世界坐標轉化到視圖坐標系下;

投影矩陣: 將頂點從視圖坐標系轉換到規范立方體中(即屏幕中);

局部坐標系(模型/物體本身)----->世界坐標系----->視圖坐標系----->屏幕。

片元着色器中,因為片元着色器是針對頂點着色器輸出的頂點數據 (gl_Position)進行逐點繪制的,所以該着色器就是對每個點賦予一個顏色值,針對上面的片元着色器,他接受外界賦予的變量(uniform類型)。

三、着色器材質

下面我們就用兩種着色器來生成一個材質。

    //創建ShaderMaterial紋理的函數
    function createMaterial(vertexShader, fragmentShader) {
        var vertShader = document.getElementById(vertexShader).innerHTML; //獲取頂點着色器的代碼
        var fragShader = document.getElementById(fragmentShader).innerHTML; //獲取片元着色器的代碼

        //配置着色器里面的attribute變量的值
        var attributes = {};
        //配置着色器里面的uniform變量的值
        var uniforms = {
            scale: {type: 'f', value: 10},
            resolution: {type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight)}
        };
        var meshMaterial = new THREE.ShaderMaterial({
            uniforms: uniforms,
            defaultAttributeValues : attributes,
            vertexShader: vertShader,
            fragmentShader: fragShader,
            transparent: true
        });
        return meshMaterial;
    }

四、利用shader材質重新繪制plane

    function addplane(){
        var planeGeometry = new THREE.PlaneGeometry(300,150)
        var meshMaterial = createMaterial("vertex-shader", "fragment-shader-3");
        var plane = new THREE.Mesh(planeGeometry,meshMaterial);
        scene.add(plane);
    }

效果:

 五、其他着色器效果示例

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM