Hi I am having problems importing models from blender in three.js.
At this moment I am using the last version of three.js (R71). I installed the exporter of three.js in blender and exports fine.
This is the code of HTML.
<body>
<font size="+6"><b>TFG</b></font><br>
Volver a atrás
<hr>
<div id='container'></div>
<script src="libs/ThreeJSV71/build/three.min.js"></script>
<script src="libs/OrbitControls.js"></script>
<script src="libs/Coordinates.js"></script>
<script src="libs/dat.gui.min.js"></script>
<script src="libs/stats.min.js"></script>
<script src="libs/ColladaLoader.js"></script>
<script src="threejs/tfg2.js"></script>
<br>
</body>
The next file is the tfg2.js where I load the model.
var width = window.innerWitdh,
height = window.innerHeight,
clock = new THREE.Clock(),
scene,
camera,
renderer,
ambientLight,
directionalLight,
loader,
modelo = new THREE.Object3D();
init();
function init()
{
scene =new THREE.Scene();
camera = new THREE.PerspectiveCamera(40, width/height, 1000);
camera.position.set(0,1,5);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width,height);
renderer.setClearColor(new THREE.Color(0x0000AA));
document.getElementById('container').appendChild(renderer.domElement);
ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(0,1,0);
scene.add(directionalLight);
scene.add(new THREE.GridHelper(10,1));
loader = new THREE.JSONLoader();
loader.load('blender/json/camara.json', function(geometry,materials)
{
modelo = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
scene.add(modelo);
});
}
When I try to see the results, nothing appear in the webpage and also de JavaScript console don't show any error. If I export the model with collada format and another .js that I have, I can see the model but I need use JSON.
What I am doing wrong?EDIT:
Added: modelo.position.set(0,0,0) inside the callback to be sure that the model is in origin.
Since there are no error what you can do:
While exporting the object from blender translate the object to origin. Go to origin>> select origin to geometry>> translate object to x, y, z to zero.
Now your camera see # position 0,1,5 xyz respectivily
Probably where your object camera is not looking
Or translate the child of scene to origin
Probably this solve your issue. As I see there are no error and warning in log.
Related
I just created a new app with npm and started to learn three.js . I don't know if I deleted something accidentally but the browser keeps giving an error. (VM80:6770 crbug/1173575, non-JS module files deprecated.)
import './style.css'
import * as THREE from 'three';
import { BoxGeometry } from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/ window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#bg'),
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(innerWidth/innerHeight);
camera.position.setZ(30);
renderer.render(scene, camera);
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial( {color: red, wireframe: true} ) ;
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
HTML:
<body>
<canvas id="bg"></canvas>
<div id="app"></div>
<script type="module" src="/main.js"></script>
</body>
edit: it somehow a bit fixed but chrome still gives errors.
updated screenshot
edit 2:
I created new app again and when I render it, the page gave me this:
I fixed it. In the last version, npm creates an automatic 'app' and I kept deleting it. I should include 'canvas' tag in there. That was all it
I'm a beginner to three.js.I'm trying to build something similar to this https://virtualshowroom.nissan.in/car-selected.html?selectedCar=ext360_deep_blue_pearl. I built everything using three.js, but I'm not able to figure out how to create a hotspot(like the red dot in the above link) and show pop up when you click on it. below is my project code, let me know if anything else is required.
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<h1></h1>
<script src="./three.js"></script>
<script type="module">
import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
var renderer,scene,camera;
scene = new THREE.Scene();
scene.background = new THREE.Color(0xfff6e6)
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var loader = new GLTFLoader();
var hlight = new THREE.AmbientLight(0x404040, 100)
scene.add(hlight)
var directionalLight = new THREE.DirectionalLight(0xffffff, 100)
directionalLight.position.set(0,1,0)
directionalLight.castShadow = true
scene.add(directionalLight)
var light = new THREE.PointLight(0xffffff, 10)
light.position.set(0, 300, 500)
scene.add(light)
var light2 = new THREE.PointLight(0xffffff, 10)
light2.position.set(500, 100, 0)
scene.add(light2)
var light3 = new THREE.PointLight(0xffffff, 10)
light3.position.set(0, 100, -500)
scene.add(light3)
var light4 = new THREE.PointLight(0xffffff, 10)
light4.position.set(-5000, 300, 0)
scene.add(light4)
var controls = new OrbitControls(camera, renderer.domElement);
document.body.appendChild(renderer.domElement)
var loader = new GLTFLoader();
loader.load( './scene.gltf', function ( gltf )
{
scene.add( gltf.scene );
}, undefined, function ( error ) { console.error( error ); } );
// load a image resource
camera.position.z = 5;
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
Those “hotspots” as you call them are Annotations where the annotation content is basically pure HTML.
The tutorial in the link is probably the best step-by-step readiness you can follow to learn how to do it in your scene.
I can give a walkthrough on the steps required to get the desired effect since I have done it a few times myself.
define a 3d point in your scene where the hotspot should be. You can optionally nest this in a an other Object3D to make sure it scales, moves and rotates with the model / parent.
Add a plane to this point load a image texture to this plane. and there you have your visible hotspot
update the hotspots to make sure they are always looking at the camera by using the lookAt function.
when the user clicks the screen cast a raycast against all the hotspots you have in your scene. Easiest way to do this is by storing all your hotspots in an array.
When the raycast hits a hotspot get the location either of the hitpoint or the hotspots location. Transform that to screen coordinates. Search on stackoverflow how to do this. I am sure there is a post about this.
Final step display your html on the correct location you obtained from the previous step.
The advantage of this method is that the hotspot will integrate nicely with the model in your scene. Since html based hotspots will always be on top of the scene.
That is about all that is to it. Let me know if you need any further clarification!
I'm trying to display an OBJ 3D model as a wireframe that can be moved with OrbitControls using Three.js. I'm new with three.js, so I apologize if I'm missing something "obvious".
I've been able to get a cube to show as a wireframe with OrbitControls.
In a different setup, I was able to display the OBJ 3D model as a wireframe. Therefore, the issue isn't related to the 3D model.
The issue happens when I try to mix both approaches together.
I've tried to go about this in two ways:
I tried to insert the OBJLoader into the cube environment. (most promising)
I tried to add OrbitControls into the working, but unmovable, wireframe OBJ environment. (didn't really work at all)
Most of the other answers focus on the order of scripts: yes, I have tried to move the three.min.js, OrbitControls.js, OBJLoader.js, and my main working model.js into order and disorder, in every possible way.
Here's my code:
<head>
<style media="screen"> html, body { margin: 0; } #model_container { background-color: #333333; margin: 50px; } </style>
<title>OBJ Wireframe</title>
<script defer src="script/three/build/three.min.js"></script>
<script defer src="script/three/examples/jsm/controls/OrbitControls.js"></script>
<script defer src="script/three/examples/jsm/loaders/OBJLoader.js"></script>
<script defer src="script/model.js"></script>
</head>
<body>
<div id="model_container"></div>
</body>
const globalWidth = window.innerWidth - 100;
const globalHeight = window.innerHeight - 100;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, globalWidth / globalHeight, 0.1, 1000);
camera.position.x = 300;
camera.position.y = -6;
camera.position.z = 1;
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setClearColor( 0xffffff, 0);
renderer.setSize(globalWidth, globalHeight);
const canvas = document.getElementById("model_container");
canvas.appendChild( renderer.domElement );
const ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
const loader = new THREE.OBJLoader();
loader.load("assets/castle.obj", function(object) {
const geometry = object.children[0].geometry;
THREE.GeometryUtils.center(geometry);
const material = new THREE.MeshLambertMaterial({});
const mesh = new THREE.Mesh(geometry, material);
mesh.material.wireframe = true;
scene.add(mesh);
})
const controls = new THREE.OrbitControls(camera);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.rotateSpeed = 0.1;
controls.target.set(0, 0, 0);
var animate = function () {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
Here are the errors I can't fix after 3 days of searching and trying everything I could:
OrbitControls.js:9: Uncaught SyntaxError: Unexpected token {
OBJLoader.js:5: Uncaught SyntaxError: Unexpected token {
Uncaught TypeError: THREE.OBJLoader is not a constructor at model.js:23
The errors seem to be rooted in the THREE.js files themselves, which I find very strange. I'm all out of ideas and documentation to go through.
I'm running this with MAMP, but have also tried uploading to a server to see if the issue is related to being local files or anything similar.
<script defer src="script/three/examples/jsm/controls/OrbitControls.js"></script>
<script defer src="script/three/examples/jsm/loaders/OBJLoader.js"></script>
It seems you are loading the files from the wrong path. Files from the jsm directory are ES6 modules which are imported via ES6 import syntax. Try to include the files from the js directory:
<script defer src="script/three/examples/js/controls/OrbitControls.js"></script>
<script defer src="script/three/examples/js/loaders/OBJLoader.js"></script>
three.js R106
I´ve started programming using three.js a little time ago, and I would like to know how to make a menu on a page before it loaded the program using three itself.So, for instance I would like before running my game to have two options:"start" and "music control" being desplayed before it loaded itself.
Is this made using three, or do you use html, javascript files?(Sorry, I really don´t know how to even start it).
If possible, I would like some tutorials or even videos about it.
I would like something like this for example:
http://www.dilladimension.com/
http://lights.helloenjoy.com/
You probably do want to use html to display the menu and js to control the instantiation of your scene.
Rather than use the page load event to set up your renderer, etc, put them inside a function, and use js events to begin the function:
function start() {
var renderer = new THREE.WebGLRenderer();
...
// more setup
...
renderer.render(scene, camera);
};
Then activate this method with a button or a link:
<button onclick="start()">
Start Scene
</button>
Here's a test implementation:
function start() {
var renderer = new THREE.WebGLRenderer();
renderer.setSize(800, 600);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
35, // Field of view
800 / 600, // Aspect ratio
0.1, // Near plane
10000 // Far plane
);
camera.position.set(-15, 10, 10);
camera.lookAt(scene.position);
var geometry = new THREE.BoxGeometry(5, 5, 5);
var material = new THREE.MeshLambertMaterial({
color: 0xFF0000
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
var light = new THREE.PointLight(0xFFFF00);
light.position.set(10, 0, 10);
scene.add(light);
renderer.setClearColor(0xdddddd, 1);
renderer.render(scene, camera);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.min.js"></script>
<button onclick="start()">
Start Scene
</button>
Help, I'm getting multiple brain spasms trying to figure this out. I'm using r74 the most recent version threejs and I've created a model in blender and exported it using the most recent plugin. When I run my program, it loads the 3d file just fine, but it should also load the texture and apply it, right? Well it isn't, and according to everything I've seen online and every article I've read I'm doing it right. So what the heck! Is three.js broken right now?
Anyway, rants aside, here is my javascript code:
<!doctype html>
<html lang="en">
<head>
<title>Imported Model (Three.js)</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel=stylesheet href="css/base.css"/>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/Detector.js"></script>
<script src="js/Stats.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/THREEx.KeyboardState.js"></script>
<script src="js/THREEx.FullScreen.js"></script>
<script src="js/THREEx.WindowResize.js"></script>
<!-- jQuery code to display an information button and box when clicked. -->
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery-ui.js"></script>
<link rel=stylesheet href="css/jquery-ui.css" />
<link rel=stylesheet href="css/info.css"/>
<script src="js/info.js"></script>
<div id="infoButton"></div>
<div id="infoBox" title="Demo Information">
This three.js demo is part of a collection at
http://stemkoski.github.io/Three.js/
</div>
<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>
<script>
// MAIN
// standard global variables
var container, scene, camera, renderer, controls, stats;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();
// custom global variables
var android;
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
// RENDERER
renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
THREEx.WindowResize(renderer, camera);
THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
// CONTROLS
controls = new THREE.OrbitControls( camera, renderer.domElement );
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
// LIGHT
var light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
// SKYBOX/FOG
var skyBoxGeometry = new THREE.CubeGeometry( 10000, 10000, 10000 );
var skyBoxMaterial = new THREE.MeshBasicMaterial( { color: 0x9999ff, side: THREE.BackSide } );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
// scene.add(skyBox);
scene.fog = new THREE.FogExp2( 0x9999ff, 0.00025 );
//JSON LOADER HERE !!!!!!!
// Note: if imported model appears too dark,
// add an ambient light in this file
// and increase values in model's exported .js file
// to e.g. "colorAmbient" : [0.75, 0.75, 0.75]
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load("map/titled.json", addModelToScene );
jsonLoader.setTexturePath("http://localhost:8080/map/");
// addModelToScene function is called back after model has loaded
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
}
function addModelToScene( geometry, materials )
{
var material = new THREE.MeshFaceMaterial( materials );
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set(10,10,10);
scene.add( mesh );
}
function animate()
{
requestAnimationFrame( animate );
render();
update();
}
function update()
{
if ( keyboard.pressed("z") )
{
// do something
}
controls.update();
stats.update();
}
function render()
{
renderer.render( scene, camera );
}
</script>
</body>
</html>
Json file (titled.json):
"materials":[{
"DbgIndex":81,
"DbgColor":15658734,
"depthTest":true,
"shading":"phong",
"wireframe":false,
"depthWrite":true,
"transparent":false,
"DbgName":"Material.002",
"colorSpecular":[0.5,0.5,0.5],
"visible":true,
"colorEmissive":[0,0,0],
"opacity":1,
"colorDiffuse":[0.64,0.64,0.64],
"specularCoef":50,
"blending":"NormalBlending"
},{
"DbgIndex":117,
"DbgColor":15658734,
"depthTest":true,
"shading":"phong",
"wireframe":false,
"depthWrite":true,
"transparent":false,
"DbgName":"Material",
"colorSpecular":[0.5,0.5,0.5],
"visible":true,
"colorEmissive":[0,0,0],
"opacity":1,
"colorDiffuse":[0.64,0.64,0.64],
"specularCoef":50,
"blending":"NormalBlending"
}],
--- edit --- in response to gaitat ---
I know.
Earlier I was using the old version of the blender plug-in "io_mesh_three" and I would choose the same settings as I'm choosing now, and there would a be reference to my texture in the json file. However, I recently found that the old blender plug-in, according to mrdoob found here: (https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender), had been completely replaced. So I installed the new plug-in, and with the new exporter options ui I could't quite tell if I was using the same settings or not, but the reference would no longer show up, so I figured it just didn't need the reference. I think I'm having trouble understanding what's happening because there isn't a lot of support online for the more recent versions of three.js. Most of what I've found has been support for the older versions, so I'm just fishing to try and find a solution to get my code to load my json file AND apply the texture.