跳到主要内容

图像元素

图像元素绘制一个矩形,可以显示纯色、纹理或精灵的一帧。面板、背景、图标、按钮和遮罩都属于图像元素。

颜色与不透明度​

color 对图像染色,与纹理颜色相乘,因此白色或灰度纹理可显示为任意颜色;没有纹理时则显示对应纯色矩形。opacity 在 0 到 1 之间控制不透明度。color 的 Alpha 会被忽略,请使用 opacity。

通过代码修改时,赋予新的 pc.Color:

panel.element.color = new pc.Color(0.23, 0.55, 1);
panel.element.opacity = 0.8;

元素颜色和不透明度不影响子项,详见组元素。

纹理​

为图像元素指定纹理资源即可显示图片:

const icon = new pc.Entity('icon');
icon.addComponent('element', {
type: pc.ELEMENTTYPE_IMAGE,
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5],
width: 128,
height: 128,
textureAsset: iconTexture.id
});
screen.addChild(icon);

iconTexture 是已添加到 app.assets 并加载的纹理资源。若使用 pc.Texture 对象,则设置 texture。

图像只能显示纹理或精灵中的一种。分配纹理资源会清除精灵资源,分配精灵则会清除纹理。

适配纹理​

默认将纹理拉伸到元素形状以填满区域。Fit Mode 可改为保持宽高比:

同一横向纹理在方形元素中的三种适配:Stretch 拉伸,Contain 完整容纳并留白,Cover 填满并溢出两侧

适配模式纹理行为
Stretch拉伸填满元素,默认模式
Contain缩放至完整容纳于元素内,在两侧或上下留白
Cover缩放至覆盖元素,多余部分溢出两侧或上下,可用遮罩裁切

Contain 和 Cover 根据元素轴心定位:居中轴心使图像居中,角落轴心使图像对齐相应角落。引擎中将 fitMode 设为 pc.FITMODE_STRETCH、pc.FITMODE_CONTAIN 或 pc.FITMODE_COVER;React 使用 fitMode prop,Web Components 使用 fit-mode 属性。

显示部分纹理​

rect 以纹理比例指定要绘制区域的 U、V、宽、高,从左下角 0, 0 开始。默认 0, 0, 1, 1 显示整张纹理:

// The top-left quarter of the texture
icon.element.rect = new pc.Vec4(0, 0.5, 0.5, 0.5);

如果同一纹理打包了很多图像,使用纹理图集和精灵更便于管理。

图像适配

精灵​

精灵是纹理图集中的一组帧,图集为纹理中的矩形区域命名。为图像元素分配精灵后,默认显示第一帧,可通过 spriteFrame 选择其他帧。精灵还提供不同渲染模式,在变化尺寸时保持边框清晰。

九宫格与平铺精灵​

Sliced 模式保持帧边框尺寸不变,将其余区域拉伸至元素尺寸;Tiled 则改为重复平铺。一张小图就能生成任意尺寸的面板、按钮和边框。边框定义详见九宫格。

相同面板的 Simple、Sliced 和 Tiled 模式:Simple 整体拉伸导致圆角模糊,Sliced 保持角落并拉伸中间,Tiled 保持角落并重复中间

宽为 b 像素的边框对应 b / pixelsPerUnit 个屏幕单位。Pixels Per Unit 默认取精灵设置,图像元素可单独覆盖。因此每单位 1 像素时,16 像素边框宽 16 单位。元素尺寸不足以容纳两侧边框时,边框会缩小。

// A texture atlas with one 64 x 64 frame, whose 16 pixel borders keep their size
const atlas = new pc.TextureAtlas();
atlas.texture = panelTexture.resource;
atlas.frames = {
panel: {
rect: new pc.Vec4(0, 0, 64, 64),
pivot: new pc.Vec2(0.5, 0.5),
border: new pc.Vec4(16, 16, 16, 16)
}
};
const sprite = new pc.Sprite(app.graphicsDevice, {
atlas,
frameKeys: ['panel'],
pixelsPerUnit: 1,
renderMode: pc.SPRITE_RENDERMODE_SLICED
});

const dialog = new pc.Entity('dialog');
dialog.addComponent('element', {
type: pc.ELEMENTTYPE_IMAGE,
anchor: [0.5, 0.5, 0.5, 0.5],
pivot: [0.5, 0.5],
width: 400,
height: 240,
sprite
});
screen.addChild(dialog);

帧的 rect 用纹理像素表示 X、Y、宽、高,以左下角为原点;border 顺序为左、下、右、上。使用精灵资源时,设置 spriteAsset 而非 sprite。

面板

将三维内容渲染为图像​

摄像机可以渲染到纹理,再由图像元素显示,适合角色头像、物品预览和小地图。为该摄像机分配独立图层,只包含它应看到的内容,并在主摄像机之前渲染:

// The texture to render into
const previewTexture = new pc.Texture(app.graphicsDevice, {
width: 512,
height: 512,
format: pc.PIXELFORMAT_SRGBA8,
mipmaps: false
});
const renderTarget = new pc.RenderTarget({
colorBuffer: previewTexture,
depth: true,
origin: pc.RENDERTARGET_ORIGIN_TOP
});

// A layer for what the preview camera sees, which the main camera does not render
const previewLayer = new pc.Layer({ name: 'Preview' });
app.scene.layers.push(previewLayer);

const previewCamera = new pc.Entity('preview camera');
previewCamera.addComponent('camera', {
layers: [previewLayer.id],
renderTarget,
priority: -1,
clearColor: new pc.Color(0, 0, 0, 0)
});
previewCamera.setPosition(0, 0.5, 3);
previewCamera.lookAt(model.getPosition());
app.root.addChild(previewCamera);

// Put the model on the preview layer, and show the texture in the interface
model.render.layers = [previewLayer.id];
portrait.element.texture = previewTexture;

摄像机 priority 为 -1,先于默认优先级 0 的主摄像机渲染,确保绘制界面时纹理已就绪。透明清屏颜色使图像背景透明。应保留 sRGB 格式 pc.PIXELFORMAT_SRGBA8;使用 pc.PIXELFORMAT_RGBA8 会使图像过亮。将 origin 设为 pc.RENDERTARGET_ORIGIN_TOP,以图像纹理常用的首行在上的顺序存储,确保 WebGL2 和 WebGPU 均正向显示;否则 WebGL2 会倒置。origin 从引擎 2.22 起可用。

渲染到图像

自定义材质​

默认材质会使用图像元素的颜色、不透明度和纹理。需要渐变或着色器效果时,可将自定义材质赋给 material,或编辑器中的 Material。它会取代默认材质,包括默认材质处理元素颜色、不透明度及纹理的逻辑。

UI 图层仅绘制透明材质,因此材质必须启用混合才能显示:

const material = new pc.StandardMaterial();
material.useLighting = false;
material.emissive = new pc.Color(1, 0.55, 0.2);
material.blendType = pc.BLEND_NORMAL;
material.depthWrite = false;
material.update();

panel.element.material = material;

新材质默认不混合,这样的材质不会在 UI 图层绘制。屏幕空间材质应关闭光照,因为场景灯光对这种界面通常没有实际意义。

自定义着色器

避免暗边​

圆形图标等带透明区域的纹理,边缘可能出现细暗边或亮边。透明像素仍保留通常为黑色或白色的颜色,缩放时滤波会将这些颜色混入可见边缘。

应在图片中修复:用最近可见像素的颜色填充透明像素的 RGB,保持 Alpha 不变。很多图片编辑器和纹理工具提供此功能,常称为 Alpha 扩边、纹理填充或膨胀。

另请参阅​