理贴图(Textures)字面意思就是給几何体对象贴上不同的纹理图!好比于我们每天选择穿不同的衣服,我们穿不同的衣服带来的感官会有很大变化!同理几何体不同贴图的视觉效果也会有千差万别。纹理贴图是 Three.js一个很重要的内容,掌握了纹理贴图可以让3d效果产生质的飞跃。
那现在就让我们进入正题吧!go!go!go!
如果没有纹理贴图,我们看到的3d物体将会是很糟糕的!例如下面这个最基础贴图例子。
//创建一个球体几何对象
const circlegeometry=new THREE.SphereBufferGeometry(0.5, 16, 16)
//创建一个立方体几何对象Geometry
const geometry=new THREE.BoxGeometry(1, 1, 1);
//创建一个圆环几何对象
const tourGeometry=new THREE.TorusBufferGeometry(0.3, 0.15, 16, 32);
// 加载贴图
let textureLoader=new THREE.TextureLoader();
const texture=textureLoader.load('/three/grass.png');
//材质对象Material
const material=new THREE.MeshBasicMaterial({
// color: 0xb9d3ff
});
material.map=texture;
不同的人穿同样的衣服显然是不合适的,好比一个140kg的胖子穿s码的T恤,那肯定是穿不下的!纹理贴图也是一样的道理,它并不是适合每种「材质对象(Material)」。材质对象按大类分可分为五种。如下
「网络(Mesh)材质」顾名思义,网格类模型才会使用的材质对象。那现在就来看看它带来的贴图效果吧。
网格基础材质,不受带有方向光源影响,没有棱角感。使用示例如下:
//材质对象MeshBasicMaterial
const material=new THREE.MeshBasicMaterial({
color: 0x00ff00
transparent:true,
opacity:.5
});
material.map=texture;
material.wireframe=true;
材质常用属性简介:color材质颜色,比如蓝色0x0000ff;wireframe将几何图形渲染为线框。默认值为false;opacity透明度设置,0表示完全透明,1表示完全不透明;transparent是否开启透明,默认false
网格法向量材质,是一种比较特殊的材质。它使得物体的每一个面的颜色都从该面向外指的法向量计算得到的。
//材质对象MeshNormalMaterial
const material=new THREE.MeshNormalMaterial({
// color: 0x00ff00,
// transparent:true,
// opacity:.5
});
// material.map=texture;
// material.wireframe=true;
material.flatShading=true
材质常用属性简介:flatShading可以让每个小平面更加的平坦突出
由一个材质捕捉(MatCap,或光照球(Lit Sphere))纹理所定义,其编码了材质的颜色与明暗。由于mapcap图像文件编码了烘焙过的光照,因此MeshMatcapMaterial 不对灯光作出反应。
const texture=textureLoader.load('/three/5B4CBC_B59AF2_9B84EB_8F78E4.png');
//材质对象Material
const material=new THREE.MeshMatcapMaterial({
});
material.matcap=texture;
材质特别属性简介:matcap贴图属性
使用这种材质的物体,其外观不是由光照或某个材质属性决定的;而是由物体到相机的距离决定的。「当物体离相机较近时会呈现白色,较远时会呈现黑色。贴图和颜色对其无效果」,可以将这种材质与其他材质相结合,从而很容易创建逐渐消失的效果。
const material=new THREE.MeshDepthMaterial({
// color: 0x00ff00,
// transparent:true,
// opacity:.5
});
const width=container.clientWidth; //窗口宽度
const height=container.clientHeight; //窗口高度
const k=width / height; //窗口宽高比
const s=1.2; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
const camera=new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 100);
camera.position.set(2, 3, 4); //设置相机位置
// camera.position.set(20, 30, 40); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
MeshLambertMaterial这是一种暗淡的非光泽表面的材质,没有镜面高光,并且会对光源做出反应。高光网格材质MeshPhongMaterial除了和MeshLambertMaterial一样可以实现光源和网格表面的漫反射光照计算,还可以产生高光效果(镜面反射)。
//点光源
const point=new THREE.PointLight(0xffffff,.5);
point.position.set(4, 4, 4); //点光源位置
scene.add(point); //点光源添加到场景中
// //环境光
const ambient=new THREE.AmbientLight(0xffffff,.5);
scene.add(ambient);
// MeshLambertMaterial
const material=new THREE.MeshLambertMaterial({
color: 0xff0000,
});
// MeshPhongMaterial
const material=new THREE.MeshPhongMaterial({
color: 0xff0000,
specular:0xffffff,//高光部分的颜色
shininess:60,//高光部分的亮度,默认30
});
MeshLambertMaterial特别属性简介:specular高光部分的颜色;shininess高光部分的亮度,默认30
MeshStandardMaterial和MeshPhysicalMaterial类是PBR物理材质,可以更好的模拟光照计算,相比光网格材质MeshPhongMaterial渲染效果更逼真。我们今天只看MeshStandardMaterial贴图效果。
//材质对象Material
const material=new THREE.MeshStandardMaterial();
material.metalness=0.45; // 金属度属性
material.roughness=0.65; //粗糙度属性
material.map=texture;
// 环境贴图
const envTextTure=cubeTextureLoader.load([
'/three/texture/px.png',
'/three/texture/nx.png',
'/three/texture/py.png',
'/three/texture/ny.png',
'/three/texture/pz.png',
'/three/texture/nz.png'
])
//材质对象Material
const material=new THREE.MeshStandardMaterial();
material.metalness=0.7; // 金属度属性
material.roughness=0.2; //粗糙度属性
material.envMap=envTextTure;
材质特别属性简介:metalness金属度属性(0.0到1.0之间的值可用于生锈的金属外观);roughness粗糙度属性(0.0表示平滑的镜面反射,1.0表示完全漫反射. 默认 0.5)
这些网站主要是关于「贴图推荐」和「纹理贴图工具」。好的「贴图」可以让我们的物体更加的惟妙惟肖。所以推荐一下,希望对大家有帮助!
本篇文章只是粗浅介绍了纹理贴图和常用网络材质的使用方法,并顺便引入了相机和光源。最后展示的贴图效果还是很不错的。如果你需要深入学习的话还是需要翻阅大量有关资料的。
three.js journey
Three.js零基础入门教程(郭隆邦)
blender 里面导出的贴图好的模型,在 threejs 中加载会变暗,如何解决,首先简单的介绍如何在 blender 中贴图与导出
一、选择材质属性
二、点击 Base Color 旁边的小圆点,会显示一些菜单,选择 Image Texture
三、点击 Open 选择图片
四、修改渲染模式
五、导出 glb 格式模型
双击可以修改模型的名字,比如:改成 Cube-1
颜色深修改材质类型 MeshStandMaterial 为 MeshBasicMaterial
引用官方的说法:
three.js是使用WebGL来绘制三维效果的,three.js封装了诸如场景、灯光、阴影、材质、贴图、空间运算等一系列功能,让你不必要再从底层WebGL开始写起。
所以学习three.js并不需要专门去学习webGL,当然有基础肯定是有帮助的。
1.打开官网看到下图,右边是一些3d样例,对初学没什么用。
官网首页
左边r130代表的版本号,这边建议大家去看的是文档说明(documentation)和resources的第一个学习资源(Three.js Fundamentals),他们都有对应的中文翻译,讲得比较基础适合入门
1) three.js版本更新得很快,今天你下载了一个新版本,明天可能又更新了。很多旧版的方法在新版中被删除,一些方法的引用文件也有所改变,在网上搜索到的很多教程都是r6-r9版本,方法的使用看起来也是各异,学习起来挺混乱的。这里我使用r130版本(编写这边文章时候的最新版本)。各版本官方下载地址:https://github.com/mrdoob/three.js/tags 。
2) 下载完之后解压得到three.js-master文件夹。这边将build里面的three.js拿出来,在自己项目做练习,examples里面有各种样例的代码包括了素材和对应的js依赖,之后可以拿来做练习(毕竟3d素材自己不好弄)。
目录结构
我使用的vscode ,安装live Server插件,可以跑本地服务,解决了图片等素材引用的跨域问题,当然你也可以直接使用官方的脚手架来练习。官方脚手架需要node环境,如果不了解的建议使用vscode。
这里我使用官网上的例子。先上全代码,附注释。可以运行下看效果。
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body {
margin: 0;
padding:0;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
const animate = function () {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
</script>
</body>
</html>
1.创建了一个场景,也就是3d模型等展示的舞台。
const scene=new THREE.Scene();
2.创建一个相机,他拍到的地方就是我们看到的内容,这里创建的是透视相
第一个参数:是角度表示看到的范围,
第二个表示:长宽比,作用是展示的物体可以正常比例显示
三四参数表示:近截面(near)和远截面(far),当物体某些部分比摄像机的远截面远或者比近截面近的时候,该这些部分将不会被渲染到场景中。
const camera=new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
3.创建一个渲染器,将场景和相机放入,渲染画面,设置渲染范围,并添加到页面中
const renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
4.创建简单的3d模型
// 创建一个正方体
const geometry = new THREE.BoxGeometry();
// 创建网格基础材质 可以理解为外表样子,材质有很多种,详细可以查文档
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
// 创建网格 将他们加入网格中在添加到场景,网格包含一个几何体以及作用在此几何体上的材质
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
5.渲染
// 这边是将相机拉远了,便于观察。如下图所示
camera.position.z = 5;
// 添加动画,渲染
const animate=function () {
requestAnimationFrame( animate );
cube.rotation.x +=0.01;
cube.rotation.y +=0.01;
renderer.render( scene, camera );
};
animate();
6.效果图
*请认真填写需求信息,我们会在24小时内与您取得联系。