本段内容会写在0篇以外所有的,本人所编写的Threejs教程中
对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久
如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS
首先我们准备一张瓷砖的贴图
还记得之前写过的草地吗?我们以同样的方式,把瓷砖贴图贴给plane
function addMesh(){
let texture = new THREE.TextureLoader().load('./ls.jpg');
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
这里我们要介绍纹理的第一个属性 wrap(包裹模式),warp有两个属性,wrapT和wrapS,S对应水平方向的图像,如何对应到物体的uv上,S对应uv的U,T对应垂直方向上,T对应uv的V
官方提供了三种包裹模式
THREE.RepeatWrapping :重复模式
THREE.ClampToEdgeWrapping:延伸模式
THREE.MirroredRepeatWrapping:镜像重复模式,每次重复时会镜像纹理
我们想要地板效果,就不能使用默认的延伸模式,而应该使用重复或镜像模式,同时,我们也应该为纹理设置其重复次数
texture.repeat : Vector2 ,x轴对应uv的u方向上重复几次,y对应uv的v方向上重复几次
这里说起来可能会比较麻烦,但是我们实际用一下,就直接可以明白了
function addMesh(){
let texture = new THREE.TextureLoader().load('./ls.jpg');
texture.wrapT = texture.wrapS = THREE.RepeatWrapping;
texture.repeat.set(10,10);
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
我们还可以换成让它镜像重复
texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;
在实际的设计中,我们的贴图都是由设计来出的,上面的贴图来源于网络,在视觉观感上可能会比较差,而我们作为程序开发,大多数都不具备良好的审美,所以不用去计较贴图是否好看
是不是当前的图形有点不太好看,那么我们转一下它吧
function addMesh(){
let texture = new THREE.TextureLoader().load('./ls.jpg');
texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;
texture.repeat.set(10,10);
texture.rotation = Math.PI/4;
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
除了旋转,我们还可以移动纹理
function addMesh(){
let texture = new THREE.TextureLoader().load('./ls.jpg');
texture.wrapT = texture.wrapS = THREE.MirroredRepeatWrapping;
texture.repeat.set(10,10);
texture.rotation = Math.PI/4;
texture.offset.set(0.8,0.8);
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
既然我们能对纹理进行操作了,那么,我们就可以利用操作纹理来做一些特别的效果,比如说一个旋转的图形
let texture;
function addMesh(){
texture = new THREE.TextureLoader().load('./light.png');
texture.center.set(0.5,0.5);
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture,
transparent:true
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
function render(){
renderer.render(scene,camera);
requestAnimationFrame(render);
texture.rotation += 0.01;
}
图片是用ps做的
我们只需要对texture做相应处理,就可以做出一个旋转的圆环效果
这个就是最简单的一种动态光圈效果,根据图片的质量不同,我们也能做出效果更好的动态光圈
(图片来源于百度,如有侵权请联系我)
简单的水流效果
let texture;
function addMesh(){
texture = new THREE.TextureLoader().load('./water.png');
//记得开启重复模式
texture.wrapT = texture.wrapS = THREE.RepeatWrapping;
let geometry = new THREE.PlaneGeometry(10,10).rotateX(-Math.PI/2);
let material = new THREE.MeshBasicMaterial({
map:texture
});
let mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
}
function render(){
renderer.render(scene,camera);
requestAnimationFrame(render);
texture.offset.x += 0.001;
}
这里笔者没有gif图,就放一张静态图上来,在render中让贴图每一帧行走0.001就可以实现水流流动的感觉
笔者这里也没有使用完美重合的水流图,所以在流动过程中可以看到很明显的图片分界线,这种图片一般由设计人员来寻找或制作
同理,使用箭头贴图,可以制作箭头流动的效果
有那么一类物体,在我们的项目中不需要展示细节,但是它却拥有很复杂的外观结构,比如说我们想在屋子里放一台笔记本电脑
如果给笔记本电脑完整的建模,那么多键盘的键位的细节都做的很精致很清楚,屏幕微小的高度差也被看的清清楚楚。。。然后把这个模型用在一个大型的场景中,我们会发现,在大型场景下,我们最多只能看到这个物体是个笔记本,而很多人不会去刻意去看笔记本的模型做的细节,而是更关注大型场景
这个时候,我们使用一张贴图来替代笔记本的键盘建模,直接使用两个box来做成笔记本,给屏幕的box贴一张图,给键盘的box再贴一张图,两张图+两个box,比起精致的建模来说,可以省去大量的建模时间以及点线面空间
总结一下就是:在做程序用的模型时,没必要的细节可以用纹理直接代替 ,以节省点线面数量
初识MeshStandardMaterial