I am working on a project with video.js to display a video and a 3D render of a webpage.
I have already got a function that call the WebGL renderer but this function is defined in another plugin that I don't want to modify.
Function for WebGL renderer (this plugin has no errors for sure):
var Canvas = function (baseComponent, THREE, settings = {}) {
var parent = BaseCanvas(baseComponent, THREE, settings);
return Util.extend(parent, {
...
render: function(){
parent.render.call(this);
this.camera.target.x = 500 * Math.sin( this.phi ) * Math.cos( this.theta );
this.camera.target.y = 500 * Math.cos( this.phi );
this.camera.target.z = 500 * Math.sin( this.phi ) * Math.sin( this.theta );
this.camera.lookAt( this.camera.target );
if(!this.VRMode){
this.renderer.render( this.scene, this.camera );
}
}
...
}
}
So I've created another plugin to create the CSS3D renderer and my problem is: I want to call the render function for webgl and add my new render function of CSS3D. I did it like this:
class css3d {
...
render(){
this.canvas.render.bind(this);
this.renderer.render(this.scene, this.canvas.camera)
}
...
}
I've got no errors but my css renderer is not working. And I've already look for topic like this: three.js properly blending css3d and webgl or topic like this: https://gist.github.com/leefsmp/38926bf2c379f604f9b5 but still not working.
Somebody could help me?
Finally, I've found my solution, I created a new frameanimation in my class. So now I've got a request animation frame for each renderer (WebGL and CSS3D).
The result looks like this, if some are interested in :
class css3d{
...
render(){
requestAnimationFrame(this.render.bind(this));
this.renderer.render(this.scene, this.canvas.camera);
}
...
}
Have a good day and thanks for helping
Related
I am trying to import a gltf file in vue.js using babylon.js and add 3 dimensional view to the webpage. I can't figure out how to do that and the documentation online is pretty vague as well. Here's what I tried:
This is what I put in Hello.vue file
<div>
<h1> Hello </h1>
<Scene>
<Box :position="[0, 0, 5]"></Box>
</Scene>
</div>
</template>
<script src = "./Hello.js">
</script>
This is what I put in Hello.js file
import vb from 'vue-babylonjs';
import Hello from './Hello.vue';
Vue.use(vb);
new Vue({
components: { Hello },
render: c => c('Hello'),
}).$mount('#app');
var delayCreateScene = function () {
// Create a scene.
var scene = new BABYLON.Scene(engine);
// Create a default skybox with an environment.
var hdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("../assets/magic_book_of_eden/textures/material_0_baseColor.png", scene);
var currentSkybox = scene.createDefaultSkybox(hdrTexture, true);
// Append glTF model to scene.
BABYLON.SceneLoader.Append("../assets/magic_book_of_eden/", "scene.gltf", scene, function (scene) {
// Create a default arc rotate camera and light.
scene.createDefaultCameraOrLight(true, true, true);
// The default camera looks at the back of the asset.
// Rotate the camera by 180 degrees to the front of the asset.
scene.activeCamera.alpha += Math.PI;
});
return scene;
};
If possible, could someone explain using an example how that could be done? I am getting the gltf model from sketchfab. Thank you!
Output:
I would try importing the file and then use that variable in the SceneLoader.
So I decided to see if I could import a DirectX Model and found this XLoader. However I can't seem to initialize it at all. Now, I am the kind of guy who likes to link directly to the library so that whenever there is an update I don't have to re-download and re-upload. My test code looks like this:
<html>
<body>
<script src="https://threejs.org/build/three.js"></script>
<script type="module" src="https://threejs.org/examples/jsm/loaders/XLoader.js"></script>
<script>
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 10000 );
var manager = new THREE.LoadingManager();
var Texloader = new THREE.TextureLoader();
var loader = new THREE.XLoader(manager, Texloader);
loader.load(['FrigateHull.x'], function (object) {
console.log(object);
},function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}},
function (xhr) {
console.log(xhr);
});
</script>
</body>
</html>
The error I am getting from this setup is this:
TypeError: THREE.XLoader is not a constructor
I have also tried the import method as described in the examples but still same error. I have also downloaded the git to the server and tried linking to that, but it said something about global is undefined.
What am I missing, or is there another DirectX Model Loader out there I could try?
Should be like this:
<script src="https://threejs.org/build/three.js"></script>
<script type="module">
import { XLoader } from "https://threejs.org/examples/jsm/loaders/XLoader.js";
// ....
var loader = new XLoader(manager, Texloader);
// ....
</script>
Although the TypeError: THREE.XLoader is not a constructor exception is resolved, there are still other problems.
Let's look at the source code of XLoader.js:
import {
AnimationClip,
AnimationMixer,
Bone,
BufferGeometry,
FileLoader,
Float32BufferAttribute,
FrontSide,
Loader,
LoaderUtils,
Matrix4,
Mesh,
MeshPhongMaterial,
Quaternion,
Skeleton,
SkinnedMesh,
TextureLoader,
Uint16BufferAttribute,
Vector2,
Vector3
} from "../../../build/three.module.js";
// ...
We don't have ../../../build/three.module.js code.
It is recommended that you clone the repository of three.js, and then npm install → npm start to start the project, instead of viewing it directly in the browser, which involves a lot of import and export of modules depends on front-end construction tools.
If I run the script, the console displays me "THREE.OrbitControls is not a constructor".
What did I wrong? I used the same code from a manual.
var controls;
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
//Hier wird die Größe des Fensters manipuliert!
renderer.setSize(window.innerWidth - 20, window.innerHeight - 20);
};
var animate = function () {
requestAnimationFrame( animate );
controls.update();
};
var geometry1 = new THREE.BoxGeometry( 10, 10, 10);
var material = new THREE.MeshPhongMaterial( {specular: "#fdfb57", color: "#d8d613", emissive: "#6b6a0d", side: THREE.DoubleSide} );
var box = new THREE.Mesh(geometry1, material);
scene.add(box);
camera.position.z = 50;
render();
animate();
You must explicitly include OrbitControls in your application. For example:
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three/build/three.module.js",
"three/addons/": "https://unpkg.com/three/examples/jsm/"
}
}
</script>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
Also, read the comments in the three.js OrbitControls example carefully so you understand when to use
controls.addEventListener( 'change', render ); // add this only if there is no animation loop (requestAnimationFrame)
and when to use
controls.update(); // required if controls.enableDamping = true, or if controls.autoRotate = true
https://github.com/mrdoob/three.js/blob/dev/examples/misc_controls_orbit.html
three.js r.147
I had the same issue with a webpack build of the three library
var THREE = require('three')
THREE.OrbitControls === undefined // true
Solution, install a 3rd party orbit control
npm install three-orbit-controls
details here: https://github.com/mattdesl/three-orbit-controls
then change the above code fragment to
var THREE = require('three')
var OrbitControls = require('three-orbit-controls')(THREE)
OrbitControls === undefined // false
ok, not the best example, but when applied in place of THREE.OrbitControls, it works just fine ;)
https://github.com/nicolaspanel/three-orbitcontrols-ts :
npm install --save three-orbitcontrols-ts
import { OrbitControls } from 'three-orbitcontrols-ts'
orbitcontrols should be installed separately in angular, this issue bothers me for several days.
I have a same problem too, it's because you put in wrong line.
you need to put it under of this line
document.body.appendChild( renderer.domElement );
then you add orbit controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', posUpdate );
controls.update();
if it wasn't work, add the script file download here
<script src="OrbitControls.js"></script>
I faced similar issue and after lot of research, the below thing worked
In your HTML the order matters when adding OrbitControls as it needs certain things from Three.js.
It should be
<script src="../build/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
I have a page based on this example, and using the relevant lines from the webgl_material_bumpmap example for implementing a loading progress Dom Element.
The page is (temporarily) here. If what I have included below is not enough information, please see the source for this page.
My problem is that the Loading text block does not disappear when the model is loaded.
I show it using:
function installModel(file) {
if (model) {**strong text**
scene.remove(model);
}
render();
var loader = new THREE.JSONLoader(true);
loader.load("obj/" + file, modelLoadedCallback);
document.body.appendChild( loader.statusDomElement );
}
The init function (without the error handling stuff) is
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, theCanvas.width/theCanvas.height, 0.1, 100);
camera.position.z = 30;
camera.lookAt( scene.position );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.damping = 0.3;
controls.addEventListener( 'change', render );
createWorld();
installModel("room1.json");
render();
loader.statusDomElement.style.display = "none";
}
Why does the Loading text remain visible?
You probably need to add:
loader.statusDomElement.style.display = "none";
in your callback function modelLoadedCallback() after you print to the console.
I worked it out.
I had to add another div element called "prog"
then
var show
function show() {
document.getElementById("prog").style.display = "inline";
}
and
var loader = new THREE.JSONLoader(true);
document.getElementById("prog").appendChild(loader.statusDomElement );
loader.load("obj/" + file, modelLoadedCallback);
I'm trying to use the iewebgl and having trouble running one of the examples from three.js, the webgl_loader_obj. I am getting the following error:
SCRIPT445: Object doesn't support this action
iewebgl.html, line 134 character 5
which points to this line
// texture
var manager = new THREE.LoadingManager(); <!-- here -->
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
I also tried commenting out the texture and model portions and loading the object without the manager but I would receive the following error:
SCRIPT445: Object doesn't support this action
OBJLoader.js, line 19 character 3
which points to this line
THREE.OBJLoader.prototype = {
constructor: THREE.OBJLoader,
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new THREE.XHRLoader( scope.manager ); <!-- here-->
loader.setCrossOrigin( this.crossOrigin );
I tried both creating canvas and getting WebGL context from JavaScript and creating WebGL context with helper.
I'm using ie 10 with r.46 of three.js. When I use r.61 of three.js I get the following exception
SCRIPT5007: Unable to get property 'getExtension' of undefined or null reference
three.min.js, line 8322 character 2
which is
} catch (Zb) {
console.error(Zb)
}
Na = j.getExtension("OES_texture_float"); <!-- here -->
j.getExtension("OES_texture_float_linear");
va = j.getExtension("OES_standard_derivatives");
Any idea what may be causing it?
I was able to solve my issue using the Creating canvas and getting WebGL context from JavaScript example
<div id="container">
<script id="WebGLCanvasCreationScript" type="text/javascript">WebGLHelper.CreateGLCanvasInline('renderCanvas', onLoad)</script>
</div>
I then placed both the init() and animate() calls in the following block leaving out the global vars
var container, stats;
var camera, cameraTarget, scene, renderer;
function onLoad() {
<!-- require(["js/Three.js"], function () { -->
init();
animate();
<!-- }); -->
}
I didn't use the require code, but included it in case anyone else runs into a similar problem and finds they need it.
Finally, had to change the render code to the following. (I left the original commented)
var externalCanvas = document.getElementById('renderCanvas');
renderer = new THREE.WebGLRenderer({ 'canvas': externalCanvas, 'clearColor': 0xffffff });
<!-- renderer = new THREE.WebGLRenderer(); -->
<!-- renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } ); -->
If you use the un-minified version of three.js, I think you'll see the problem is the _gl object (j in the minified version) is null. It also looks to me as if three.js will throw an exception, log the message "Error creating WebGL context" and then proceed to try to use the _gl object. :)
Did you see that message in your console? Here's the un-minified source where I think your error occurs.
function initGL() {
try {
var attributes = {
alpha: _alpha,
premultipliedAlpha: _premultipliedAlpha,
antialias: _antialias,
stencil: _stencil,
preserveDrawingBuffer: _preserveDrawingBuffer
};
_gl = _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );
if ( _gl === null ) {
throw 'Error creating WebGL context.';
}
} catch ( error ) {
console.error( error );
}
_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
_glExtensionTextureFloatLinear = _gl.getExtension( 'OES_texture_float_linear' );
_glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
Is WebGL supported on your IE? Do other webgl tests work? I don't have IE Win8.1 preview but I am curious to know if three.js works with it.