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

原文地址:https://www.cnblogs.com/vadim-web/p/13469016.html

今天郭先生说一说如何在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);
    }
`

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

var sphere = new THREE.SphereBufferGeometry(10, 128, 64);

var texture1 = new THREE.TextureLoader().load(‘/static/images/texture/planets/diqiu-s.jpg’, () ⇒ {this.loaded_num –});
var texture2 = new THREE.TextureLoader().load(‘/static/images/texture/planets/dixing.jpg’, () ⇒ {this.loaded_num –});
var texture3 = new THREE.TextureLoader().load(‘/static/images/base/water.jpg’, () ⇒ {this.loaded_num –});

uniforms = {
time: {
value: 0
},
texture1: ,
texture2: ,
texture3: ,
}

uniforms[ “texture3” ].value.wrapS = uniforms[ “texture3” ].value.wrapT = THREE.RepeatWrapping;

var material = new THREE.ShaderMaterial({
uniforms: uniforms,
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 ); },
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); }
});

mesh = new THREE.Mesh(sphere, material);

scene.add(mesh);

this.render();

这个差不多就是全部代码了,主要就是一个材质

 

WEBGL学习网(WebGLStudy.COM)专注提供WebGL 、ThreeJS、BabylonJS等WEB3D开发案例源码下载。
声明信息:
1. 本站部分资源来源于用户上传和网络,如有侵权请邮件联系站长:1218436398@qq.com!我们将尽快处理。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源打赏售价用于赞助本站提供的服务支出(包括不限服务器、网络带宽等费用支出)!
7.欢迎加QQ群学习交流:549297468 ,或者搜索微信公众号:WebGL学习网
WEBGL学习网 » three.js 着色器材质之纹理材质

发表评论

提供优质的WebGL、ThreeJS源码

立即查看 了解详情