上一篇郭先生在例子中用到了着色器变量中的uniform和varying。这篇继续结合例子将一下attribute变量,在使用过程中也发现由于three.js的版本迭代,之前的一些属性和参数已经发生了改变,ShaderMaterial也不需要传递attributes属性值,查看源码我们可以看到如果传递了attributes参数,会给出下面这样的错误。

attributes should now be defined in THREE.BufferGeometry instead.

因为我们现在想传递attributes时,几何体需要设置对应的缓冲类型,然后将使用setAttribute方法(老版本使用addAttribute方法)将属性添加到BufferGeometry的attributes中,然后我们在顶点着色器中定义使用即可。

先看看今天要完成的效果,灵感还是在iview主页上看到的。在线案例请点击博客原文

1. 制作几何体

之前的版本有这样一个方法THREE.BufferGeometryUtils.mergeBufferGeometries,它可以将几何体组合起来,并保留几何体的中心坐标,但是现在已经找不到了。建议使用merge方法。

let geometry = new THREE.Geometry();
for(let i=0; i<39; i++) { //39行
for(let j=0; j<39; j++) { //39列
let sphere = new THREE.SphereGeometry(2, 15, 10);
sphere.translate(i * 50 - 950, 0, j * 50 - 950); //这里我们使用Geometry的translate方法将间隔调成50
geometry.merge(sphere);//结合几何体
}
}
let bufferGeometry = new THREE.BufferGeometry().fromGeometry(geometry); //最后将几何体替换成对应的缓冲类型

2. 设置attributes属性

因为现在所有的球已经失去了中心坐标,如果不增加一些属性,我们很难在顶点着色器中操作这些点(因为不知道哪个点对应哪个球),因此这个时候我们就需要使用attributes属性。这里我们设置一个叫做centers的attribute属性,每一个球上面的点都对应同一个centers。

total = bufferGeometry.attributes.position.count; //几何体点的个数
every = total / 39 /39; //每个球体点的个数
centers = new Float32Array(total * 3);//初始化类型数组,并设置长度
//将中心点保存到centers中
for(let i=0; i<39; i++) {
for(let j=0; j<39; j++) {
for(let k=0; k<every; k++) {
centers[(i*39*every + j*every + k) * 3] = i * 50 - 950;
centers[(i*39*every + j*every + k) * 3 + 1] = 0;
centers[(i*39*every + j*every + k) * 3 + 2] = j * 50 - 950;
}
}
}
bufferGeometry.setAttribute('centers', new THREE.BufferAttribute(centers, 3));//为bufferGeometry设置属性

3. 设置着色器材质

这里重点就是顶点着色器,要做出水波的效果其实是两个方向正弦效果的叠加,所以设置一个centery,它是中心点的y坐标,它会随时间高低变化。有一个centery其实波浪效果就实现了,接来下还需要动态的改变球的大小。center向量是每个球中心点静止时的坐标,target是球中心点到球上一点的向量(也是球的法向量),newPosition是position沿法向量变换的点,我们回过头看一下centery,它值的范围是[-80,80],因此(centery + 80.0) / 80.0的范围是[0, 2],我们在centery最高是,让球最大,newPosition = center + target * 2。最后设置gl_Position,newPosition控制缩放,centery控制小球上下浮动。

uniforms = {
time: {
type: 'f',
value: 0
}
}
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: `
attribute vec3 centers;
uniform float time;
void main() {
float centery = sin(centers.x / 100.0 + time) * 40.0 + sin(centers.z / 100.0 + time) * 40.0;
vec3 center = vec3(centers.x, 0, centers.z);
vec3 target = position - center;
vec3 newPosition = center + target * ((centery + 80.0) / 80.0);
gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition.x, newPosition.y + centery, newPosition.z, 1.0 );
}
`,
fragmentShader: `
void main() {
gl_FragColor = vec4(0.0,0.5,0.8,1.0);
}
`
});

好了,到此为止,我们结合案例说了着色器变量uniform,varying和attribute,感觉还好的话就点咋赞吧!

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

