gpt4 book ai didi

javascript - 三个 : How could we insert a locally loaded mesh into the canvas being generated by Three to display it?

转载 作者:数据小太阳 更新时间:2023-10-29 04:52:00 25 4
gpt4 key购买 nike

您好,感谢您阅读这个问题:

我正在学习 Threejs,目前我有一个奇怪的困难:

我已经学会了如何使用加载器以纯 HTML/JAVASCRIPT 加载格式为 NRRD 的本地文件:这里是 repo:https://github.com/YoneMoreno/LoadNRRDInThreeJSExample

作为它的外观示例:

enter image description here

但是,我想将前面的示例与 React 集成。

我研究了如何使用这个 SO 线程关联 React 和 Three: Rendering three.js element in React?

现在我的代码是这样的:

/*global THREE */

import React from 'react';

class LoadNRRD extends React.Component {

constructor(props) {
super(props)

this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.animate = this.animate.bind(this)
}

componentDidMount() {
const width = this.mount.clientWidth
const height = this.mount.clientHeight

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
width / height,
0.1,
1000
)

var loader = new THREE.NRRDLoader();
loader.load("models/columnasegmentado01.nrrd", function (volume) {
var sliceZ;


//z plane

var indexZ = 0;
sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4))
console.log(sliceZ);
scene.add(sliceZ.mesh);

});

const renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);


renderer.setClearColor('#000000')


this.scene = scene
this.camera = camera
this.renderer = renderer

let controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 0;
controls.zoomSpeed = 5;
controls.panSpeed = 2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;


this.mount.appendChild(this.renderer.domElement)
this.start()
}

componentWillUnmount() {
this.stop()
this.mount.removeChild(this.renderer.domElement)
}

start() {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate)
}
}

stop() {
cancelAnimationFrame(this.frameId)
}

animate() {


this.renderScene()
this.frameId = window.requestAnimationFrame(this.animate)
}

renderScene() {
this.renderer.render(this.scene, this.camera)
}

render() {
return (
<div
style={{width: '2000px', height: '2000px'}}
ref={(mount) => {
this.mount = mount
}}
/>
)
}
}

export default LoadNRRD;

我不明白的部分是:为什么它显示 Canvas 但里面没有模型?

enter image description here

我已经检查加载程序是否运行良好并且模型是否就位,因为我们可以在控制台日志中看到它:

THREE.VolumeSlice
axis:"z"
canvas:canvas
canvasBuffer:canvas
... more properties ...

你能帮帮我吗?我错过了一些步骤吗?您以前遇到过这个问题吗?您如何尝试调试这种情况?

请注意,在分支 ThreeIntegrate 中是我正在编写的代码:https://github.com/PrototipoAtlas/Prototipo

如果您有任何意见或建议,请告诉我 🙃 🙂

编辑:谢谢@Jim Tang 的建议。我已经安装了三个 Chrome 扩展程序,并且在全局变量 window.scene 中设置场景后它给出的输出如下所示: https://github.com/jeromeetienne/threejs-inspector/issues/11

结果是: enter image description here

我尝试使用独立的纯 HTML/JS 示例,它的模型如下:

enter image description here

那么关键问题是:为什么模型与场景没有关联?‽‽

我又试了一次,看起来模型确实已加载,但是当我尝试更改 iot 的颜色时,在控制台中,甚至单击它时显示:

THREE.MeshBasicMaterial: .shading has been removed. Use the boolean .flatShading instead.

我认为,解决方案可能是发现缺失的部分。如果我们再次看到有效的示例,我们有三个元素:

enter image description here

我怀疑这三个元素可能是添加到 DOM 中的元素:

        document.body.appendChild(container);
container.appendChild(renderer.domElement);
...more code...
container.appendChild(stats.dom);

在不显示模型的代码中,附加的是:

this.mount.appendChild(this.renderer.domElement);
this.mount.removeChild(this.renderer.domElement)

即使删除了附加的不常见元素,统计信息,纯 HTML/JS 示例仍然有效并显示了三个元素!!

enter image description here

我发现缺少的元素是相机,因为如果我们看到工作示例,对象有 fov、near、far 等:

enter image description here

所以我尝试在我们正在讨论的代码中将相机添加到场景中:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
width / height,
0.1,
1000
);


scene.add(camera);

它提供了一个巨大的堆栈跟踪:

    TypeError: Cannot read property 'getExtension' of null
