3.8.7 UIRender组装数据接口postUpdateAssembler问题
Cocos Creator version
3.8.7
System information
MacOS google 浏览器
Issue description
项目中很多自定义组件使用了UIRender postUpdateAssembler 方法,进行顶点uv、颜色、坐标的定义,3.8.6 版本各组件功能正常,升级到3.8.7后,postUpdateAssembler 引擎不再触发调用,看了引擎源码修改,和 batcher-2d.ts加入到新功能Sorting2d有一定关系,尝试引擎定扩展定制修改,会有其他渲染问题,目前项目升级卡在这个问题上,麻烦帮忙看一下,有什么解决方案
Relevant error log output
无
Steps to reproduce
无
Minimal reproduction project
enum ColorMode { /** * 双颜色 / Double = 0, /* * 左上、右上、左下、右下四颜色 */ Four = 1, }
@ccclass('CCGradientRender') @executeInEditMode @requireComponent(UIRenderer) @menu('weg/render/CCGradientRender(颜色渐变渲染器,支持Label、Sprite等继承于UIRenderer的对象)') export class CCGradientRender extends Component { @property private _colorMode: ColorMode = ColorMode.Double; @property({ type: Enum(ColorMode), tooltip: DEV && '颜色模式,双颜色 | 四颜色', }) private get colorMode() { return this._colorMode; } private set colorMode(value: ColorMode) { this._colorMode = value; this.updateColor(); }
@property
private _colorT: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '⬆ 顶部颜色',
visible: function () {
return this.colorMode == ColorMode.Double;
},
})
private get colorT() {
return this._colorT;
}
private set colorT(value: Color) {
this._colorT = value;
this.updateColor();
}
@property
private _colorB: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '⬇ 底部颜色',
visible: function () {
return this.colorMode == ColorMode.Double;
},
})
private get colorB() {
return this._colorB;
}
private set colorB(value: Color) {
this._colorB = value;
this.updateColor();
}
@property
private _colorLT: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '↖ 左上',
visible: function () {
return this.colorMode == ColorMode.Four;
},
})
private get colorLT() {
return this._colorLT;
}
private set colorLT(value: Color) {
this._colorLT = value;
this.updateColor();
}
@property
private _colorRT: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '↗ 右上',
visible: function () {
return this.colorMode == ColorMode.Four;
},
})
private get colorRT() {
return this._colorRT;
}
private set colorRT(value: Color) {
this._colorRT = value;
this.updateColor();
}
@property
private _colorLB: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '↙ 左下',
visible: function () {
return this.colorMode == ColorMode.Four;
},
})
private get colorLB() {
return this._colorLB;
}
private set colorLB(value: Color) {
this._colorLB = value;
this.updateColor();
}
@property
private _colorRB: Color = new Color(255, 255, 255, 255);
@property({
displayName: DEV && '↘ 右下',
visible: function () {
return this.colorMode == ColorMode.Four;
},
})
private get colorRB() {
return this._colorRB;
}
private set colorRB(value: Color) {
this._colorRB = value;
this.updateColor();
}
private ur: UIRenderer = null;
protected onLoad() {
this.ur = this.node.getComponent(UIRenderer);
if (!(this.ur instanceof Sprite || this.ur instanceof Label)) {
weg.warn('CCGradientRender onLoad, Label or Sprite only');
this.destroy();
return;
}
}
protected onEnable() {
// 启用顶点透明度(否则透明度只受color.a影响)
this.ur['_useVertexOpacity'] = true;
const postUpdateAssembler = this.ur.postUpdateAssembler;
this.ur.postUpdateAssembler = () => {
this.updateColor();
postUpdateAssembler.apply(this.ur);
};
}
protected onDisable() {
if (!this.ur['_renderData']) {
return;
}
const renderData = this.ur['_renderData'];
let vb = renderData.chunk.vb;
let color = this.ur.color;
// 动态计算顶点布局,适配CCGray等组件修改的顶点格式
const stride = renderData.floatStride || 9; // 默认9个float,CCGray会变为14个
const colorOffset = stride === 14 ? 9 : 5; // CCGray时写入a_gray_color(偏移9),否则写入ATTR_COLOR(偏移5)
// 消除渐变效果,恢复原始颜色
const colorR = color.r / 255;
const colorG = color.g / 255;
const colorB = color.b / 255;
const colorA = color.a / 255;
// 所有顶点设置统一颜色
let offset = colorOffset;
for (let i = 0; i < renderData['_vc']; i++) {
vb[offset] = colorR;
vb[offset + 1] = colorG;
vb[offset + 2] = colorB;
vb[offset + 3] = colorA;
offset += stride;
}
}
private updateColor() {
if (!this.ur || !this.ur['_renderData']) {
return;
}
const renderData = this.ur['_renderData'];
let vb = renderData.chunk.vb;
// 获取UIRenderer的原始颜色用于透明度混合
let baseColor = this.ur.color;
let baseA = baseColor.a / 255;
// 动态计算顶点布局,适配CCGray等组件修改的顶点格式
// 默认9个float,CCGray会变为14个
const stride = renderData.floatStride || 9;
// CCGray时写入a_gray_color(偏移9),否则写入ATTR_COLOR(偏移5)
let offset = stride === 14 ? 9 : 5;
// _isGray 为 true 时的变暗因子
const darkenFactor = this.ur['_isGray'] ? 0.5 : 1.0;
if (this._colorMode === ColorMode.Double) {
// 双颜色模式:上下渐变
const vbColors = [this._colorB, this._colorB, this._colorT, this._colorT];
// 按照 左下、右下、左上、右上的顺序写入颜色
for (let i = 0, len = vbColors.length; i < len; i++) {
let color = vbColors[i];
vb[offset] = (color.r / 255) * darkenFactor;
vb[offset + 1] = (color.g / 255) * darkenFactor;
vb[offset + 2] = (color.b / 255) * darkenFactor;
vb[offset + 3] = (color.a / 255) * baseA;
offset += stride;
}
} else {
// 四颜色模式:四个角独立颜色
const vbColors = [this._colorLB, this._colorRB, this._colorLT, this._colorRT];
for (let i = 0, len = vbColors.length; i < len; i++) {
let color = vbColors[i];
vb[offset] = (color.r / 255) * darkenFactor;
vb[offset + 1] = (color.g / 255) * darkenFactor;
vb[offset + 2] = (color.b / 255) * darkenFactor;
vb[offset + 3] = (color.a / 255) * baseA;
offset += stride;
}
}
}
}
Source: cocos/cocos-engine