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);

这样就做成了案例上面的效果,是不是很有意思,我们可以做各种效果,说不上有心仪的效果。

 

转载请注明地址:郭先生的博客

posted @ 2020-08-07 09:21  郭先生的博客  阅读(734)  评论(0编辑  收藏  举报