我有一个项目正在使用Three.js
和imgui-js
. 我正在尝试更新到每个版本的最新版本,但我遇到了问题(它们最后一次更新是在 2020 年 2 月左右)。
要初始化我正在调用的两个库:
await ImGui.default();
ImGui.CreateContext();
ImGui_Impl.Init(canvas);
ImGui.StyleColorsDark();
const clear_color = new ImGui.ImVec4(0.3, 0.3, 0.3, 1.00);
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
renderer.physicallyCorrectLights = true;
renderer.outputEncoding = THREE.sRGBEncoding;
然后我将一些对象添加到三个场景中:
const scene = new THREE.Scene();
let floorDim = 1000;
var grid = new THREE.GridHelper(floorDim, 200, 'orange', 'white');
grid.name = "grid";
grid.material.opacity = 1.0;
grid.material.transparent = true;
grid.material.color.convertGammaToLinear(2.2);
grid.position.set(0, 2, 0);
scene.add(grid);
var subgrid = new THREE.GridHelper(floorDim, 600, 'grey', 'grey');
subgrid.name = "subgrid";
subgrid.material.opacity = 1.0;
subgrid.material.color.convertGammaToLinear(2.2);
subgrid.material.transparent = true;
subgrid.position.set(0, 1, 0);
scene.add(subgrid);
const light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.set(0, 100, -50);
light.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(light);
const box_1_mesh = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 5), new THREE.MeshLambertMaterial({ color:0x970000 }));
box_1_mesh.position.set(0, 5, 0);
scene.add(box_1_mesh);
const box_2_mesh = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 5), new THREE.MeshLambertMaterial({ color:0x333000 }));
box_2_mesh.position.set(-2, 6, 7);
scene.add(box_2_mesh);
const camera = new THREE.PerspectiveCamera(50, canvas.width / canvas.height, 2, 10000);
camera.position.set(0, 10, -25);
camera.updateProjectionMatrix();
camera.lookAt(0, 0, 0);
scene.add(camera);
并调用如下所示的更新循环:
function _loop(time) {
ImGui_Impl.NewFrame(time);
ImGui.NewFrame();
ImGui.SetNextWindowPos(new ImGui.ImVec2(20, 20), ImGui.Cond.FirstUseEver);
ImGui.SetNextWindowSize(new ImGui.ImVec2(294, 140), ImGui.Cond.FirstUseEver);
ImGui.Begin("Visblility Toggles:");
ImGui.Checkbox("box_1 (near)", (value = box_1_mesh.visible) => box_1_mesh.visible = value);
ImGui.Checkbox("box_2 (distant)", (value = box_2_mesh.visible) => box_2_mesh.visible = value);
ImGui.Checkbox("grid", (value = grid.visible) => grid.visible = value);
ImGui.Checkbox("subgrid", (value = subgrid.visible) => subgrid.visible = value);
ImGui.End();
ImGui.EndFrame();
ImGui.Render();
renderer.setClearColor(new THREE.Color(clear_color.x, clear_color.y, clear_color.z), clear_color.w);
renderer.setSize(canvas.width, canvas.height);
camera.aspect = canvas.width / canvas.height;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
ImGui_Impl.RenderDrawData(ImGui.GetDrawData());
renderer.state.reset();
window.requestAnimationFrame(_loop);
}
更新到这些库的最新版本后,我遇到了场景中的对象未按预期呈现的问题。
例如,我将 2 添加GridHelpers
到场景中,但由于某种原因只显示了一个。此外,如果在场景中切换不同对象的可见性Three
,例如关闭/打开其中一个网格的显示,则在切换回对象时不会再次显示(有时其他对象会消失)。
发生的另一个问题是更复杂的网格材质将具有意想不到的透明度,但是对于我在此示例中添加的简单框,该问题似乎不会发生。虽然,根据是否进行ImGui_Impl.RenderDrawData
呼叫,框的外观可能会发生变化,这可能是相关的。
我发现如果我注释掉对 的调用ImGui_Impl.RenderDrawData(ImGui.GetDrawData())
,场景会按预期显示,两个网格助手都会出现,所以我怀疑现在两个库的使用之间可能存在一些内部冲突webGl
。尽管我绝对有可能设置不正确,或者我错过了所需的电话。
为了帮助演示该问题,我创建了一个复制该问题的片段:https ://codepen.io/bpeake/pen/KKNNQre 。
(async function() {
await ImGui.default();
const canvas = document.getElementById("output");
const devicePixelRatio = window.devicePixelRatio || 1;
canvas.width = canvas.scrollWidth * devicePixelRatio;
canvas.height = canvas.scrollHeight * devicePixelRatio;
window.addEventListener("resize", () => {
const devicePixelRatio = window.devicePixelRatio || 1;
canvas.width = canvas.scrollWidth * devicePixelRatio;
canvas.height = canvas.scrollHeight * devicePixelRatio;
});
ImGui.CreateContext();
ImGui_Impl.Init(canvas);
ImGui.StyleColorsDark();
const clear_color = new ImGui.ImVec4(0.3, 0.3, 0.3, 1.00);
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
renderer.physicallyCorrectLights = true;
renderer.outputEncoding = THREE.sRGBEncoding;
const scene = new THREE.Scene();
let floorDim = 1000;
var grid = new THREE.GridHelper(floorDim, 200, 'orange', 'white');
grid.name = "grid";
grid.material.opacity = 1.0;
grid.material.transparent = true;
grid.material.color.convertGammaToLinear(2.2);
grid.position.set(0, 2, 0);
scene.add(grid);
var subgrid = new THREE.GridHelper(floorDim, 600, 'grey', 'grey');
subgrid.name = "subgrid";
subgrid.material.opacity = 1.0;
subgrid.material.color.convertGammaToLinear(2.2);
subgrid.material.transparent = true;
subgrid.position.set(0, 1, 0);
scene.add(subgrid);
const light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.set(0, 100, -50);
light.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(light);
const box_1_mesh = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 5), new THREE.MeshLambertMaterial({ color:0x970000 }));
box_1_mesh.position.set(0, 5, 0);
scene.add(box_1_mesh);
const box_2_mesh = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 5), new THREE.MeshLambertMaterial({ color:0x333000 }));
box_2_mesh.position.set(-2, 6, 7);
scene.add(box_2_mesh);
const camera = new THREE.PerspectiveCamera(50, canvas.width / canvas.height, 2, 10000);
camera.position.set(0, 10, -25);
camera.updateProjectionMatrix();
camera.lookAt(0, 0, 0);
scene.add(camera);
window.requestAnimationFrame(_loop);
function _loop(time) {
ImGui_Impl.NewFrame(time);
ImGui.NewFrame();
ImGui.SetNextWindowPos(new ImGui.ImVec2(20, 20), ImGui.Cond.FirstUseEver);
ImGui.SetNextWindowSize(new ImGui.ImVec2(294, 140), ImGui.Cond.FirstUseEver);
ImGui.Begin("Visblility Toggles:");
ImGui.Checkbox("box_1 (near)", (value = box_1_mesh.visible) => box_1_mesh.visible = value);
ImGui.Checkbox("box_2 (distant)", (value = box_2_mesh.visible) => box_2_mesh.visible = value);
ImGui.Checkbox("grid", (value = grid.visible) => grid.visible = value);
ImGui.Checkbox("subgrid", (value = subgrid.visible) => subgrid.visible = value);
ImGui.End();
ImGui.EndFrame();
ImGui.Render();
renderer.setClearColor(new THREE.Color(clear_color.x, clear_color.y, clear_color.z), clear_color.w);
renderer.setSize(canvas.width, canvas.height);
camera.aspect = canvas.width / canvas.height;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
ImGui_Impl.RenderDrawData(ImGui.GetDrawData());
renderer.state.reset();
window.requestAnimationFrame(_loop);
}
})();
#output {
position: absolute;
top: 0px;
right: 0px;
width: 100%;
height: 100%;
z-index: 1;
}
<script>
// emu localStorage otherwise ImGUI fails because S.O blocks localStorage
{
const localStorageStorage = new Map();
const localStorage = {
getItem(k) { return localStorageStorage.get(k); },
setItem(k,v) { return localStorageStorage.set(k, v); },
};
Object.defineProperty(window, 'localStorage', {
get() { return localStorage; }
});
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r125/three.min.js"></script>
<script src="https://flyover.github.io/imgui-js/dist/imgui.umd.js"></script>
<script src="https://flyover.github.io/imgui-js/dist/imgui_impl.umd.js"></script>
<script src="https://flyover.github.io/nanovg-js/dist/nanovg.umd.js"></script>
<canvas tabindex="0" id="output"></canvas>
imgui-js
我的or设置有什么问题three-js
吗?关于我可以做什么以使ImGui_Impl.RenderDrawData
调用不会影响我的three.js
场景渲染的任何想法?