three.js 着色器材质之纹理
时间:2022-07-24
本文章向大家介绍three.js 着色器材质之纹理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击着色器纹理。
捕57获.PNG
这里我们分别引入三个纹理,分别是地球的表面纹理,对应的海拔灰度图,和云朵的纹理。使用表面纹理还是地球的外貌,海拔灰度图给地球添加凹凸效果,云朵纹理给地球添加云朵效果。下面我们说一说代码。
1. 绘制几何体,加载贴图
我们只需要在一个球体中进行操作,所以新建一个球体。然后分别加载三张纹理。
var sphere = new THREE.SphereBufferGeometry(10, 128, 64);
var texture1 = new THREE.TextureLoader().load('/static/images/texture/planets/diqiu-s.jpg');
var texture2 = new THREE.TextureLoader().load('/static/images/texture/planets/dixing.jpg');
var texture3 = new THREE.TextureLoader().load('/static/images/base/water.jpg');
2. 使用uniform变量
这里除了将三张纹理传到着色器中,还传递了一个时间,这个时间来让纹理动起来。云朵的纹理的wrapS和wrapT设置成THREE.RepeatWrapping,这是让纹理简单地重复到无穷大,而不至于0,0到1,1的范围。
uniforms = {
time: {
value: 0
},
texture1: {
value: texture1
},
texture2: {
value: texture2
},
texture3: {
value: texture3
},
}
uniforms[ "texture3" ].value.wrapS = uniforms[ "texture3" ].value.wrapT = THREE.RepeatWrapping;
3. 顶点着色器
顶点着色器我们只是用地球的灰度图,这里面是用texture2D( texture2, vUv )来获取图片中每个点的颜色值。新建三维向量newPosition,这个向量代表球体上的点经过灰度贴图操作后新点的位置。由于是灰度图,那么他的r,g,b应该是相同的,并且保证新的顶点坐标是沿着球表面法向量方向,所以vec3 newPosition = position + normal * tcolor.r / 2.0;
vertexShader: `
varying vec2 vUv;
uniform sampler2D texture2;
void main() {
vUv = uv;
vec4 tcolor = texture2D( texture2, vUv );
vec3 newPosition = position + normal * tcolor.r / 2.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
}
`
4. 片元着色器
片元着色器使用两个纹理,还是顶点着色器传过来的uv以及时间。这里tcolor1就是地图点的颜色,tcolor3代表云朵的纹理,但是他的uv是随时间变化的(这里要求纹理设置重复)。这里还是用了mix方法,mix方法返回线性混合的x和y,如:x(1−a)+ya。
fragmentShader: `
varying vec2 vUv;
uniform sampler2D texture1;
uniform sampler2D texture3;
uniform float time;
void main() {
vec4 tcolor1 = texture2D( texture1, vUv );
vec4 tcolor3 = texture2D( texture3, vUv - vec2(time, - time * 0.4) );
gl_FragColor = mix(tcolor1, tcolor3 * 1.3, tcolor3.r / 2.0);
}
`
这样就获得了一个动态的地球。是不是很简单呢?
转载请注明地址:郭先生的博客
- 深度学习界的 “吃鸡挂”——目标检测 SSD 实验
- Hadoop查看所有JOB以及如何Kill指定用户的所有Job
- Java基础-23(01)总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程
- ORA-01427问题的分析和解决(r6笔记第51天)
- 从编程实现角度学习 Faster R-CNN(附极简实现)
- Java基础-23(02)总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程
- 8 个最好的 Java RESTful 框架
- 【C++基础】C++11 lambda 表达式解析
- 大量redo生成的问题原因及改进(r6笔记第50天)
- Java基础-22总结登录注册IO版,数据操作流,内存操作流,打印流,标准输入输出流,
- YOLO,一种简易快捷的目标检测算法
- Java基础-22总结转换流,随机访问流,合并流,序列化流,Properties
- openshift镜像构建
- 关于数据库无法登录的问题反思(r6笔记第49天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos下安装Ansible的示例代码
- ubuntu18.04安装搜狗拼音的简易教程
- linux中$符号的基础用法总结
- Linux下的 mariadb 使用 root 用户启动方式(推荐)
- window与linux项目部署之linux文件路径不存在问题
- Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib
- Linux使用 iftop 实时监控网卡的流量
- Centos中TCPWrappers访问控制实现
- CentOS7 重新分配分区大小的实现方法
- Linux 下安装pip包的方法
- Linux系统设置PATH环境变量(3种方法)
- leetcode栈之有效的括号
- linux系统安装iso文件方法
- xshell 远程登陆CentOS7 免密登陆的思路详解
- Linux服务器下Nginx与Apache共存的实现方法分析