Reputation: 11
I have two scenes and to renders. I alse use Bootstrap 4 for modal window. One scene is main, another is shown in modal window, that's why I am using two renders: one for the element on the main screen and one for modal window.
Code:
Main scene:
<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]))
}
Scene for modal window:
<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);
Init:
function init() {
setMainScene()
setModalWindowScene()
// adding objects to main scene
addRoom()
addRacks()
addExtinguishingCylinders()
addHotHalls()
addWires()
addLights()
window.addEventListener('resize', onWindowResize, false);
}
Rendering:
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>
When user opens modal window, object is added to modal scene and the user can interact with it in modal scene with modal controls.
Problem:
When the first time user opens the modal window, picture of the object isn't drawn, despite that object is append to <div id="FrontView"></div>
in the modal window, but it is empty. But when user resize the window , picture appears and stay forever.
Interesting thing. When there is no picture in modal window, I can rotate object with controls, which was binded to modal scene.
Demonstration: Before resizing After resizing
Upvotes: 1
Views: 698
Reputation: 11
Ok, it's look like I set zero aspect when creating modelWindowCamera
because object document.getElementById("FrontView")
had no size before first render. And when I changed scale of the window, document.getElementById("FrontView")
had no zero sizes and aspect of the camera updated with no zero aspect.
For solution I just set aspect to constant 1, and code is now like this:
modalWindowCamera = new THREE.PerspectiveCamera(45, 1, 1, 100);
Upvotes: 0
Reputation: 10155
You need to call render in your init function.
It looks like you only call render in your onWindowResize function which will not fire until the window is actually resized (not when the page loads).
You probably want a render loop also.
Take a look at the example below.
You will see at the top, I call the init function to set the scene, then the animate function to start the render loop.
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>
Upvotes: 2