今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击博客原文

这里我们分别引入三个纹理,分别是地球的表面纹理,对应的海拔灰度图,和云朵的纹理。使用表面纹理还是地球的外貌,海拔灰度图给地球添加凹凸效果,云朵纹理给地球添加云朵效果。下面我们说一说代码。

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)+y*a。

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

这样就获得了一个动态的地球。是不是很简单呢?

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

three.js 着色器材质之纹理的更多相关文章

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

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

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

    上一篇郭先生在例子中用到了着色器变量中的uniform和varying.这篇继续结合例子将一下attribute变量,在使用过程中也发现由于three.js的版本迭代,之前的一些属性和参数已经发生了改 ...

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

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

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

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

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

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

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

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

  7. [Unity] Shader(着色器)之纹理贴图

    在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...

  8. pixi.js 图像资源(svg)转纹理

    当Pixi使用WebGL去调用GPU渲染图像时,需要先将图像转化为GPU可以处理的版本.而能够被GPU处理的图像就叫做纹理,在pixi中使用纹理缓存来存储和引用所有纹理.通过将纹理分配给精灵,再将精灵 ...

  9. three中的着色器示例

    其实在3D引擎/库的帮助下,我们做webgl开发的难度已经很大大地降低了,熟悉相关API的话,开发一个简单的3D程序可以说是很轻松的事情. 在我看来,webgl的核心就是着色器(顶点着色器.片元着色器 ...

随机推荐

  1. 利用vue-i18n实现多语言切换

    在vue项目中利用vue-i18n,我们可以实现多语言的切换,可以轻松搞定大部分的需求,包括中英文切换,以及词条的变更. vue-i18n基本的使用方法 一.安装vue-i18n npm instal ...

  2. Java中使用方法的注意事项

    Java方法使用的注意事项 本文列举了几个小白在java中使用方法应该注意的几个地方 1. 方法应该定义在类中2.方法中不可以再嵌套方法3.方法定义的前后顺序无所谓4.想要执行方法必须要调用5.如果方 ...

  3. CCNA - Part7:网络层 - ICMP 应该是你最熟悉的协议了

    ICMP 协议 在之前网络层的介绍中,我们知道 IP 提供一种无连接的.尽力而为的服务.这就意味着无法进行流量控制与差错控制.因此在 IP 数据报的传输过程中,出现各种的错误是在所难免的,为了通知源主 ...

  4. 大厂程序员教你如何学习C++(内附学习资料)

    目前准备面试同学都知道,C++是百度和腾讯的主流开发语言,而java是阿里的主流开发语言. 对于初学者来说,也不用纠结究竟学习c++还是java 其实只要好好掌握好一门即可,另一门即可融会贯通 因为我 ...

  5. spring-cloud-alibaba-sentinel和feign配合使用,启动报Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List

    背景 我在学习spring-cloud-alibaba技术栈期间,在学习服务熔断与限流的时候,服务启动发生了以下异常 #这是控制台最上面的 sun.misc.Unsafe.park(Native Me ...

  6. ReentrantLock以及AQS实现原理

    什么是可重入锁? ReentrantLock是可重入锁,什么是可重入锁呢?可重入锁就是当前持有该锁的线程能够多次获取该锁,无需等待.可重入锁是如何实现的呢?这要从ReentrantLock的一个内部类 ...

  7. 01 . RPC简介原理及用Go实现一个简单的RCP

    RPC简介 本地过程调用 // 正常情况下程序的执行和调用情况.例如有如下go语言代码: package main import "fmt" func main() { var a ...

  8. android 官方教程地址和一个中文教程

    https://developer.android.google.cn/guide/components/fundamentals http://www.runoob.com/w3cnote/andr ...

  9. Android Zero (基础介绍篇)

    开发Android首先你得先配置好环境,配置的文章网上一大把,这里就不重复造轮子说了,配置好JAVA下载好AndroidStudio后我们先对基本的项目结构做一下了解! 首先介绍下你必须得知道的文件夹 ...

  10. proj0的具体实现 #CS61B-sp18

    https://github.com/Centurybbx/sp18-century/tree/master/proj0 proj0的具体实现在上面的Github中. 在proj0中我明显感受到国外大 ...