three.js 着色器材质之变量(一)
上一篇说顶点着色器和片元着色器的皮毛,这篇郭先生说一说着色器变量,通过变量可以设置材质。先看看今天要做的如下图。在线案例请点击博客原文。

在这个案例之前,我们先复习一下着色器变量
- Uniforms是所有顶点都具有相同的值的变量。 比如灯光,雾,和阴影贴图就是被储存在uniforms中的数据。 uniforms可以通过顶点着色器和片元着色器来访问。
- Varyings 是从顶点着色器传递到片元着色器的变量。因此需要在两个着色器中同时定义,对于每一个片元,每一个varying的值将是相邻顶点值的平滑插值。
- Attributes 与每个顶点关联的变量。例如,顶点位置,法线和顶点颜色都是存储在attributes中的数据。attributes 只可以在顶点着色器中访问。
嗯,现在我们知道了这些变量的用法,接下来我们使用它。
1. 制作红绿灯几何体
要制作这样一个红绿灯,我们考虑使用Geometry的merge方法
var shape = new THREE.Shape();
shape.moveTo(-10, 20);
shape.absarc(0, 20, 10, Math.PI, Math.PI * 2, true);
shape.lineTo(10, -20);
shape.absarc(0, -20, 10, 0, Math.PI, true );
shape.lineTo(-10, 20); var extrudeSettings = {
steps: 2, //用于沿着挤出样条的深度细分的点的数量,默认值为1
depth: 5, //挤出的形状的深度,默认值为100
bevelEnabled: true, //对挤出的形状应用是否斜角,默认值为true
bevelThickness: 1, //设置原始形状上斜角的厚度。默认值为6
bevelSize: 1, //斜角与原始形状轮廓之间的延伸距离
bevelSegments: 10, //斜角的分段层数,默认值为3
curveSegments: 12, //曲线上点的数量,默认值是12
};
var frame = new THREE.ExtrudeGeometry(shape, extrudeSettings);
// var material = new THREE.MeshPhongMaterial({color: 0x222222, emissive: 0x222222}); var cylinGeom = new THREE.CylinderGeometry(6, 6, 6, 30, 20);
frame.merge(cylinGeom.clone(), new THREE.Matrix4().compose(new THREE.Vector3(0, 15, 3.1), new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0), Math.PI/2), new THREE.Vector3(1,1,1)));
frame.merge(cylinGeom.clone(), new THREE.Matrix4().compose(new THREE.Vector3(0, 0, 3.1), new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0), Math.PI/2), new THREE.Vector3(1,1,1)));
frame.merge(cylinGeom.clone(), new THREE.Matrix4().compose(new THREE.Vector3(0, -15, 3.1), new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0), Math.PI/2), new THREE.Vector3(1,1,1)));
通过ExtrudeGeometry挤压出我们想要的几何体,然后添加三个圆柱体,形成我们想要的几何体。
2. 设置uniform变量
现在使用uniform变量
uniforms = {
time: {
type: 'f', value: 0.0
}
}
这里我们在其中设置一个叫做time的变量,它的类型是一个float类型,默认值设置成0.0。然后我们在requestAnimationFrame的每一帧动画中调用uniforms.time.value += 0.01;让着色器动起来。
3. 顶点着色器
顶点着色器我们不做太多操作
varying vec3 vPosition;
uniform float time;
void main() {
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
这里我们定义一个三维向量vPosition,用来将顶点着色器里面的position属性传递到片元着色器中(three.js会默认传入一些属性,像uv,position,normal等)
4. 片元着色器
varying vec3 vPosition;
uniform float time;
void main() {
float time = mod(time, 3.0);//time值对3取模,得到[0,3)范围内的值。
//由于我们制作红绿灯时用了小技巧,让其z分量比较大,所以可以根据z的值判断是否为红绿灯面。然后在根据y值,判断为哪个灯。
if(vPosition.z == 6.1 && vPosition.y > 8.0) {
if(time < 1.0) {//时间为[0,1)红灯
gl_FragColor=vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor=vec4(0.2, 0.0, 0.0, 1.0);
}
} else if(vPosition.z == 6.1 && vPosition.y > -8.0) {//时间为[1,2)黄灯
if(time >= 1.0 && time < 2.0) {
gl_FragColor=vec4(1.0, 0.7, 0.0, 1.0);
} else {
gl_FragColor=vec4(0.2, 0.1, 0.0, 1.0);
}
} else if(vPosition.z == 6.1) {//时间为[2,3)绿灯
if(time >= 2.0) {
gl_FragColor=vec4(0.0, 1.0, 0.0, 1.0);
} else {
gl_FragColor=vec4(0.0, 0.2, 0.0, 1.0);
}
} else {//其余部分为灰色
gl_FragColor=vec4(0.2, 0.2, 0.2, 1.0);
}
}
这里我们使用顶点着色器传过来的向量vPosition和uniform中的time值做一些判断,实现对每个点颜色进行控制(根据颜色插值从而实现颜色面的控制),里面使用了一些方法,例如mod,请参见上一篇文章。
虽然这个小案例很简单,但是我相信大家肯定有了很好的想法,前面几篇都是比较基础的,后面还有很多好看的案例,喜欢就点个赞吧!
转载请注明地址:郭先生的博客
three.js 着色器材质之变量(一)的更多相关文章
- three.js 着色器材质之变量(二)
上一篇郭先生在例子中用到了着色器变量中的uniform和varying.这篇继续结合例子将一下attribute变量,在使用过程中也发现由于three.js的版本迭代,之前的一些属性和参数已经发生了改 ...
- three.js 着色器材质之变量(三)
这篇郭先生在练习一下着色器变量,在度娘上面或者官网上经常看到类似水波一样的效果,这篇就试着做一个这样的效果,顺便巩固一下顶点着色器和片元着色器,毕竟多多练习才能更好地掌握.效果如下图,在线案例请点击博 ...
- three.js 着色器材质基础(一)
说起three.js,着色器材质总是绕不过的话题,今天郭先生就说一说什么是着色器材质.着色器材质是很需要灵感和数学知识的,可以用简短的代码和绘制出十分丰富的图像,可以说着色器材质是脱离three.js ...
- three.js 着色器材质内置变量
这篇郭先生说一下three.js着色器的内置变量,分别是 gl_PointSize:在点渲染模式中,控制方形点区域渲染像素大小(注意这里是像素大小,而不是three.js单位,因此在移动相机是,所看到 ...
- three.js 着色器材质之纹理
今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击博客原文. 这里我们分别引入三个纹理,分别是地球的表面纹理,对应的海拔灰度图,和云朵的纹理.使用表面纹理还 ...
- three.js 着色器材质之glsl内置函数
郭先生发现在开始学习three.js着色器材质时,我们经常会无从下手,辛苦写下的着色器,也会因莫名的报错而手足无措.原因是着色器材质它涉及到另一种语言–GLSL,只有懂了这个语言,我们才能更好的写出着 ...
- OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)
OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,unifo ...
- OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围
OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章) 所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符. ...
- [js]js的惰性声明, js中声明过的变量(预解释),后在不会重新声明了
js的惰性声明, js中声明过的变量(预解释),后在不会重新声明了 fn(); // 声明+定义 js中声明过一次的变量,之后在不会重新声明了 function fn() { console.log( ...
随机推荐
- 主题博客添加 h5 贴边音乐插件
前言: 前几日,在逛微博的时候,发现微博主页的左下角有一个贴边的音乐小插件,我顿时就想在自己博客上也弄一个玩玩.当时就想把微博那个移植过来,首先我用谷歌浏览器F12 查看页面源码,和检查元素代码,发现 ...
- Python-字符串内容检测
str.isnumeric():检测字符串是否只由数字组成 str.isalpha():检测字符串是否只由字母组成 str.islower():检测字符串中所有的字母是否都为小写 str.isuppe ...
- 解决alert在ios版微信中显示url的问题(重写alert)
为了解决alert在ios版微信中显示url的问题 window.alert = function(name){ var iframe = document.createElement("I ...
- Java 线程池中的线程复用是如何实现的?
前几天,技术群里有个群友问了一个关于线程池的问题,内容如图所示: 关于线程池相关知识可以先看下这篇:为什么阿里巴巴Java开发手册中强制要求线程池不允许使用Executors创建? 那么就来和大家探讨 ...
- Alink漫谈(十一) :线性回归 之 L-BFGS优化
Alink漫谈(十一) :线性回归 之 L-BFGS优化 目录 Alink漫谈(十一) :线性回归 之 L-BFGS优化 0x00 摘要 0x01 回顾 1.1 优化基本思路 1.2 各类优化方法 0 ...
- Eclipse默认快捷键说明
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当 ...
- [spring cloud] -- 服务注册与服务发现篇
eureka 服务发现客户端 DiscoveryClinet职责(核心) 注册服务无试了到Eureka Server中; 发送新塘更新与Eureka Server的租约: 在服务关闭时从Eureka ...
- 题解 洛谷 P5465 【[PKUSC2018]星际穿越】
首先考虑题目的性质,发现点向区间连的边为双向边,所以也就可以从一个点向右跳到区间包含该点的点,如图所示: 但事实上向后跳其实是不优的,可以有更好的方法来节省花费: 因此我们发现一个点跳到其前一个区间的 ...
- HTTP request smuggling CL.TE
CL.TE 简介 前端通过Content-Length处理请求,通过反向代理或者负载均衡将请求转发到后端,后端Transfer-Encoding优先级较高,以TE处理请求造成安全问题. 检测 发送如下 ...
- 旧的成功的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="htt ...