简单了解three.js 着色器材质


Posted in Javascript onAugust 03, 2020

说起three.js,着色器材质总是绕不过的话题,今天郭先生就说一说什么是着色器材质。着色器材质是很需要灵感和数学知识的,可以用简短的代码和绘制出十分丰富的图像,可以说着色器材质是脱离three.js的另一块知识,因此它十分难讲,我们只能在一个一个案例中逐渐掌握着色器语言的使用技巧。

1. 什么是着色器材质

着色器材质(ShaderMaterial)是一个用GLSL编写的小程序 ,在GPU上运行。它能够提供 materials 之外的效果,也可以将许多对象组合成单个Geometry或BufferGeometry以提高性能。

2. 着色器材质的变量

每个着色器材质都可以指定两种不同类型的shaders,他们是顶点着色器和片元着色器(Vertex shaders and fragment shaders)。

  • 顶点着色器首先运行; 它接收attributes, 计算/操纵每个单独顶点的位置,并将其他数据(varyings)传递给片元着色器。
  • 片元(或像素)着色器后运行; 它设置渲染到屏幕的每个单独的“片元”(像素)的颜色。

shader中有三种类型的变量: uniforms, attributes, 和 varyings

  • Uniforms是所有顶点都具有相同的值的变量。 比如灯光,雾,和阴影贴图就是被储存在uniforms中的数据。 uniforms可以通过顶点着色器和片元着色器来访问。
  • Attributes 与每个顶点关联的变量。例如,顶点位置,法线和顶点颜色都是存储在attributes中的数据。attributes 只 可以在顶点着色器中访问。
  • Varyings 是从顶点着色器传递到片元着色器的变量。对于每一个片元,每一个varying的值将是相邻顶点值的平滑插值。

注意:在shader 内部,uniforms和attributes就像常量;你只能使用JavaScript代码通过缓冲区来修改它们的值。

3. 着色器材质的使用

上面说了每个着色器材质都可以指定两种不同类型的shaders,不过如果我们不去指定这两个shaders而直接使用也不会报错,因为ShaderMaterial已经定义了默认的顶点着色器和片元着色器,他们的代码是这样的。

