我有两个场景并进行渲染。我还使用Bootstrap 4作为模态窗口。 一个场景是主要场景,另一个场景显示在模态窗口中,这就是为什么我要使用两个渲染:一个用于主屏幕上的元素,另一个用于模态窗口。
代码:
主要场景:
<div class="output3d" id="WebGL-output"></div>
function setMainScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color("#ffffff");
renderer = new THREE.WebGLRenderer({antialias: true, logarithmicDepthBuffer: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("WebGL-output").appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 2000);
camera.position.x = home[0];
camera.position.y = home[1];
camera.position.z = home[2];
camera.lookAt(home[3], home[4], home[5])
controls = initOrbitControls(camera, renderer, new THREE.Vector3(home[3], home[4], home[5]))
}
模态窗口的场景:
<div class="modal" data-backdrop="static" id="ObjectInfo" role="dialog" tabindex="-1">
<div class="modal-dialog modal-xl modal-dialog-scrollable" role="document" style="bottom: 0">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="ObjectId"></h5>
<button aria-label="Close" class="close" data-dismiss="modal" onclick="" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="container">
<div class="row">
<div class="col">
<div>
<img src="css/360.jpg" alt="<-->">
</div>
<div id="FrontView"></div>
</div>
<div class="col">
<p id="ObjectType" class="mb-0"></p>
<p id="ObjectInfoText" class="mb-0"></p>
</div>
</div>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
function setModalWindowScene() {
modalWindowScene = new THREE.Scene()
modalWindowScene.background = new THREE.Color("#ffffff");
modalWindowRenderer = new THREE.WebGLRenderer({antialias: true});
modalWindowRenderer.setPixelRatio(window.devicePixelRatio);
modalWindowRenderer.setSize(450, 450);
document.getElementById("FrontView").appendChild(modalWindowRenderer.domElement);
modalWindowCamera = new THREE.PerspectiveCamera(45, document.getElementById("FrontView").innerWidth / document.getElementById("FrontView").innerHeight, 1, 100);
modalWindowControls = new THREE.OrbitControls(modalWindowCamera, modalWindowRenderer.domElement);
初始化:
function init() {
setMainScene()
setModalWindowScene()
// adding objects to main scene
addRoom()
addRacks()
addExtinguishingCylinders()
addHotHalls()
addWires()
addLights()
window.addEventListener('resize', onWindowResize, false);
}
渲染:
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
if (modalWindowOpen) {
modalWindowRenderer.render(modalWindowScene, modalWindowCamera);
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
modalWindowCamera.aspect = document.getElementById("FrontView").offsetWidth / document.getElementById("FrontView").offsetHeight;
camera.updateProjectionMatrix();
modalWindowCamera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
modalWindowRenderer.setSize(document.getElementById("FrontView").offsetWidth, document.getElementById("FrontView").offsetHeight)
}
HTML:
<script type="text/javascript">
init();
animate();
</script>
当用户打开模态窗口时,将对象添加到模态场景中,并且用户可以使用模态控件在模态场景中与之交互。
问题:
当用户第一次打开模式窗口时,尽管该对象已附加到模式窗口中的<div id="FrontView"></div>
上,但未绘制该对象的图片,但该对象为空。但是,当用户调整窗口大小时,图片会显示并永久保留。
有趣的事情。当模态窗口中没有图片时,我可以使用控件旋转对象,该控件已绑定到模态场景。
答案 0 :(得分:2)
您需要在init函数中调用render。
看来您只在onWindowResize函数中调用render,直到实际调整窗口大小(页面加载时才启用)后才会触发。
您可能还需要渲染循环。
看看下面的例子。
您将在顶部看到,我调用init函数设置场景,然后调用animate函数启动渲染循环。
var camera, scene, renderer, mesh, material;
// init scene.
init();
// Start animation/render loop.
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer();
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
// Create scene.
scene = new THREE.Scene();
// Create material
material = new THREE.MeshPhongMaterial();
// Create cube and add to scene.
var geometry = new THREE.BoxGeometry(200, 200, 200);
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Create ambient light and add to scene.
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
// Create directional light and add to scene.
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
}
function animate() {
requestAnimationFrame(animate); // this makes the animate function a loop that runs every frame.
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
<script src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
答案 1 :(得分:0)
好吧,看起来我在创建modelWindowCamera
时设置了零宽高比,因为对象document.getElementById("FrontView")
在首次渲染之前没有大小。而且,当我更改窗口的比例时,document.getElementById("FrontView")
的尺寸没有为零,并且相机的纵横比也没有为零。
对于解决方案,我只是将Aspect设置为常数1,现在代码如下:
modalWindowCamera = new THREE.PerspectiveCamera(45, 1, 1, 100);