webgl之Three.js学习 day9加载和使用纹理

一、在材质中使用纹理

1.加载纹理并应用

纹理最基础的用法是在材质上设置贴图。当你使用 这个材质时(和几何体一起构建网格),网格就会拥有颜色,而这个颜色则来源于纹理。

可以用如下的方式来加载纹理并应用于网格:

function createMesh(geom,imageFile){
    var texture = THREE.ImageUtils.loadTexture
                        ("../assets/textures/general/"+imageFile);
    var mat = new THREE.MeshPhongMaterial();
    mat.map = texture;
    var mesh = new THREE.Mesh(geom,mat);
    return mesh;
}

为了达到最佳效果,最好使用正方形的图片,其长宽大小是2的次方。例如大小为256*256,512*512,1024*1024的图片最合适。

由于纹理需要放大和缩小,所以纹理上的像素(也称作是texel)通常不会一对一地映射成面上的像素。因此,WebGL和Three.js提供了集中选择。你可以设置magFilter属性,指定纹理如何放大;设置minFilter属性,指定纹理如何缩小。这些属性可以设置成下面的两个基础值:

名称

描述

THREE.NearestFilter(最近过滤器)

这个过滤器使用能够找到的最近texel(纹理上的像素)的颜色。用于放大时,这回导致方块化;用于缩小时,这回丢失很多细节

THREE.LinearFilter(线性过滤器)

这个过滤器比较高级,它会使周围四个texel的颜色值来确定颜色。这样虽然在缩小时仍然会丢失很多细节,但在放大时会平滑很多,方块化也比较少

除了这些基础值,我们还可以使用mipmap。一个mipmap是一组纹理图片,每个图片的尺寸都是前一张图片的一半。这些图片是在加载纹理时创建的,可以生成比较光滑的过滤效果。所以如果你有一个正方形的纹理(尺寸为2的次方),只需要稍稍几步就可以达到更好的过滤效果。这些属性可以设置成下面这些值:

名称

描述

THREE.NearestMipMapNearestFilter

这个过滤器会选择最贴近目标解析度的mipmap,然后应用前表中所讲的最近过滤原则。放大时仍然会有方块化,但缩小时会好很多。

THREE.NearestMipMapLinearFilter

这个过滤器选择的不是mipmap,而是层次最近的两个mipmap。然后在这两层上应用最近过滤原则获取两个中间值。这两个中间值会传递给一个线性过滤器,以获取最终结果

THREE.LinearMipMapNearestFilter

这个过滤器会选择最贴近目标解析度的mipmap,然后应用前表中所讲的线性过滤原则

THREE.LinearMipMapLinearFilter

这个过滤器选择的不是一个mipmap,而是层次最近的两个mipmap。然后在这两层上应用线性过滤原则获取两个中间值。这两个中间值会传递给一个线性过滤器,以获取最终结果

如果你没有明确指定magFilter和minFilter属性的值,对于magFilter属性,Three.js会使用THREE.LinearFilter。对于minFilter属性,Three.js会使用THREE.LinearMipMapLinearFilter。

2.使用凹凸贴图创建皱纹

我们可以为材质设置额外的纹理(所谓的凹凸贴图)来为材质增加厚度:

function createMesh(geom,imageFile,bump){
    var texture = THREE.ImageUtils.loadTexture
                        ("../assets/textures/general/"+imageFile);
    var mat = new THREE.MeshPhongMaterial();
    mat.map = texture;
    
    var bump = THREE.ImageUtils.loadTexture
                        ("../assets/textures/general/"+bump);
    mat.bumpMap = bump;
    mat.bumpScale = 0.2;
    var mesh = new THREE.Mesh(geom,mat);
    return mesh;
}

这段代码中,除了设置map属性,我们还设置了纹理的bumpMap属性。另外,通过bumpScale属性,我们还可以设置凹凸的高度(如果是负数,则指的是深度)。像素的密集度定义的是凹凸的高度。凹凸贴图中只有像素的相对高度,没有任何坡度的方向性信息。

