前言

最近在做自定义几何体(平面)示例的时候,发现加上贴图后并没有得到想要的结果,代码是这样的:

 //创建几何体var geometry=new THREE.Geometry();var vertices=[new THREE.Vector3(0,0,0),new THREE.Vector3(100,0,0),new THREE.Vector3(100,100,0),new THREE.Vector3(0,100,0),];var faces=[new THREE.Face3(0, 1, 2),new THREE.Face3(0, 2, 3)];geometry.vertices = vertices;geometry.faces = faces;geometry.computeFaceNormals();//计算法向量 这决定了对光做出的反应material = new THREE.MeshLambertMaterial({map:new THREE.TextureLoader().load("./img/pic1.jpg"),side: THREE.DoubleSide,// color: "red",opacity: 1,depthWrite: false,transparent: true // 定义此材质是否透明});mesh = new THREE.Mesh(geometry, material);scene.add(mesh);

理想的结果:

实际的结果:

然后想到了,自定义的geometry是不会自动设置UV坐标的,那如何给它设置合适的UV坐标呢。这需要对UV坐标有一定的了解。

UV坐标

可以将需要贴图的图片,给它设定一个坐标系作为图片的定位,该坐标系就是UV坐标了。在贴图时,可以根据图片的UV坐标,对应到Three.js的每个三角面进行贴图。

在Three.js中可以定义好uv坐标,与每个三角面一一对应。
代码如下:

//创建几何体var geometry=new THREE.Geometry();var vertices=[new THREE.Vector3(0,0,0),new THREE.Vector3(100,0,0),new THREE.Vector3(100,100,0),new THREE.Vector3(0,100,0),];var faces=[new THREE.Face3(0, 1, 2),new THREE.Face3(0, 2, 3)];geometry.vertices = vertices;geometry.faces = faces;geometry.computeFaceNormals();//计算法向量 这决定了对光做出的反应material = new THREE.MeshLambertMaterial({map:new THREE.TextureLoader().load("./img/pic1.jpg"),side: THREE.DoubleSide,// color: "red",opacity: 1,depthWrite: false,transparent: true // 定义此材质是否透明});//几何体UV坐标定义var t0 = new THREE.Vector2(0, 0); //图片左下角var t1 = new THREE.Vector2(1, 0); //图片右下角var t2 = new THREE.Vector2(1, 1); //图片右上角var t3 = new THREE.Vector2(0, 1); //图片左上角var uv1 = [t0, t1, t2]; //选中图片一个三角区域像素——用于映射到一个三角面var uv2 = [t0, t2, t3]; //选中图片一个三角区域像素——用于映射到一个三角面geometry.faceVertexUvs[0][0] = uv1;geometry.faceVertexUvs[0][1] = uv2;mesh = new THREE.Mesh(geometry, material);scene.add(mesh);

效果:

如果想要重复多次贴图或者只贴一部分,只需要设计好贴图的UV坐标既可以了,如下修改UV部分代码:

//几何体UV坐标定义var t0 = new THREE.Vector2(0, 0); //图片左下角var t1 = new THREE.Vector2(0.5, 0); //图片右下角var t2 = new THREE.Vector2(0.5, 0.5); //图片右上角var t3 = new THREE.Vector2(0, 0.5); //图片左上角var uv1 = [t0, t1, t2]; //选中图片一个三角区域像素——用于映射到一个三角面var uv2 = [t0, t2, t3]; //选中图片一个三角区域像素——用于映射到一个三角面geometry.faceVertexUvs[0][0] = uv1;geometry.faceVertexUvs[0][1] = uv2;

效果:

实际上我们的几何体是有非常多的三角面组合而成的,为每个三角面设置好合适的uv坐标就可以实现多种多样的个性化贴图了。

