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

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

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

  • 相关阅读:
    WHERE col1=val1 AND col2=val2;index exists on col1 and col2, the appropriate rows can be fetched directly
    MySQL 交集 实现方法
    MBProgressHUD的使用
    Xcode4 使用 Organizer 分析 Crash logs(转)
    SimpleXML 使用详细例子
    PHP的XML Parser(转)
    iPhone,iPhone4,iPad程序启动画面的总结 (转)
    Pop3得到的Email 信件格式介绍
    yii总结
    隐藏Tabbar的一些方法
  • 原文地址:https://www.cnblogs.com/vadim-web/p/13450691.html
Copyright © 2011-2022 走看看