我目前正在为 Autodesk Viewer 开发自定义扩展,在尝试更改模型特定部分的颜色时遇到问题。 当尝试在我的自定义扩展中使用 THREE.MeshPhongMaterial 更改片段颜色时,对象识别正常,但材质表示中出现错误并且对象变得透明,导致浏览器控制台中出现以下错误:
GL_INVALID_OPERATION:活动绘制缓冲区缺少片段着色器输出。
我在发布这个问题之前阅读了这些帖子。
如果您能提供有关此错误含义以及解决该错误的步骤的建议,我将不胜感激。
我的javascript如下:
class ChangeColorCustom extends Autodesk.Viewing.Extension {
constructor(viewer, options) {
super(viewer, options);
this._colorPickerId = this.guid();
this.addCSS();
}
addCSS() {
const link = $('<link/>', {
rel: 'stylesheet',
type: 'text/css',
href: '/extensions/ChangeColorCustom/contents/main.css'
});
link.appendTo('head');
}
load() {
this.viewer.addEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
this.onItemSelected.bind(this)
);
this.createUI();
return true;
}
unload() {
console.log("ChangeColorCustom unloaded");
this.viewer.removeEventListener(
Autodesk.Viewing.SELECTION_CHANGED_EVENT,
this.onItemSelected
);
$(`#${this._colorPickerId}-container`).remove();
return true;
}
createUI() {
const container = this.viewer.container;
if (container) {
const htmlString = `
<div id="${this._colorPickerId}-container" style="position: absolute; right: 25%; top: 5%; z-index: 100;">
<input type="text" id="${this._colorPickerId}-DBIdInput" placeholder="Enter DBID">
<input type="range" id="${this._colorPickerId}-opacitySlider" min="0" max="1" step="0.01" value="1">
<button id="${this._colorPickerId}-applyColorButton">Apply Color</button>
<button id="${this._colorPickerId}-resetButton">Reset Color</button>
</div>
`;
container.insertAdjacentHTML('beforeend', htmlString);
// Apply color
$(`#${this._colorPickerId}-applyColorButton`).click(() => {
const dbId = parseInt($(`#${this._colorPickerId}-DBIdInput`).val(), 10);
const opacity = parseFloat($(`#${this._colorPickerId}-opacitySlider`).val());
if (!isNaN(dbId)) {
// set the color to `#ffffff`
const fixedColor = new THREE.Color("#ffffff");
this.changeColor(dbId, fixedColor, opacity);
}
});
// reset button
$(`#${this._colorPickerId}-resetButton`).click(() => {
const dbId = parseInt($(`#${this._colorPickerId}-DBIdInput`).val(), 10);
if (!isNaN(dbId)) {
this.resetColor(dbId);
}
});
}
}
changeColor(dbId, color, opacity) {
const material = new THREE.MeshPhongMaterial({
color: color,
transparent: true,
opacity: opacity
});
material.colorWrite = true;
const instanceTree = this.viewer.model.getData().instanceTree;
instanceTree.enumNodeFragments(dbId, (fragId) => {
const proxy = this.viewer.impl.getFragmentProxy(this.viewer.model, fragId);
proxy.setMaterial(material);
proxy.updateAnimTransform();
}, true);
this.viewer.impl.invalidate(true, true, true);
}
resetColor(dbId) {
// Reset to the default material or reset logic here.
}
guid() {
const d = new Date().getTime();
return 'xxxx-xxxx-xxxx-xxxx'.replace(/[xy]/g, (c) => {
const r = (d + Math.random() * 16) % 16 | 0;
return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
}
onItemSelected(event) {
if (event.dbIdArray.length > 0) {
const dbId = event.dbIdArray[0];
this.viewer.getProperties(dbId, (props) => {
$(`#${this._colorPickerId}-DBIdInput`).val(props.externalId || props.dbId);
}, (error) => {
console.error('Error getting properties:', error);
});
}
}
}
Autodesk.Viewing.theExtensionManager.registerExtension(
'ChangeColorCustom',
ChangeColorCustom
);
提前感谢您的帮助。😊
如果您只是尝试将自定义颜色应用于场景中的选定元素,我建议使用标准 viewer.setThemingColor 方法。
创建自定义的 Three.js 材质/着色器也可以在 APS 查看器中,但是这是一个更加复杂的过程,因为着色器必须始终针对查看器渲染管道进行调整。