three.js中使用压缩纹理实例教程

在three.js中使用压缩纹理可以显著提高 webGL 应用程序的性能和加载速度。在这里,我们将介绍如何使用基于glTF格式的压缩纹理工作流程。

一、创建纹理

首先,我们需要创建一个纹理图像。可以使用Photoshop 或其他类似软件创建一个512 x 512像素的PNG图片。然后,我们将其转换为DDS格式。DDS是DirectDraw Surface的简称,是一种常用的GPU纹理格式,特别适合用于3D游戏中。

  1. 下载并安装 NVIDIA Texture Tools 工具集,可以从 NVIDIA Developer 网站上找到。
  2. 打开命令行,转到所下载的 NVIDIA Texture Tools 的安装目录,并输入以下命令:
nvdxt.exe -file input.png -output output.dds

其中 input.png 是您要转换的 PNG 文件的名称,output.dds 是转换后的DDS文件的名称。

二、导入纹理

接下来,需要用 GLTFLoader 导入 DDS 格式的纹理文件。首先,使用GLTFExporter将模型导出为 glTF 格式。然后,打开 glTF 格式的文件,查找到使用的纹理贴图,并将其路径更改为 DDS 文件路径。

{
  "images": [
    {
      "uri": "texture.dds"
    }
  ],
  "materials": [
    {
      "pbrMetallicRoughness": {
        "baseColorTexture": {
          "index": 0
        }
      }
    }
  ]
}

三、压缩纹理

现在,我们需要将DDS文件压缩为更适合 WebGL 的格式。通常使用基于 BC7 格式的压缩方法,它可以减小纹理贴图的大小并提高渲染性能。

  1. 下载并安装 Microsoft DirectX Texture Tool 工具集,可以从微软官网上找到。
  2. 打开命令行,转到所下载的 DirectX Texture Tool 的安装目录,并输入以下命令:
nvcompress.exe -bc7 input.dds output.dds

其中 input.dds 是您要压缩的 DDS 文件的名称,output.dds 是压缩后的文件的名称。

四、创建压缩纹理

最后,我们需要在Three.js中加载并使用压缩纹理。为此,可以使用THREE.CompressedTexture类和THREE. DXT5_SRGB_Format(或其他BC7格式)来创建一个新的压缩纹理对象。

var loader = new THREE.CompressedTextureLoader();
loader.load('compressed-texture.dds', function(texture) {
    texture.format = THREE.DXT5_SRGB_Format;
    mesh.material.map = texture; 
});

在上面的代码中,我们首先使用CompressedTextureLoader加载DDS文件。然后,我们将纹理格式设置为 DXT5_SRGB_Format,并将其应用于渲染的模型材质。

现在,您已经了解了基本的glTF格式压缩纹理工作流程。通过使用压缩纹理,可以减小贴图大小,并在渲染3D场景时提高性能和加载速度。

