2D 纹理(Texture2D)是最常用的美术资源,使用二维 UV 坐标进行采样。
在编辑器中可以方便地导入一张 2D 纹理,按照路径 资产面板 -> 右键上传 -> 选择 Texture2D -> 选择对应贴图 -> 2D 纹理资产创建完毕 操作即可。
同样的,在脚本中可以通过 ResourceManager 加载图片获取对应的 2D 纹理:
const textureResource = {
type: AssetType.Texture2D,
url: `图片url`,
};
engine.resourceManager
.load(textureResource, cubeTextureResource)
.then((resource) => {
// 引擎支持的2D纹理
const texture = resource;
// 接下来可以将纹理应用到材质上或者进行其他操作
});
方法 | 解释 |
---|---|
setImageSource | 设置纹理的图像数据源头 |
setPixelBuffer | 修改纹理对象的图像数据 |
getPixelBuffer | 获取纹理对象的图像数据 |
前面提到过,图片、canvas 画布、视频等跟图像相关的数据源都可以用来当作纹理。比如视频就可以通过 setImageSource 接口上传到纹理:
// 拿到视频标签,即 HTMLVideoElement
const video = document.getElementsByTagName("video")[0];
// 加载到纹理
texture.setImageSource(video);
setImageSource
只能同步那一帧的数据,但是视频每一帧都在变化,如果需要纹理同步变化,则要在脚本 onUpdate 钩子里面执行
对于视频这类需要频繁更新纹理内容的使用场景,创建纹理的时候需要关闭 mipmap 并设置纹理使用方式为 Dynamic,以获得更好的性能,示例代码如下:
纹理底层其实对应着每个像素的颜色值,即 RGBA 通道,我们可以手动填写这些颜色通道的颜色数值,然后通过 setPixelBuffer 接口传到纹理中:
const texture = new Texture2D(engine, 1, 1);
// 将该像素设置为红色,即 R 通道为 255。
const data = new Uint8Array([255, 0, 0, 255]);
texture.setPixelBuffer(data);
同样的,我们可以读取这些颜色通道的颜色数据:
const texture = new Texture2D(engine, width, height);
// 对纹理做了一系列处理
// ···
// 用来保存颜色信息的数组,它的大小和要读取的数据量相等
const data = new Uint8Array(width * height * 4);
texture.getPixelBuffer(0, 0, width, height, 0, data);
将纹理赋予材质球的相应属性,可以开启不同的渲染功能,如添加基础颜色纹理,可以决定模型的基本色调。在编辑器中,只需在对应属性选择相应纹理即可。
对应的,在脚本中,可以这样设置:
const material = new PBRMaterial(engine);
const texture = 生成纹理(); // 上文所示,不再赘述
material.baseTexture = texture;
为了解决带透明像素图片在 Alpha 值突变处出现黑边的问题,编辑器内置了色彩膨胀功能。该功能是通过将图片中所有透明像素的 RGB 值改写为与其最临近非完全透明像素的 RGB 值,达到去除图片黑边的效果。
选项 | 解释 |
---|---|
范围 Alpha Range | 阈值,透明像素 Alpha 值小于此阈值, RGB 值被修改 |
大小 Alpha Value | 透明像素填充后的 Alpha 值 |
项目发布文档中详细说明了纹理导出时的全局配置,若此处勾选 Overwrite 选项时,此资产导出时将遵循自定义配置将非全局配置。