//顶点着色器代码
void main() {
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
//片元着色器代码
void main() {
  gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}

这里的projectionMatrix、modelViewMatrix和position都是three为我们设置好的变量,可以直接拿来用,前两个变量我们之前已经说了,而position就是每一个顶点的坐标值,当着色器代码执行时,会循环执行gl_Position和gl_FragColor设置顶点位置,和颜色插值。并且我们最终要设置的就是gl_Position和gl_FragColor。多的先不说,下面看一个小例子。

var geom = new THREE.SphereGeometry(10, 30, 20);
var mate = new THREE.ShaderMaterial({
  vertexShader: `
  varying vec3 vNormal;
  void main() {
        //将attributes的normal通过varying赋值给了向量vNormal
    vNormal = normal;
        //projectionMatrix是投影变换矩阵 modelViewMatrix是相机坐标系的变换矩阵 最后我们将y值乘以1.4得到了一个形如鸡蛋的几何体
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position.x, position.y * 1.4, position.z, 1.0 );
  }
  `,
  fragmentShader: `
    //片元着色器同样需要定义varying vec3 vNormal;
  varying vec3 vNormal;
  void main() {
        //vNormal是一个已经归一化的三维向量
    float pr = (vNormal.x + 1.0) / 2.0; //pr红色通道值范围为0~1
    float pg = (vNormal.y + 1.0) / 2.0; //pg绿色通道值范围为0~1
    float pb = (vNormal.z + 1.0) / 2.0; //pb蓝色通道值范围为0~1
    gl_FragColor=vec4(pr, pg, pb, 1.0); //最后设置顶点颜色,点与点之间会自动插值
  }
  `
})
var mesh = new THREE.Mesh(geom, mate);
scene.add(mesh)

简单了解three.js 着色器材质

这篇我们简单的操作顶点着色器和片元着色器绘制了一个五彩的鸡蛋,但是这还仅仅是一个静态的着色器,下一篇我们让着色器材质动起来。

以上就是简单了解three.js 着色器材质的详细内容,更多关于three.js 着色器材质的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
jquery实现表格奇数偶数行不同样式(有图为证及实现代码)
Jan 23 Javascript
判断复选框是否被选中的两种方法
Jun 04 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
Mar 10 Javascript
基于jquery实现瀑布流布局
Jun 28 Javascript
JavaScript常用函数工具集:lao-utils
Mar 01 Javascript
浅析js的模块化编写 require.js
Dec 07 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
bootstrap动态添加面包屑(breadcrumb)及其响应事件的方法
May 25 Javascript
JS作用域链详解
Jun 26 Javascript
vue-resource调用promise取数据方式详解
Jul 21 Javascript
webpack+vue-cil中proxyTable处理跨域的方法
Jul 20 Javascript
vue实现倒计时功能
Mar 24 Vue.js
Element InputNumber 计数器的实现示例
Aug 03 #Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
Aug 03 #Javascript
Vue 根据条件判断van-tab的显示方式
Aug 03 #Javascript
在vue中使用el-tab-pane v-show/v-if无效的解决
Aug 03 #Javascript
Vue解决echart在element的tab切换时显示不正确问题
Aug 03 #Javascript
js实现点击上传图片并设为模糊背景
Aug 02 #Javascript
jQuery实现雪花飘落效果
Aug 02 #jQuery
You might like
php实现SAE上使用storage上传与下载文件的方法
2015/06/29 PHP
PHP文件操作之获取目录下文件与计算相对路径的方法
2016/01/08 PHP
既简单又安全的PHP验证码 附调用方法
2016/06/02 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
2018/06/11 PHP
Laravel框架学习笔记之批量更新数据功能
2019/05/30 PHP
PHP查找一列有序数组是否包含某值的方法
2020/02/07 PHP
JavaScript Event学习第六章 事件的访问
2010/02/07 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
javascript中字符串拼接详解
2014/09/26 Javascript
javascript用函数实现对象的方法
2015/05/14 Javascript
jquery实现顶部向右伸缩的导航区域代码
2015/09/02 Javascript
vue2 自定义动态组件所遇到的问题
2017/06/08 Javascript
vue.js实现条件渲染的实例代码
2017/06/22 Javascript
vue+iview写个弹框的示例代码
2017/12/05 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
vue+express+jwt持久化登录的方法
2019/06/14 Javascript
Vue.js计算机属性computed和methods方法详解
2019/10/12 Javascript
js实现旋转的星空效果
2019/11/01 Javascript
基于JavaScript实现控制下拉列表
2020/05/08 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
使用原生javascript开发计算器实例代码
2021/02/21 Javascript
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
Python中字典创建、遍历、添加等实用操作技巧合集
2015/06/02 Python
Python连接mysql数据库的正确姿势
2016/02/03 Python
Python 类与元类的深度挖掘 II【经验】
2016/05/06 Python
django模板结构优化的方法
2019/02/28 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
Python3读写ini配置文件的示例
2020/11/06 Python
阿里健康官方海外旗舰店:阿里健康国际自营
2017/11/24 全球购物
荷兰DOD药房中文官网:DeOnlineDrogist
2020/12/27 全球购物
创业者是否需要商业计划书?
2014/02/07 职场文书
2014大学生全国两会学习心得体会
2014/03/13 职场文书
民主生活会批评与自我批评总结
2014/10/17 职场文书
小学四年级作文之人物作文
2019/11/06 职场文书
Win7/8.1用户可以免费升级到Windows 11系统吗?
2021/11/21 数码科技
vue实现列表拖拽排序的示例代码
2022/04/08 Vue.js