我目前在手机上使用glTFs处理jpg和png图像的工作流程中遇到了GPU内存问题。遗憾的是,我找不到一个好的设置来避免这种情况。
我想下一步是要么使用GPU压缩的纹理格式,比如basis,要么降低纹理分辨率。遗憾的是,我还没有找到一个好的工作流程来创建和链接优化的资产。
我的问题是:n1. 基本纹理格式是否已经是所有平台的可行格式?n2. 是否可以链接glTF文件中的基本纹理?n3. 您使用什么工具创建优化纹理(使用mipmap/纹理地图集)?n4. 是否可以检查可用的GPU内存以加载移动设备的低分辨率纹理?n5. 是否有在glTFs中包含基础纹理的ETA?
现在,我们正在使用Blender导出glTF文件,它只支持导出JPEG和PNG。
我很想听听您的工作流程如何优化web的纹理和模型!
由donmccurdy在12日邮报中解决很抱歉耽搁了您的时间。如果您>
我们测试了基本纹理,并且对文件大小的减少非常满意。到目前为止,我在移动设备上遇到了一些8k纹理问题(仅渲染黑色),但我不确定原因是什么。
要回答您的一些问题:JohannesDeml:
是否可以链接glTF文件中的基本纹理?
我使用提供的工具将blender输出纹理从png转换为basis,并手动替换gltf中的纹理槽(编辑模型文件中的代码)。JohannesDeml:
您使用哪些工具来创建优化纹理(使用mipmap/纹理图谱)?nbasis universal团队正式提供的转换器。为纹理创建mipmap会显著增加转换时间和文件大小,但我看不出在性能或视觉表现上有什么区别。
再加上一些数字:在一种情况下,4k纹理上的文件大小从13.9 MB JPG增加到7.0 MB,在另一种情况下,如果没有mipmap,文件大小从7.4 MB增加到0.53 MB,而且很少失去细节。
嗨@weiserhei,
非常感谢您的见解!因此,我猜您正在使用basis live演示示例中的自定义GLTFLoader(https://basis-universal-webgl.now.sh/gltf/106)?
据我所知,从长远来看,glTF中的基本文件将有一个ktx2包装器(https://www.khronos.org/assets/uploads/developers/library/2019-siggraph/glTF-Ecosystem-Forum-siggraph_Aug19.pdf29). 值得等待吗?weiserhei:
我使用提供的工具将blender输出纹理从png转换为basis,并手动替换gltf中的纹理槽(编辑模型文件中的代码)。
我明白了,所以我可能需要构建一个小型自动化工具。weiserhei:
加入一些数字:在一种情况下,4k纹理上的文件大小从13.9 MB JPG变为7.0 MB,而在另一种情况下,在没有mipmap和极少细节损失的情况下,文件大小从7.4 MB变为0.53 MB。
听起来真不错!非常感谢现实世界的dara比较!n@weiserhei:我修改了gltf加载程序,以支持在中这样做的基本纹理https://github.com/binomiaalllc/basis\\u universal/tree/master/webgl/gltf60.
我还得到了提供的模型。不幸的是,当我尝试将来自ThreeJS的PavingStone示例放在一个简单的立方体上时,立方体仍然是黑色的。这是我正在使用的文件:image_template.zip(526.9 KB)
我编辑了纹理以指向基本纹理:n“纹理”:[n{n“源”:0n}n,
“图像”:[n{n“mimeType”:“图像/基础”,“名称”:“d_图像_模板”,“uri”:铺路石基础“n}n],
“使用的扩展”:[n“谷歌纹理基础”
,n“所需扩展”:[n“谷歌纹理基础”

知道我缺少什么吗?
您的images-零件看起来正确。请确保包含basis所需的必要的库文件,并且已加载它们。
我已将您的文件导入到我的项目中,并且没有修改任何内容,结果如下:grafik.png743×773 180 KB
非常感谢您的测试。这很有趣。
我试着进一步挖掘,调用BasisTextureLoader并加载纹理的逻辑似乎是正确的,简直无法渲染。
我做了一个小复制:https://deml.io/three/examples/webgl\\u loader\\u gltf\\u basis.html67ngrafik1130×937 372 KB
前面的框是我在这里上传的,它的基本纹理似乎在贴图属性中,但没有渲染它。背面的立方体是生成的,纹理是手动为材质设置的,这一块工作正常。nForked repo 2:nglTF Loader 17 | Html复制文件14
似乎您没有使用扩展名。你怎么样是否更改加载程序以支持基本纹理?
我不记得换过装载机,这个零件应该已经用完了。我跟随了这篇关于媒体的文章:在中使用基本纹理Three.js. Basis Universal是一种新的图像格式…|由Ada Rose Cannon |三星互联网开发商| Medium 60编辑:我必须检查源代码管理以实际验证我的声明,它们只是来自我的内存
此外,我还使用DRACO压缩和转换了我的gltf Basis模型,但这不会影响您的多维数据集。
我不使用扩展,我的模型中缺少这些行-您介意分享一些有关这方面的信息吗?
啊,我刚才被那篇文章绊倒了。据我所知,这只是加载纹理本身(就像我集成在复制中的BasistTexture加载程序示例一样,它实际上是有效的)。我想我的问题是:你是如何连接BasistExtralLoader和你的GLTFLoader的?
我想使用扩展名“GOOGLE\\u texture\\u basis”,他们在示例中也使用了该扩展名。它很可能会被取代,但据我所知,这可能是目前的标准。我的想法是extesio
可以指示应该使用哪个textureloader。问题是,我不知道哪一步不起作用,因为至少加载了基本纹理,并且材质的贴图通道中有一些纹理,但它不会显示在渲染器中。JohannesDeml:
您是如何将BasistTextureLoader与GLTFLoader连接起来的?
启用基本纹理的链接通过加载管理器进行。我想这部分代码应该可以完成这项工作,但为了简单起见,它只是我项目的一个摘录。nnew THREE.Sprite文件。如果您想使用Basis,现在我将创建console.log()文件,并从您的模型中分别加载它们。
不久之后,将210文件嵌入raycaster.ray.at(210, marker.position)和.intersectObject()文件是可能的,但现在还没有。这个three.js其中一部分正在开发中https://github.com/mrdoob/three.js/pull/1849040,以及glTF和KTX软件存储库中的各种任务。
感谢您的解决方案!这对我有用!
嗨,
感谢您提供了这条非常有用的线索。一路上我学到了很多。我正在将.basis纹理添加到gltf中。(我正在手动添加它们),然后根据上面的代码片段加载gltf。它似乎可以正常工作,这意味着模型已加载,纹理似乎也已加载。但是,我得到了以下错误:nWebGL:drawerelements:绑定到纹理单元1的纹理不可渲染。它可能是非2次幂,并且具有不兼容的纹理过滤,或者不是“纹理完整”,或者它是具有线性过滤的浮点/半浮点类型,并且没有启用相关的浮点/半浮点线性扩展。
现在纹理肯定是2次幂。我还看到这些错误
[警告]3.webgl渲染器:WEBGL\\u compressed\\u texture\\u astc扩展不受支持。n[警告]3.webgl渲染器:EXT\\u texture\\u compression\\u bptc扩展不受支持。n[警告]3.webgl渲染器:WEBGL\\u compressed\\u texture\\u etc1扩展不受支持。n[警告]3.webgl渲染器: 不支持WEBGL\\u压缩\\u纹理\\u pvrtc扩展。n[警告]3.webgl渲染器:WEBKIT\\u WEBGL\\u compressed\\u texture\\u pvrtc扩展不受支持。
这是用于Chrome 81.0和Safari 13.1的。
我的目标是最终在桌面和移动设备的glTF中使用压缩纹理。
我用命令行工具let intersects;. . .raycaster.setFromCamera(mouse, == 0) return;// you already created a markermarker.position.copy(intersects[0].point);
非常感谢您的提示。n***7***缺失。将它添加到basis命令行修复了它
这里的一些信息对于正确加载gLTF+basis非常有用。如果只有一种纹理,效果很好。当我尝试在gLTF中为3个不同网格创建3个不同纹理/图像的模型时,它似乎只对所有网格应用了第一个纹理/图像。我尝试更改图像数组中的名称和顺序,并在许多其他地方更改位置或索引。似乎没有任何内容会更改应用于哪个网格的纹理。有什么想法吗?
将有一个新的工作流可用于three.jsr119。它仍然是实验性的(glTF的基础扩展尚未完成,事情可能会改变),但它可能比本线程前面描述的旧工作流更有用。请尝试:n- 使用glTF Transform CLI 40使用***8***或***9***压缩。n- 在中测试https://sandbox.js.com/9或https://gltf-viewer-experimental.donmccurdy.com/15.
请注意,Basis UASTC的***10***选项在我的查看器中还不受支持,我不确定该支持是否会进入r119。公共关系是https://github.com/mrdoob/three.js/pull/1993218r119发布后,我将进行更新https://gltf-viewer.donmccurdy.com/8(以及上述实验版本)
Compressed Texture Workflow (glTF|Basis)n

three.js[已解决]正交摄影机的变换控件:gizmos缩放问题

您好,我正在使用带轨道控制的正交摄影机。我注意到当缩放照相机变焦不改变相机的位置(如透视相机)。首先,我想知道为什么这两个相机的实现方式不同?第二,我也在使用TransformControls,对于透视摄影机,更新功能上的小控件的重新缩放在这个等式中非常有效>但是使用OrbitControls更改缩放而不是正交摄影机的位置时,它没有正常工作。我试着像这样在等式中添加缩放,但没有得到任何好的结果>我应该以不同的方式包括它吗?我应该使用其他控件吗?谢谢大家的帮助!NaDaMa:首先,我很想了解为什么这两个摄像头...

日期:2021-12-11 08:00:01 浏览:1611

three.js多次渲染同一模型(obj模型),FPS要低得多

我试图在程序中渲染150个相同的树模型,但FPS突然从60下降到30+。你能告诉我什么是最好的解决办法吗?非常感谢。和平与爱。skr有两种典型的方法可以解决这个性能问题(太多的绘制调用):- 使用实例化渲染- 将所有几何体合并为一个几何体(因此只有一个网格)...

日期:2021-12-11 08:00:02 浏览:1592

three.js可缩放场景背景

three.js大家好,我有一个场景,由一个物体(反射雕像)组成,保持在一个漂亮背景的中心。我一直在使用威尼斯日落矩形hdr地图作为我的场景背景它既可以作为环境地图,也可以作为背景我看到背景不会与场景中渲染的网格一起缩放。这给人一种场景完全是假的感觉。i、 e状态向上/向下缩放,但背景不缩放。目前,我已经禁用了放大/缩小功能,这样用户就不会感到害怕。我的问题是:1. 当轨道控制放大/缩小时,我是否需要在此处使用一些着色器魔法来放大或缩小场景背景,以便看起来场景中的所有对象都在均匀缩放?或者这根本不可能做到?...

日期:2021-12-11 09:00:02 浏览:1186

three.js移动导入的Gltf模型

three.js我导入了我的gltf模型并将其添加到场景中,但现在如果我尝试移动它,它将不会=新建三、几何();var=混音器( 模型动画[0]>如何移动模式?Prakar_Srivastava:var>3D对象不能是Geometry或BufferGeometry类型。它应该是Object3D或类似Mesh、Points或Line的派生类的实例。在您的情况下,我只是这样声明变量:var mode;在动画循环中,执行以下操作:如果(mod!==未定义)>还请记住,基本3D场景的重要部分在代码片段中丢失(例如相...

日期:2021-12-11 10:00:01 浏览:1017

three.js平面明暗处理的问题

three.js嗨!我在项目中使用节点材质。我在模型渲染方面有问题。它看起来像是真实的平面阴影。如何平滑多边形?也有点像低分辨率阴影纹理贴图的自阴影。可能不是,但可能是。@Arkadiy\\u Vinkovskiy您需要在您的帖子中添加更多细节。屏幕截图不足以说明这里发生了什么。始终包括引起问题的代码,如果您使用的是模型,也要包括这些代码。更好的是,使用codepe制作一个工作示例...

日期:2021-12-11 10:00:02 浏览:930

three.js如何渲染立方体材质?

您好,直到昨天,我才相信Object3D是一组网格,而网格是一组几何体+材质,每个对象只有一个对象。我发现了立方体材质的结构,因此object3D的网格包含1个几何体(boxGeometry)和6个材质!所以问题是,这种网格的渲染效果如何?有关于它的文件吗?(这是为了提高我对three.js)非常感谢还有其他问题,与我的上一个帖子相关,如果一个网格中可能有多个材质,如何设置CustomDistanceMaterial以考虑所有材质的所有贴图?elysium11:所以问题是,渲染如何在这种类型的网格上工作?您...

日期:2021-12-11 11:00:03 浏览:797

three.js如何创建要在网格中拟合的线段

three.js伙计们,我想帮忙,假设我有一个这样的网格图像718×729 1.25 KB我想在网格面内创建线段,也就是说,我想将网格转换成这样的线图像710×828 740字节有人能帮忙吗???...

日期:2021-12-11 12:00:01 浏览:843

three.jsGLTFLoader.js这是我的登记簿错误

three.js每当我试着做决定的时候3.GLTFLoader对象我收到此错误代码:“未捕获类型错误:这是我的登记簿不是一个函数“我需要帮助!由Penta#u Trax在post#5中解决我最终发现我一直在使用错误的文件,当你需要使用jsm/example时,我使用的是js/example。其他东西也是个问题。但这是问题的基础。你能给我们看看你的代码吗?通常,如果你使用的是import语句,GLTFLoader不需要在前面加三个字符。好的,所以在这之前,我刚刚关注了这个视频,因为它是去年发布的。但是现在我试...

日期:2021-12-11 12:00:02 浏览:1008

three.js使用threejs的光流

嘿,我需要通过我的屏幕显示一束移动的光束。我不想使用任何模型或动画。我想知道我是否可以单独使用threejs来实现这一点。我也应该能够控制其运动的颜色强度和路径。嗨!也许这会有帮助:GitHub-jeromeetienne/三倍体积聚光灯: three.js扩展以提供体积聚光灯13,用于可视化光锥。您可以使用THREE.Curve()设置其路径。控制颜色强度,可能取决于曲线上的位置,也可以使用tween.js或者GSAP用于复杂的动画。创造力取决于您这是您想要的吗?https://threejs.org/e...

日期:2021-12-11 13:00:01 浏览:1222

three.js使用光线投射动态绘制多边形

我要画多边形three.js具有交点。为此,我使用下面的函数。首先,我使用光线投射器在第一个交点的第一个点添加球体。每次单击后,在交点处创建新球体,并在该交点和上一点之间创建线。现在,我希望在第一次单击时关闭多边形指向或单击该点周围。如何实现此目标。raycaster params是否与网格一起工作以检测鼠标位置周围的网格?function checkIntersectionclick() = raycaster.intersectObjects(addedObject, true);if (interse...

日期:2021-12-11 13:00:02 浏览:802