完整示例代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>贴图与uv坐标</title><style>body {font-family: Monospace;margin: 0px;overflow: hidden;}</style>
</head><body><script type="text/javascript" src="../node_modules/three/build/three.js"></script><script type="text/javascript" src="../node_modules/three/examples/js/controls/OrbitControls.js"></script><script>let camera, light, scene, renderer, mesh, material, raycaster, group, texture;//初始化相机function initCamera() {camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);camera.position.set(400, 400, 400);}//初始化灯光function initLight() {light = new THREE.AmbientLight(0xffffff);}//初始化场景function initScene() {scene = new THREE.Scene();//坐标辅助线let helper = new THREE.AxisHelper(1000);//网格辅助线let gridHelper = new THREE.GridHelper(1000, 50);scene.add(helper);scene.add(light);scene.add(gridHelper);}//初始化物体function initMesh() {//创建几何体var geometry=new THREE.Geometry();var vertices=[new THREE.Vector3(0,0,0),new THREE.Vector3(100,0,0),new THREE.Vector3(100,100,0),new THREE.Vector3(0,100,0),];var faces=[new THREE.Face3(0, 1, 2),new THREE.Face3(0, 2, 3)];geometry.vertices = vertices;geometry.faces = faces;geometry.computeFaceNormals();//计算法向量 这决定了对光做出的反应material = new THREE.MeshLambertMaterial({map:new THREE.TextureLoader().load("./img/pic1.jpg"),side: THREE.DoubleSide,// color: "red",opacity: 1,depthWrite: false,transparent: true // 定义此材质是否透明});//几何体UV坐标定义var t0 = new THREE.Vector2(0, 0); //图片左下角var t1 = new THREE.Vector2(0.5, 0); //图片右下角var t2 = new THREE.Vector2(0.5, 0.5); //图片右上角var t3 = new THREE.Vector2(0, 0.5); //图片左上角var uv1 = [t0, t1, t2]; //选中图片一个三角区域像素——用于映射到一个三角面var uv2 = [t0, t2, t3]; //选中图片一个三角区域像素——用于映射到一个三角面geometry.faceVertexUvs[0][0] = uv1;geometry.faceVertexUvs[0][1] = uv2;mesh = new THREE.Mesh(geometry, material);scene.add(mesh);}//初始化function initRender() {renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(0xFFFFFF, 1.0);document.body.appendChild(renderer.domElement);//添加鼠标控制let controls = new THREE.OrbitControls(camera, renderer.domElement);//创建控件对象// controls.addEventListener('change', animate);//监听鼠标、键盘事件window.addEventListener('resize', onWindowResize, false);}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);//围绕Y轴旋转//group.rotateY(0.001 * Math.PI);if (texture) {// console.log("进来了");texture.offset.y += 0.01;}}function init() {initCamera();initLight();initScene()initMesh();initRender()animate();}init();</script>
</body></html>

