以编程方式为模型生成简单的UV映射

And*_*res 7 uv-mapping three.js

来自这个问题,我正在尝试使用Three.js以编程方式为某些模型生成UV映射,我需要这个,因为我的模型也是以编程方式生成的,我需要对它们应用简单的纹理.我已经在这里阅读并成功生成了一些简单的3D文本的UV映射,但是当将相同的映射应用于更复杂的模型时,它就无法工作.

我试图应用的纹理是这样的:

在此输入图像描述

黑色背景在PNG图像中只是透明的.我需要将它应用到我的模型中,它只是一个闪光效果,所以我不关心模型中的确切位置,是否可以通过编程方式为这种情况创建一个简单的UV Map?

我正在使用链接问题中的代码,该代码适用于平面模型,但不适用于非平面模型:

assignUVs = function( geometry ){

    geometry.computeBoundingBox();

    var max     = geometry.boundingBox.max;
    var min     = geometry.boundingBox.min;

    var offset  = new THREE.Vector2(0 - min.x, 0 - min.y);
    var range   = new THREE.Vector2(max.x - min.x, max.y - min.y);

    geometry.faceVertexUvs[0] = [];
    var faces = geometry.faces;

    for (i = 0; i < geometry.faces.length ; i++) {

      var v1 = geometry.vertices[faces[i].a];
      var v2 = geometry.vertices[faces[i].b];
      var v3 = geometry.vertices[faces[i].c];

      geometry.faceVertexUvs[0].push([
        new THREE.Vector2( ( v1.x + offset.x ) / range.x , ( v1.y + offset.y ) / range.y ),
        new THREE.Vector2( ( v2.x + offset.x ) / range.x , ( v2.y + offset.y ) / range.y ),
        new THREE.Vector2( ( v3.x + offset.x ) / range.x , ( v3.y + offset.y ) / range.y )
      ]);

    }

    geometry.uvsNeedUpdate = true;
}
Run Code Online (Sandbox Code Playgroud)

gma*_*man 8

你需要更具体.在这里,我将以编程方式应用UV贴图

for (i = 0; i < geometry.faces.length ; i++) {
   geometry.faceVertexUvs[0].push([
     new THREE.Vector2( 0, 0 ),
     new THREE.Vector2( 0, 0 ),
     new THREE.Vector2( 0, 0 ),
   ]);
}
Run Code Online (Sandbox Code Playgroud)

快乐?

应用UV坐标有无限的方法.这个怎么样

for (i = 0; i < geometry.faces.length ; i++) {
   geometry.faceVertexUvs[0].push([
     new THREE.Vector2( Math.random(), Math.random() ),
     new THREE.Vector2( Math.random(), Math.random() ),
     new THREE.Vector2( Math.random(), Math.random() ),
   ]);
}
Run Code Online (Sandbox Code Playgroud)

没有正确的答案.只要你想做什么就取决于你.这有点像问我如何将铅笔应用到纸上.

很抱歉这么傻,只是指出这个问题在某种意义上是荒谬的.

无论如何,有一些常用的方法来应用纹理.

  • 球面映射

    想象一下,你的模型是半透明的,里面有一个由胶片制成的球体,球体内部是一个点光源,因此它可以从球体向各个方向投射(如电影放映机).因此,您可以计算出适合该情况的正确UV

    要在那里得到一个点,将你的点乘以球体的世界矩阵的倒数,然后将结果标准化.在那之后,仍然存在纹理本身如何映射到虚拟球体的问题,对于该虚拟球体,还有无数种方式.

    最简单的方法是我猜叫墨卡托投影,这是世界上大多数2d地图的工作方式.他们的问题是北极和南极都浪费了大量的空间.假设x,y,z是前一段中提到的归一化坐标

    U = Math.atan2(z, x) / Math.PI * 0.5 - 0.5;
    V = 0.5 - Math.asin(y) / Math.PI;
    
    Run Code Online (Sandbox Code Playgroud)
  • 投影映射

    这就像电影一样.您从一个点投射了一个2D图像.想象一下,你把电影放映机(或投影电视)指向了椅子.计算这些点

    计算这些点就像从几乎所有WebGL应用程序所做的3D数据计算2D图像一样.通常它们的顶点着色器中有一条线就像这样

    gl_Position = matrix * position;
    
    Run Code Online (Sandbox Code Playgroud)

    哪里matrix = worldViewProjection.然后你可以做

    clipSpace = gl_Position.xy / gl_Position.w
    
    Run Code Online (Sandbox Code Playgroud)

    您现在有x,y值从-1到+1.然后将它们转换为0到1的UV坐标

    uv = clipSpace * 0.5 + 0.5;
    
    Run Code Online (Sandbox Code Playgroud)

    当然,通常你会在初始化时用JavaScript计算UV坐标,但概念是相同的.

  • 平面映射

    这与投影映射几乎相同,只是想象投影仪而不是点,与您想要投影的尺寸相同.换句话说,通过投影映射,当您将模型移近投影仪时,投影的图像将变小但是平面则不会.

    在投影映射示例之后,这里唯一的区别是使用正交投影而不是透视投影.

  • 立方体映射?

    这是从6个方向有效的平面映射.由您来决定哪个UV坐标可以获得6个平面中的哪个.我猜大多数时候你都会采用三角形的法线看看它面对的是哪个平面,然后从那个平面做平面映射.

    实际上我可能会把我的条款搞砸了.您还可以在具有立方体纹理但需要U,V,W而不仅仅是U,V的情况下进行真正的立方体映射.除此之外,它与球体示例相同,只是您将标准化坐标直接用作U,V,W.

  • 圆柱映射

    这就像球形映射,只是假设有一个小圆柱投射到您的模型上.与球体不同,圆柱体具有方向,但基本上您可以将模型的点移动到圆柱体的方向,然后假设x,y,z现在相对于圆柱体(换句话说,您将它们乘以矩阵的逆矩阵)然后,表示圆柱的方向).

    U = Math.atan2(x, z) / Math.PI * 0.5 + 0.5
    V = y
    
    Run Code Online (Sandbox Code Playgroud)

2个解决方案

  1. 也许你想要环境映射?

    这是一个例子,这是另一个例子.

  2. 也许您应该考虑使用像Maya或Blender这样的建模软件包,它们内置了UV编辑器和UV投影仪.