get
http://localhost:3001/build/three.js:20112:22
initGLContext
http://localhost:3001/build/three.js:21116:15
new WebGLRenderer
http://localhost:3001/build/three.js:21161:3
LoadNRRD.componentDidMount
http://localhost:3001/static/js/bundle.js:62599:28
62596 | scene.add(sliceZ.mesh);
62597 | });
62598 |
> 62599 | var renderer = new THREE.WebGLRenderer({ antialias: true });
| ^ 62600 | renderer.setPixelRatio(window.devicePixelRatio);
62601 | renderer.setSize(width, height);
62602 |
View source
▶ 17 stack frames were collapsed.
./src/index.js
C:/Users/YonePC/WebstormProjects/prototipo/src/index.js:22
19 | );
20 | };
21 |
> 22 | ReactDOM.render(
23 | <BrowserRouter>
24 | <App/>
25 | </BrowserRouter>
View compiled
▶ 6 stack frames were collapsed.

TypeError: Cannot read property 'domElement' of undefined
LoadNRRD.componentWillUnmount
C:/Users/YonePC/WebstormProjects/prototipo/src/components/animals/LoadNRRD.js:73
70 |
71 | componentWillUnmount() {
72 | this.stop();
> 73 | this.mount.removeChild(this.renderer.domElement)
74 | }
75 |
76 | start() {
View compiled
▶ 25 stack frames were collapsed.
./src/index.js
C:/Users/YonePC/WebstormProjects/prototipo/src/index.js:22
19 | );
20 | };
21 |
> 22 | ReactDOM.render(
23 | <BrowserRouter>
24 | <App/>
25 | </BrowserRouter>
View compiled
▶ 6 stack frames were collapsed.

编辑2:

我又试了一次,我们看到了:

enter image description here

我们正在讨论的代码:

/*global THREE */

import React from 'react';

class LoadNRRD extends React.Component {

constructor(props) {
super(props);

this.stop = this.stop.bind(this);
this.start = this.start.bind(this);
this.animate = this.animate.bind(this)
}

componentDidMount() {
const width = this.mount.clientWidth;
const height = this.mount.clientHeight;

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
width / height,
0.1,
1000
);


scene.add(camera);

const loader = new THREE.NRRDLoader();
loader.load("models/columnasegmentado01.nrrd", function (volume) {
let sliceZ;


//z plane

const indexZ = 0;
sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
sliceZ.name = 'foo';
console.log(sliceZ);
scene.add(sliceZ.mesh);

});

var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);


renderer.setClearColor('#000000');


this.scene = scene;
window.scene = scene;
this.camera = camera;
this.renderer = renderer;

let controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 0;
controls.zoomSpeed = 5;
controls.panSpeed = 2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;


this.mount.appendChild(this.renderer.domElement);
this.start()
}

componentWillUnmount() {
this.stop();
this.mount.removeChild(this.renderer.domElement)
}

start() {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate)
}
}

stop() {
cancelAnimationFrame(this.frameId)
}

animate() {


this.renderScene();
this.frameId = window.requestAnimationFrame(this.animate)
}

renderScene() {
this.renderer.render(this.scene, this.camera)
}

render() {
return (
<div
style={{width: '2000px', height: '2000px'}}
ref={(mount) => {
this.mount = mount
}}
/>
)
}
}

export default LoadNRRD;

如您所见,我已将名称添加到 sliceZ,它显示在 Web 控制台上: enter image description here

EDIT3:使用渲染器信息对象进行调试:

我们看到有一个几何体和一个纹理,并且渲染方法被调用了 217 次:

{render: {…}, memory: {…}, programs: Array(0), autoReset: false, reset: ƒ}
autoReset:false
memory:geometries:1 textures:1
__proto__:Object
programs:[WebGLProgram]
render:
calls:217
faces:434
frame:0
points:0
vertices:1302
__proto__:Object
reset:
ƒ resetInfo()
__proto__:
Object

我调试了一个工作示例,其中 React 与 Three 集成:

https://codepen.io/anon/pen/eMYxZw

然后在控制台上我们看到信息对象:

autoReset: false

memory: Object { geometries: 1, textures: 0 }

programs: Array [ {…} ]

render: Object { frame: 485, calls: 1, vertices: 36, … }

__proto__: Object { … }

所以我们看到调用次数为 1,可能是代码中的问题表明不断调用渲染器的渲染方法?

另外我上传了正在讨论的代码:

https://github.com/YoneMoreno/ThreeReactNRRDLoaderStandalone.git

你能帮帮我吗?

最佳答案

有一个google chrome扩展程序three.js inspector,您可以安装它并非常方便地检查场景层次结构。顺便说一句,如果它在一个元素内,它就无法找到你的三个对象。

关于javascript - 三个 : How could we insert a locally loaded mesh into the canvas being generated by Three to display it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48967106/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com