three.js 着色器材質之變量(三)


這篇郭先生在練習一下着色器變量,在度娘上面或者官網上經常看到類似水波一樣的效果,這篇就試着做一個這樣的效果,順便鞏固一下頂點着色器和片元着色器,畢竟多多練習才能更好地掌握。效果如下圖,在線案例請點擊博客原文

這里用到了用到了頂點着色器和片元着色器。

1. 設置幾何體

設置一個幾何體,對於波浪效果,我們制作一個球幾何體(當然也可以設置其他的,可能有意想不到的效果哦!)。

var sphere = new THREE.SphereBufferGeometry(10, 120, 80);

2. 設置attribute屬性

這里我們使用一個叫做noise的attribute屬性來搞定它,同時我們在設置一個類型化數組boolArray來輔助它。

count = sphere.attributes.position.count;//頂點的數量
verticesArray = new Float32Array(count);//存放每一個點的噪聲值
boolArray = new Float32Array(count);//輔助類型數組
for(var v = 0; v < count; v++) {
    verticesArray[v] = Math.random() * 2 + 10;//隨機數[10,12)
    if(Math.random() >= 0.5) {//在創造一個隨機數,如果大於如果大於0.5,boolArray設置成10.5,boolArray設置成1。如果小於0.5,boolArray設置成-1
        boolArray[v] = 1;
    } else {
        boolArray[v] = -1;
    }
}
var bufferAttribute = new THREE.BufferAttribute(verticesArray, 1);
sphere.setAttribute('noise', bufferAttribute);

3. 設置着色器材質

var material = new THREE.ShaderMaterial({
    vertexShader: `
        attribute float noise;//着色器中定義noise屬性
        varying vec3 vNormal;//定義兩個varying屬性,用於將頂點着色器中的屬性傳到片元着色器中
        varying vec3 vPosition;
        void main() {
            vNormal = normal;
            vPosition = position;
            vec3 newPosition = position + normal * noise;//這里比較重要,頂點坐標加上球面法向量乘以噪聲,得到新的頂點坐標,新的坐標是和normal方向相同的。
            gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
        }
    `,
    fragmentShader: `
        varying vec3 vPosition;
        varying vec3 vNormal;
        void main() {
            vec3 nml = (vNormal + 1.0) / 2.0;//這個使用了頂點坐標的法向量
            vec3 cy = vec3((sin(vPosition.y * 3.0) + 1.0) / 2.0);//這個使用了頂點坐標
            gl_FragColor=vec4(cy * nml, 1.0);//將兩種效果結合起來(上面兩種顏色你們不妨可以單個試一試哦)
        }
    `
});

4. 設置動態效果

上一篇我們使用了uniform傳遞了一個time值,這次我們另辟蹊徑,在render方法中改變attribute屬性。

for(var v = 0; v < count; v++) {
    if(verticesArray[v] < 10) {//如果噪聲小於10,就將對應的boolArray變成1,然后累加
        boolArray[v] = 1;
        verticesArray[v] += 0.05;
    } else if(verticesArray[v] > 12) {//如果噪聲大於12,就將對應的boolArray變成-1,然后累減
        boolArray[v] = -1;
        verticesArray[v] -= 0.05;
    } else if(boolArray[v] == 1) {//如果boolArray等於1,就繼續累加
        verticesArray[v] += 0.05;
    } else {//如果boolArray等於-1,就繼續累減
        verticesArray[v] -= 0.05;
    }
}
var bufferAttribute = new THREE.BufferAttribute(verticesArray, 1);
//更新noise屬性值
mesh.geometry.setAttribute('noise', bufferAttribute);

這樣就做成了案例上面的效果,是不是很有意思,我們可以做各種效果,說不上有心儀的效果。

 

轉載請注明地址:郭先生的博客


免責聲明!

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



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