zoukankan      html  css  js  c++  java
  • 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);

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

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

  • 相关阅读:
    线段树快速查找区间值
    html学习笔记
    区块链是怎么运行的
    【C++ 流类库与输入输出 】实验七
    【C++ 实验六 继承与派生】
    10天冲刺第四天后端app开发
    10天冲刺第三天后端app开发
    10天冲刺第二天之完成后端
    第二次冲刺第一天之后台管理
    第一阶段--冲刺总结
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13450691.html
Copyright © 2011-2022 走看看