Three.js的uv坐标贴图理解相关推荐

  1. threejsV0.143.0版本如何设置uv坐标贴图

    由于各版本threejs贴图的方式可能不太一样,所以研究了一下0.143.0版本是如何通过设置uv坐标来贴图的,上代码. const geometry = new THREE.BoxGeometry( ...

  2. 绘制圆柱 uv坐标贴图

    public class CreateMesh : MonoBehaviour {public int n = 6;public float r = 5;// Start is called befo ...

  3. 游戏渲染建模常用到的相关名词 AlvinCR个人理解-(烘焙、法线、LOD、UV坐标、各向异性)

    本文是UE4世界场景构建总览一文的名词解释部分 如有更新:https://alvincr.com/2021/01/ue4-1-world-creat-pandect/#Related_posts 1 ...

  4. UnityShader学习教程之<详解uv坐标,c#类似uv坐标的值以及贴图操作>

    基础篇(五) 一.uv坐标 工作的时候一直都听到同事们再说uv坐标,其实我们对这个词很熟悉,但是说到真正是什么,却发现自己了解的并不透彻,写一篇博客,梳理下基础,了解uv到底是干嘛的! 1.uv是什么 ...

  5. UE4官方文档学习笔记材质篇——UV坐标动画,凹凸贴图偏移

    一.UV坐标动画 1.含义 UV 坐标动画或 UV 平移的含义是,水平 (U) 和/或垂直 (V) 移动纹理的 UV 坐标,以产生复杂动画的错觉. 2."Panner(平移)"节点 ...

  6. 3dsmax怎么添加uv坐标_012:多层贴图UVWMAP(UV坐标)技术

    001 怎样建有弧度的窗框 002:欧式雕花和线脚的制作技巧 003:Blend贴图 004:V-Ray线框和晶格修改 005:如何在曲面上扣洞 006:如何进行地面拼花的制作 007:FFD的简单应 ...

  7. 深入理解 D3.js 可视化库之力导向图原理与实现

    大厂技术  坚持周更  精选好文 简介 D3.js[1] 是一个基于 web 标准的 JS 可视化库,它借助 SVG.Canvas 和 HTML 进行数据可视化.在数据可视化中,我们很多时候会使用图来 ...

  8. Unity shader图集Atlas下的UV坐标归一化转换

    unity中如果图片打入了图集中,在shader中取到的uv坐标默认是图集中的坐标,如果需要shader做一些类似流光的效果,需要转换成常用的0-1区间的归一化uv坐标,转换方法如下: 步骤一: C# ...

  9. 三维模型(X,Y,Z)坐标,UV坐标

    1.什么是UV? 对于三维模型,有两个最重要的坐标系统,一是顶点的位置(X,Y,Z)坐标,另一个就是UV坐标.什么是UV?简单的说,就是贴图影射到模型表面的依据. 完整的说,其实应该是UVW(因为XY ...

  10. 3d图形学中的uv坐标

    1.什么是uv? 所有的图象文件都是二维的一个平面.水平方向是U,垂直方向是V,通过这个平面的,二维的UV坐标系.我们可以定位图象上的任意一个象素.但是一个问题是如何把这个二维的平面贴到三维的NURB ...

最新文章

  1. 剑指offer_第4题_重建二叉树
  2. 可以通过无线充电的软脑植入物来控制大脑中的脑细胞
  3. 初步解读Golang中的接口相关编写方法
  4. Java项目中如何更优雅的处理空值?
  5. mysql数据库项目式教程答案_MySQL数据库项目式教程(高职)
  6. linux rz xshell
  7. 使用LoadRunner对Web Services进行调用--Add Service Call
  8. 树莓派做一个聊天机器人
  9. 工作总结13:vue官网封装组件
  10. php值对象模式场景,php设计模式介绍之值对象模式第1/5页
  11. PHP文字转语音合成网源码 百度API开发
  12. Numpy | Python列表与Numpy数组对比
  13. r语言数据变量分段_使用R语言实现数据分段
  14. opencv 计数后不动了 训练模型时_用OpenCV,深度学习和Python进行年龄识别
  15. 【第3篇】python爬虫实战-CSDN个人主页文章列表获取
  16. shell引入sql脚本报错_Oracle11g rac集群安装执行脚本报错的解决方法
  17. javascript的window.open()具体解释
  18. 基于FPGA的三人表决器设计
  19. 2021-2027全球与中国编码器附件市场现状及未来发展趋势
  20. 移动端页面底部导航被浏览器工具栏遮盖解决方法

热门文章

  1. 《C程序员:从校园到职场》出版预告(3):从“阳春白雪”到“下里巴人”
  2. OpenGl L13深度测试
  3. STEAM账号被盗(绑定QQ邮箱)的找回方法以及背后操作原理解析
  4. Android案例分享__HomePageA__仿'58到家/百度糯米/豆果美食/美团外卖/手机京东'首页
  5. 7个最佳小型企业电子邮件营销服务(2020)
  6. take their time用法
  7. Qt多线程之QtConcurrent
  8. 生成密钥、配送密钥和更新密钥
  9. uva1589 Xiangqi
  10. 命令提示符cmd以管理员身份运行的快捷键