3.使用法向贴图创建更加细致的凹凸和皱纹

法向贴图中保存的不是每个像素的高度,而是像素的法向向量。如下图所示:

下面的代码展示的就是如何在Three.js里使用法向贴图:

function createMesh(geom,imageFile,normal){
    var t = THREE.ImageUtils.loadTexture
                        ("../assets/textures/general/"+imageFile);
    var m = THREE.ImageUtils.loadTexture
                        ("../assets/textures/general/"+normal);
    var mat2 = new THREE.MeshPhongMaterial({map:t,normal:m});
    
    var mesh = new THREE.Mesh(geom,mat2);
    return mesh;
}

这里我们将normalMap属性设置为一个法向纹理。我们还可以指定凹凸的程度,方法是设置normalScale属性:mat.normalScale.set(1,1)。通过这两个属性,你可以沿着x轴和y轴进行缩放。

4.使用光照贴图假阴影

光照贴图是预先渲染好的阴影,你可以用它来模拟真实的阴影。光照贴图中的阴影将会显示成地面上的阴影,从而模拟出真实阴影的效果。你可以用这种技术创建出解析度很高的阴影,而且不会损害渲染的性能。当然,这只对静态场景有效。光照贴图的使用跟其他纹理基本一样,只有几处小小的不同:

var lm = THREE.ImageUtils.loadTexture('../assets/textures/lightmap/lm-1.png');
var wood = THREE.ImageUtils.loadTexture('../assets/textures/general/floor-wood.jpg');
var groundMaterial = new THREE.MeshBasicMaterial({lightMap:lm,map:wood});
groundGeom.faceVertexUvs[1] = groundGeom.faceVertexUvs[0];

应用光照贴图时,我们只要将材质的lightMap属性设置成刚才所示的纹理即可。但是将光照贴图显示出来我们还需要额外的几个步骤。我们需要为光照贴图明确指定UV映射(将纹理的哪一部分应用到表面)。只有这样你才能将光照贴图与其他纹理独立开来。

5.用环境贴图创建虚假的反光效果

你可以通过创建一个对象所处环境的纹理来伪装反光,并将它应用到指定的对象上。下图既是同环境贴图创建发光效果的例子:

 这个截图里你可以看到球和方块反射这周围环境。如果移动鼠标,你还可以看到这个反光是跟相机角度和你所看到的城市环境相关联,要创建这样一个例子,我们要执行以下步骤:

(1)创建一个CubeMap对象:一个CubeMap是有6个纹理的集合,而这些纹理可以应用到方块的每一个面上。

(2)创建一个带有这个CubeMap对象的方块:带有CubeMap对象的方块就是移动相机时你所看到的环境。它可以在你向四周看时制造出一种幻象,就好像你站在某个环境中一样。实际上你是处在一个方块中,而这个方块内测渲染出来的纹理让你感觉好像处在某个空间中。

(3)将CubeMap作为纹理:我们用来模拟环境的CubeMap对象也可以用作网格的纹理。Three.js会让它看上去像是环境的反光。

你所需要的是六张用来构建整个场景的图片。所以你需要如下的图片:超前的(posz)、朝后的(negz)、朝上的(posy)、朝下的(negy)、朝右的(posx)、朝左的(negx)。Three.js会将它们缝合在一起,创建一个无缝的环境贴图。

 

二、纹理的高级用途

1.定制UV映射

通过UV映射,你可以指定纹理的哪一部分显示在物体表面上。UV映射的定制一般是在诸如Blender这样的软件中完成的,特别是当模型变得复杂时。这里需要记住的是UV映射有两个维度,U和V,取值范围是0到1。定制UV映射时,你要为物体的每个面指定其要显示纹理的哪一部分。

2.重复映射

3.在画布上绘制图案并作为纹理

  • 用画布做纹理
  • 用画布作凹凸贴图
  • 用视频输出作为纹理

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值