three.js 着色器材质之变量(二)的更多相关文章

  1. three.js 着色器材质之变量(一)

    上一篇说顶点着色器和片元着色器的皮毛,这篇郭先生说一说着色器变量,通过变量可以设置材质.先看看今天要做的如下图.在线案例请点击博客原文. 在这个案例之前,我们先复习一下着色器变量 Uniforms是所 ...

  2. three.js 着色器材质之变量(三)

    这篇郭先生在练习一下着色器变量,在度娘上面或者官网上经常看到类似水波一样的效果,这篇就试着做一个这样的效果,顺便巩固一下顶点着色器和片元着色器,毕竟多多练习才能更好地掌握.效果如下图,在线案例请点击博 ...

  3. three.js 着色器材质基础(一)

    说起three.js,着色器材质总是绕不过的话题,今天郭先生就说一说什么是着色器材质.着色器材质是很需要灵感和数学知识的,可以用简短的代码和绘制出十分丰富的图像,可以说着色器材质是脱离three.js ...

  4. three.js 着色器材质内置变量

    这篇郭先生说一下three.js着色器的内置变量,分别是 gl_PointSize:在点渲染模式中,控制方形点区域渲染像素大小(注意这里是像素大小,而不是three.js单位,因此在移动相机是,所看到 ...

  5. three.js 着色器材质之纹理

    今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击博客原文. 这里我们分别引入三个纹理,分别是地球的表面纹理,对应的海拔灰度图,和云朵的纹理.使用表面纹理还 ...

  6. three.js 着色器材质之glsl内置函数

    郭先生发现在开始学习three.js着色器材质时,我们经常会无从下手,辛苦写下的着色器,也会因莫名的报错而手足无措.原因是着色器材质它涉及到另一种语言–GLSL,只有懂了这个语言,我们才能更好的写出着 ...

  7. OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)

    OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,unifo ...

  8. 通用js函数集锦<来源于网络> 【二】

    通用js函数集锦<来源于网络> [二] 1.数组方法集2.cookie方法集3.url方法集4.正则表达式方法集5.字符串方法集6.加密方法集7.日期方法集8.浏览器检测方法集9.json ...

  9. 【D3.V3.js系列教程】--(十二)坐标尺度

    [D3.V3.js系列教程]--(十二)坐标尺度 1.多种类型的缩放尺度 Quantitative Scales Linear Scales Identity Scales Power Scales ...

随机推荐

  1. java 面向对象(二十二):关键字:final

    final:最终的1.可以用来修饰:类.方法.变量 2.具体的: 2.1 final 用来修饰一个类:此类不能被其他类所继承. * 比如:String类.System类.StringBuffer类 * ...

  2. javascript基础(四): 操作表单

    表单是什么?form-----DOM树 文本框----text 下拉框----select 单选框----radio 多选框----checkbox 隐藏域----hidden 密码框----pass ...

  3. Configurate vim tool

    vim tool is a commom editor, for the sake of improving effeicient, it is necessary to configurate vi ...

  4. 理解Spring(一):Spring 与 IoC

    目录 什么是 Spring Spring 的整体架构 什么是 IoC Bean 的概念 Spring 的基本使用 Spring 的两种 IoC 容器 Spring 容器的基本工作原理 Spring B ...

  5. 转自fineui论坛:解决fineui框架开发中的Designer.aspx.cs丢失问题

    在开发的时候碰到个问题,本来好好的Edit.aspx  Edit.aspx.cs  Edit.Designer.aspx.cs编辑Edit.aspx然后保存,编译的时候 发现Edit.aspx.cs里 ...

  6. 彻底禁用咱的Win10电脑更新

    一.关闭Windows Update服务 右键“此电脑”>“管理” 找到Windows Update服务双击打开,服务状态>停止,服务类型>禁用 “恢复”选项卡,三项全部选择“无操作 ...

  7. 【揭秘】C语言类型转换时发生了什么?

    ID:技术让梦想更伟大 作者:李肖遥 链接:https://mp.weixin.qq.com/s/ZFf3imVaJgeesuhl1Kn9sQ 在C语言中,数据类型指的是用于声明不同类型的变量或函数的 ...

  8. OpenLDAP 2.4.44 安装部署避坑指南

    写在前面: 有关openLDAP的部署文档在网上随意能找到很多,但是最近用到才发现网上的教程多数是旧版的用法,例如"/etc/openldap/slapd.conf “早已弃用,更有甚者直接 ...

  9. MVC + EFCore 项目实战 - 数仓管理系统7 - 数据源管理中--新增数据源

    上篇我们完成了数据源列表展示功能(还未测试). 本篇我们来新增数据源,并查看列表展示功能.   接上篇: 二.数据源管理功能开发 2.新增数据源 我们用模态对话框来完成数据源的新增,效果如下图: 我们 ...

  10. Mybatis——@MapperScan原理

    @MapperScan配置在@Configuration注解的类上会导入MapperScannerRegistrar类. 而MapperScannerRegistrar实现了ImportBeanDef ...