纹理

纹理用来表现物体的细节。理论上可以将物体的每个细节建模出来,但是这样时间成本和性能成本都太高,因此,将物体的一些细节用纹理来表示。

图片纹理

图片纹理直接在物体表面应用图片。可以使用TextureLoader类的load方法来加载纹理。

function loadImgTexture(){
var loader = new THREE.TextureLoader();
loader.load("metal-rust.jpg",function(texture){
var geometry = new THREE.BoxGeometry(10,10,10);
var material = new THREE.MeshBasicMaterial({color:0x739783,map:texture});
mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
})
}

注意加载图片是异步的,所以这里我们使用render循环来渲染:

function render(){
requestAnimationFrame(render);
renderer.render(scene,camera);
}

凹凸贴图

凹凸贴图可以使纹理也有厚度,看起来更立体。凹凸贴图一般使用一张灰度图,设置成材料的bumpMap属性

function loadImgTexture(){
var loader = new THREE.TextureLoader();
loader.load("stone.jpg",function(texture){
loader.load("stone-bump.jpg",function(bumpTexture){
var geometry = new THREE.BoxGeometry(10,10,10);
var material = new THREE.MeshPhongMaterial({map:texture,bumpMap:bumpTexture,bumpScale:0.2});
mesh = new THREE.Mesh(geometry,material);
mesh.rotation.x = 30/180Math.PI;
scene.add(mesh);
})
})
}

凹凸贴图虽然看起来更立体,但是其只是有深度,没有方向,所以只有在某个方向看是很立体,在其它方向看又不好。如果贴图的对象不怎么转动,光线也不怎么变化,倒可以使用凹凸贴图。

法向贴图

法向贴图使用一张法向图来表示纹理图片某个点的法向量。即用一张图片保存另一张图片的法向量信息,然后再在threejs中将这两个图片的信息合在一起,就形成了一个细节丰富的立体纹理。创建法向贴图如下,注意这里不要再使用MeshBasicMaterial:

function loadImgTexture(){
var loader = new THREE.TextureLoader();
loader.load("plaster.jpg",function(texture){
loader.load("plaster-normal.jpg",function(normalTexture){
var geometry = new THREE.BoxGeometry(10,10,10);
var material = new THREE.MeshPhongMaterial({map:texture,normalMap:normalTexture,bumpScale:0.2});
mesh = new THREE.Mesh(geometry,material);
mesh.rotation.x = 30/180Math.PI;
scene.add(mesh);
})
})
}

法向贴图可以生成细节丰富的纹理,同时不损害渲染性能。但是法向图这张图片创建起来稍有困难,使用Blender或Photo创建。

光照贴图

环境贴图

环境贴图是使用上下左右前后六张图或者一张全景图来模拟真实的环境,threejs会将这些图片渲染成无缝的环境盒子,例子可看【threejs-cubeMap例子】,其中貌似真实的环境,球的反光效果,都是用这张全景图渲染出来的: 

球的反光看起来非常逼真,但其实是假的,也就四并没有使用光线追踪来表现出反光效果。光线追踪是很耗cpu的,所以,使用环境贴图即节约性能,又能表现出很逼真的效果。

UV贴图

关于uv贴图,【blender wiki】里面说得很好:


UV贴图是将2D纹理映射到3D物体最灵活的一种方式.在这个过程中三维曲面网络("mesh")的X Y Z被展平到一副二维(X Y 或者说 我们将要看到的 U V)图片中,这样图片中的颜色就被映射到曲面网络("mesh")中。
有助于理解UV贴图的最形象的比喻是切开一个硬纸盒.盒子是一个三维物体,正如同加到场景中的一个曲面网络("mesh")方块.
如果沿着边缝或折痕剪开盒子,可以把盒子摊开在一个桌面上.当我们从上往下俯视桌子时,我们可以认为U是左右方向,V是上下方向.盒子上的图片就在一个二维坐标中.我们使用U V代表"纹理坐标系"来代替通常在三维空间使用的 X Y.

如果给模型的每个面都用一张图片去贴纹理,这将要加载很多纹理图片,如果可以只将图片的某个部分映射到模型,那就只需要一张图片就够了。uv贴图就能够将图片的某部分映射到模型的某个面,如果还不好理解,类比一下CSS Sprite技术。比如,上一篇【加载3D模型例子】例子中,我们用到了一张图片: 

这张图里面凌乱的放着摊开的人皮、衣服、手、眼睛等图片元素。而我们加载出来的模型是这样的: 

在这张图中,脸是脸,衣服是衣服,都在它们应该出现的位置。这便是使用了uv映射,将图中的某部分作为纹理,贴到模型中的对应部分。

但是,图中的各个部分,是怎么和模型对应起来的呢?一个人的模型有那么多个面,纯手工编码一个个去对应,感觉会出人命。其实,uv贴图一般是做模型的时候就做好了,图和模型的对应关系也包含在模型文件(就是那个.dae文件)中了,编程的时候一般是不用关心这个。

