这可能是一个初学者的常见问题:我们应该使用什么类型的图像来正确地在 Three.js 中对球体进行纹理处理?我敢打赌,我们一开始都尝试过将可能是一朵花或一个人的方形图像发送到 3D 球体上,然后“希望”它能正常工作ὠ2。当然,我们发现纹理全部拉伸且丑陋……
既然我知道了一种为球体创建纹理使其看起来不变形的方法,它就不是很简单了。所以我认为很高兴与所有 Three.js 开发者/未来开发者分享我是如何做到的。如果您有其他或更好的方法,请发表评论!
重述问题
让我们从一个简单的场景开始:您想要将高尔夫球纹理应用于SphereGeometry. 如果你在谷歌上搜索“高尔夫球纹理”并选择一个将它“覆盖”到你的球体上,你很可能会得到一个扭曲的高尔夫球:
![](https://i-blog.csdnimg.cn/blog_migrate/3db139600c09bf02d705ca0de2ecea3f.png)
左图:用作球体纹理的图像。右图:注意图像在两极处是如何真正扭曲的
那么如何避免失真不均匀的问题,尤其是在两极?
等距柱状是你的朋友
如果您知道“Equirectangular”的含义以及它如何在纹理球体上工作,则可以跳过本节并阅读下一节,了解如何使用 Blender 生成等距圆柱纹理。
如果您遇到过threejs.org 上托管的示例场景之一,您可能已经掌握了这个问题的关键。
![](https://i-blog.csdnimg.cn/blog_migrate/fd05886bd582f5bac821b43afdafc49a.png)
该示例在左下角展示了一个外观完美的高尔夫球。
虽然它没有直接将颜色或“反照率”纹理应用到球体上,因为它使用了高尔夫球的法线贴图,但在这种情况下它基本上是相同的想法。
请注意这张法线贴图图像与我们之前随机选择的“谷歌图像”有何不同:
![](https://i-blog.csdnimg.cn/blog_migrate/792c0f7b887f8d561625772e59f8804b.png)
https://github.com/mrdoob/three.js/blob/master/examples/textures/golfball.jpg
这些孔在中心相对均匀,但在接近顶部和底部时开始水平伸展。这称为“等距柱状图像”。这个术语来自我们如何将地球地图投影到 2:1 图像上,请参阅https://en.wikipedia.org/wiki/Equirectangular_projection以获得更深入的解释。
让我首先简要概述一下 Three.js 如何将纹理映射到SphereGeometry.
Three.js 为工厂几何体创建一个默认的 UV 贴图。让我们尝试将 UV 测试纹理应用到香草上来SphereGeometry解决这个问题。最初 UV 测试纹理看起来像这样:
![](https://i-blog.csdnimg.cn/blog_migrate/bd469f47e5c441e13a138992cfea6f71.png)
U值从左到右递增,V值从上到下递增
左上角有一个 UV 坐标 (0,0),而右下角有一个 UV 坐标 (1,1)。
下面是带有此 UV 测试纹理的球体的顶部和底部。
![](https://i-blog.csdnimg.cn/blog_migrate/cf2ae65943f22df8942738691087eb2a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/30ce9eaf9377b192ea95505235ed439c.png)
左:球体的“北极”,右:球体的“南极”
您可以看到球体顶部的 V 值为 0,而球体底部的 V 值为 1。U 值水平延伸,但由于球体是圆形的,因此 UV 贴图的右边缘缝合到其左边缘,这就是为什么您可以在上图中看到 U 值从 0.9 变回 0.0。
因此,无论您使用此方法将图像应用为球体纹理,图像的左上角都将分配 UV (0,0),而图像的右下角将分配 UV (1,1)。
当图像包裹在球体上时,像素将在两极处挤在一起。这就是为什么你会看到靠近两极的高尔夫球颠簸更宽;因为在挤压之后,这些颠簸会在最终结果中很好地出现,正如您在 Three.js 示例中看到的那样。
因此,当您寻找可行的球体纹理时,请添加关键字“equirectangular”!
使用 Blender 生成等距柱状纹理
好了,本文的重头戏来了。
如果您无法在网上找到合适的等距柱状图像,或者您实际上需要为您的球体定制图案怎么办?好吧,你可以在 Blender 中做到这一点!
我们将使用自定义材质在 Blender 中创建一个球体。然后我们将使用球体的默认 UV 贴图将该材质烘焙成等距柱状图像。让我们开始吧!
在一个全新的 Blender 项目中,删除默认立方体,并添加一个 UV 球体:
![](https://i-blog.csdnimg.cn/blog_migrate/47c5bbedccf359c835a1bd50b875311d.png)
SHIFT-A 打开添加菜单
添加球体后,展开左下角的调整菜单,通过 200 段和 100 环使球体更高分辨率:
![](https://i-blog.csdnimg.cn/blog_migrate/99b285a8dd5a7afcb57cb60f0d1c56e5.png)
一个更高分辨率的球体通常可以帮助我们获得更平滑的生成纹理。
接下来转到“着色”选项卡,并添加一个新材料:
![](https://i-blog.csdnimg.cn/blog_migrate/830c085e7b76d4a23b4ff12c04906809.png)
您可以将材料名称保留为 Material.001 不加编辑
然后在下面的区域中,您会看到添加的默认节点(“Principled BSDF”、“Material Output”)。再次按下 SHIFT-A 调出添加菜单并搜索“噪声纹理”,这是您可以在 Blender 中使用的众多纹理节点之一。
![](https://i-blog.csdnimg.cn/blog_migrate/398412abb1967425c7e8d4815f79d951.png)
将噪声纹理的“颜色”出口连接到 BSDF 节点的“基础颜色”入口。然后你应该会看到球体上出现了一些彩色的噪声图案!
![](https://i-blog.csdnimg.cn/blog_migrate/3fc6737a7b3726dbad12b2db89b0bfb4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9ee6a4aed017bbda4f7211a89b1ff664.png)
你可以用很多不同的方式制作球体纹理,看看这个很酷的 YouTube 视频,你就会明白你在调整这些纹理时有多大的自由度。让我们假设这个简单的噪声纹理是我们现在想要应用到 Three.js 球体中的纹理。对于下一部分,我们将把这个纹理“烘焙”成一个可保存的图像。
在现有节点旁边的一些空白区域,再次按住 SHIFT-A 添加“图像纹理”节点:
![](https://i-blog.csdnimg.cn/blog_migrate/59080f4d959367f6fe0cff00de545ca0.png)
这个图像纹理节点不需要连接到任何东西
单击 Image Texture 节点中的 New 并将其命名为有意义的名称。
![](https://i-blog.csdnimg.cn/blog_migrate/6cf7b329d01cd52fd7ddbaee83cc112c.png)
由于我们正在创建 2:1 等距柱状图像,因此我们将宽度提高到 2048 像素。按确定。
然后在右侧面板上,转到“Camera”图标选项卡(即“RenderProperties”),选择“Cycles”作为渲染引擎,因为这是人们通常用于纹理烘焙的引擎。
![](https://i-blog.csdnimg.cn/blog_migrate/08c657504e36c41bf5c096aaec1f02ef.png)
然后向下滚动并展开“烘焙”部分以应用以下设置:
Bake Type:“Diffuse”,这意味着我们只是将颜色作为图像纹理进行烘焙
贡献:只勾选“颜色”,因为我们不需要为输出纹理贡献光照或其他东西
目标:选择“Image Textures”,因为我们要将烘焙输出存储到我们之前在 Image Texture 节点创建的图像实例。
![](https://i-blog.csdnimg.cn/blog_migrate/071a26b00454202038dc46a5bd098f32.png)
在你点击这里的“烘焙”按钮之前,有一个非常重要的步骤你不能错过!
您需要同时选择场景中的 Sphere 对象和 Image Texture 节点。只需单击一次即可将它们分别选中。
![](https://i-blog.csdnimg.cn/blog_migrate/b7f68a02d3bf6f232bd49fedad97250a.png)
请注意,球体以黄色突出显示,图像纹理节点以白色突出显示,这意味着它们已被选中
选择球体和图像纹理节点后,您可以安全地单击侧面板中的“烘焙”。这可能需要一些时间,可能不到一分钟。
为什么要主动选择Image Texture节点呢?因为Blender 文档中提到了这一点:
烘焙需要网格具有 UV 贴图,以及带有要烘焙到的图像的颜色属性或图像纹理节点。活动 图像纹理节点或颜色属性用作烘焙目标。
Blender 场景中的球体已经带有默认 UV 贴图,因此第一个要求已经完成。
底部的进度条完成后,转到顶部的“渲染”选项卡,然后在下拉列表中选择噪声纹理图像。瞧!显示的图像是渲染结果:
![](https://i-blog.csdnimg.cn/blog_migrate/c4022cd6047630dbc34f1ffb5541f4e4.png)
现在您可以将此结果保存为计算机某处的图像:
![](https://i-blog.csdnimg.cn/blog_migrate/1d45d28b3b81d02b680b774b326df163.png)
将此纹理应用于 Three.js SphereGeometry 将为您提供一个未扭曲的球体:
![](https://i-blog.csdnimg.cn/blog_migrate/c9de1e5db346b6ab46694235da225a33.png)
好吧……这看起来不够有说服力。让我们在“Minkowski”模式下使用“Voronoi Texture”节点做另一个例子:
![](https://i-blog.csdnimg.cn/blog_migrate/8df0c88a97313d1c3819823a53e5e235.png)
来自 Blender 的渲染图像纹理
以及应用于 Three.js 球体时的外观:
![](https://i-blog.csdnimg.cn/blog_migrate/697d1646e7594ebbfce0ff39c5d29ded.png)