虽说如此,我们加载模型之后,也可以通过Geometry对象的faceVertexUvs属性看看具体是怎么映射的。简单起见,创建一个BoxGometry,查看一个其内置的uv映射:

var geom = new THREE.BoxGeometry(24, 24, 24);
console.log(geom.faceVertexUvs);

打印出:

是一个有12个元素的数组,12代表的就是立方体的12个三角面。再看数组的具体某一个元素:

又是一个长度为3的Vector2数组,代表纹理图片中的三个位置,这三个点围成的部分就是这个三角面的纹理。上面的(0,0),(1,0),(1,1)都是比例,0代表0%,1代表100%。点是从右下角开始按逆时针排列的,比如A(0,0),B(1,0),C(1,1)三点,在图片中围成的区域如下: 

将这张图加载到立方体,能更清晰立方体是如何通过uv映射来处理纹理的,【例子】。


持续更新看这里

threejs纹理的更多相关文章

  1. ThreeJS模拟人沿着路径运动-路径箭头使用纹理offset偏移

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. threejs深入纹理,立体场景cubeResolution(四)

    在这个课程里主要完成讲解两个demo: 一个是电视墙:用视频做纹理 一,用视频做纹理 首先我们用video标签把视频源引入: <video id="video" autopl ...

  3. m3u8编码视频webgl、threejs渲染视频纹理demo

    <!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>fz-live< ...

  4. ThreeJS文字作为纹理贴图

    文字作为纹理贴图 From:http://www.linhongxu.com/post/view?id=222 这里可以使用canvas作为纹理贴图,Three为我们提供里CanvasTexture ...

  5. threejs构建web三维视图入门教程

    本文是一篇简单的webGL+threejs构建web三维视图的入门教程,你可以了解到利用threejs创建简单的三维图形,并且控制图形运动.若有不足,欢迎指出. 本文使用的框架是three.js gi ...

  6. ThreeJS的特效合成器和后期处理通道

    最近要写个 web 交互式发光可交互的框架.没查到啥好资料,自己一个人摸索了很久,有些失望,可是毕竟是探索过的东西,所以做个记录,怀念我过去好多天掉的青丝(捂脸).我在前面那篇博客里面已经介绍了如何让 ...

  7. threejs - uv 映射 简要

    啥也不说先上way+code+demo; https://github.com/Thinkia/threejs_/blob/master/test/test2-%20uv/readme.md 如何理解 ...

  8. threejs绕轴转,粒子系统,控制器操作等(二)

    前言:threejs系列的第二篇文章,也是一边学习一边总结: 1,一个物体绕着另一个物体转动 上一篇文中主要是物体自转,为了描述一个一个物体绕另一个物体转,这里我描述了一个月球绕地球公转,并且自转的场 ...

  9. gis和threejs的学习资料

    *********************************** 基础知识/名词 瓦片/矢量瓦片GeoJson - 绘制GeoJson看数据, geojson规范, 中文版 ********** ...

随机推荐

  1. 强制停止ORACLE数据库

    操作环境 SuSE+Oracle11gR2 适用场景 shutdown immediate停止数据库失败 操作命令 1.kill掉oracle实例相关进程 2.清除oracle占用的共享内存段 ipc ...

  2. 使用django实现自定义用户认证

    参考资料:https://docs.djangoproject.com/en/1.10/topics/auth/customizing/    直接拉到最后看栗子啦 django自定义用户认证(使用自 ...

  3. Java学习06 (第一遍) - JSP与Servlet

    EL(Expression Language) <% User user=(User)session.getAttribute("user"); Dept dept=user ...

  4. quartz 实例

    第一步:添加jar包 第二步:在spring配置文件中添加 <context:annotation-config/> 第三步:编写定时代码 我们通常做Java后台接口,是让前端访问的,让前 ...

  5. 神经网络中的激活函数具体是什么?为什么ReLu要好过于tanh和sigmoid function?(转)

    为什么引入激活函数? 如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层 ...

  6. SimpleAdapter用法

    [SimpleAdapter用法] public class TestSimpleAdapter extends Activity { @Override protected void onCreat ...

  7. appium桌面版本以及一些自动化测试方方封装

    appium_desktop 标签(空格分隔): appium_desktop 一 appium_desktop_v1.2.6 1.appium_desktop在github上最新下载地址:appiu ...

  8. w3af的使用

    编解码工具 配置身份 基本身份认证 明文用base64编码 NTML认证方式,微软特有的加密方式 form表单身份认证 这样基于表单的认证就配置好了 基于cookie认证 点击后面的感叹号,它会有co ...

  9. Linux 学习总结(二)

    一.用户与用户组管理 1.添加用户 useradd 选项 用户名 -c 指定一段注释性描述 -d 目录,指定用户目录,若目录不存在,-m 选项可以创建目录 -g 指定用户所属用户组 -s 指定用户登陆 ...

  10. PHPActiveRecord validates

    validates_presence_of #检测是不是为空 为空的话可以抛出异常 *Model类: static $validates_presence_of = array( array('tit ...