Three.js iPad performance - ipad

before I totally give up on this idea I wanted to check with the three.js community to make sure that I'm not doing something wrong?
Essentially I have taken Mr doobs canvas geometry cube example http://mrdoob.github.io/three.js/examples/canvas_geometry_cube.html and applied an image to the cube faces. When testing on the iPad I have frame a frame speed of 1fps (as opposed to 60fps with the original example). The image also looks really broken up on rotation.
Are there any tricks on getting this to work well on the iPad? I'm aware that WebGL isn't supported but I thought the canvas renderer would perform better than it is?
Code below
Many thanks
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Drag to spin the cube';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
// Cube
var loader = new THREE.TextureLoader();
loader.load( 'test-texture.png', function ( texture ) {
var materials = [];
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
material.transparent = true;
for ( var i = 0; i < 6; i ++ ) {
materials.push( material );
}
// then the cube definitions
cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200,4,4,4), new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add( cube );
animate();
});
// Plane
var geometry = new THREE.PlaneGeometry( 200, 200 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
plane = new THREE.Mesh( geometry, material );
scene.add( plane );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}

I would suggest to wait for iOS8 which should bring WebGL support.

Related

Align multiple photos so contents are at same place

I have multiple images like these
and a main photo one with which all others need to agree.
I want in all photos the little squares of the top row to be exactly on the same place(cause I use a Photoshop script to sample the color of each square's center using static coordinates). In many photos the camera moved a little so I need to adjust them (mostly vertically) to fix that. Do you know of any way that this can be done easily on many (cause I have like 1000 of them) photos?
I tried open like 30-40 in Photoshop at a time but need a way to place and keep some reference points. You know any way that this can be done? Maybe guides common for all opened files or something similar?
You can align vertical centres and then distribute the horizontal centres with code:
function align_tiny_photos()
{ // align and distribute
var idAlgn = charIDToTypeID( "Algn" );
var desc48 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref16 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref16.putEnumerated( idLyr, idOrdn, idTrgt );
desc48.putReference( idnull, ref16 );
var idUsng = charIDToTypeID( "Usng" );
var idADSt = charIDToTypeID( "ADSt" );
var idAdCV = charIDToTypeID( "AdCV" );
desc48.putEnumerated( idUsng, idADSt, idAdCV );
executeAction( idAlgn, desc48, DialogModes.NO );
var idDstr = charIDToTypeID( "Dstr" );
var desc62 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref23 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref23.putEnumerated( idLyr, idOrdn, idTrgt );
desc62.putReference( idnull, ref23 );
var idUsng = charIDToTypeID( "Usng" );
var idADSt = charIDToTypeID( "ADSt" );
var idAdCH = charIDToTypeID( "AdCH" );
desc62.putEnumerated( idUsng, idADSt, idAdCH );
executeAction( idDstr, desc62, DialogModes.NO );
}
To use:
align_tiny_photos();

How to replace and load a GLTF model into a ready made html document

I have copied code from https://threejs.org/examples/#webgl_loader_gltf and pasted it into an html document. I relinked all of the models, textures and .js files locally from MrDoob's JavaScript 3D library https://github.com/mrdoob/three.js/. When I link GLTF files from his folder locally on my computer I am able to view them in firefox but when I simply change the GLTF to my model I am unable to see it. I tried scalling the model down in blender before I export it and I also tried viewing it in Babylon viewer online (I was able to view my own GLTF model on the online Babylon viewer no problem).
// model
var loader = new THREE.GLTFLoader();
loader.load( '../../skull_downloadable/scene.gltf', function ( gltf ) {
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.envMap = envMap;
}
} );
scene.add( gltf.scene );
}, undefined, function ( error ) {
console.error( error );
} );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaOutput = true;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
// stats
stats = new Stats();
container.appendChild( stats.dom );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}

three.js, dat.GUI slider controlled by code, morph targets do not move

I work on a human face that the mouth should move about external coordinates (OpenCV and dlibs). In a first step I try to control the dat.GUI by code, which already works. But now I have the problem that the morph targets do not move when I control by code. The sliders move, but the face doesn't. When I use the mouse, they work perfectly. I ask for help with this problem.
<script>
// Laden der 3DScene
var scene = new THREE.Scene();
// Laden der Kamear Perspektive
var camera = new THREE.PerspectiveCamera(15, window.innerWidth/window.innerHeight, 1, 10000);
camera.position.z = 17;
camera.position.y = 3;
// Laden des Renderers
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setClearColor( 0x000000 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Laden des Orbitcontrollers
var controls = new THREE.OrbitControls( camera, renderer.domElement );
// Laden der Lichter (Beleuchtung)
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
var light = new THREE.PointLight( 0xFFFFDD );
light.position.set( -15, 10, 15 );
scene.add(light);
// Laden des Json Modells
var loader = new THREE.JSONLoader();
loader.load( "./three/models/JSON/test/mkh_shapes.json", function (geometry) {
var material = new THREE.MeshLambertMaterial({morphTargets: true});
var mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(1.2,1.2,1.2); //Modellgrösse die angezeigt wird
mesh.position.x = 0; //Position (x = nach rechts+ links-)
mesh.position.y = -19; //Position (y = nach oben +, unten-)
mesh.position.z = 0; //Position (z = nach vorne +, hinten-)
scene.add(mesh);
//dat.Gui
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var shape = {
mouth_open: 0.0, //Anfangsposition 0.0
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'Morph Targets' );
folder.add( shape, 'mouth_open', 0, 1 ).step( 0.01 ).name('mouth_open').listen().onChange ( function( a ) { mesh.morphTargetInfluences[ 40 ] = a;} );
folder.open();
var updateGui = function() {
for (var i in folder.__controllers) {
folder.__controllers[i].updateDisplay();
}
}
var time = Date.now() * 0.003;
shape.mouth_open = 0.50 //* Math.sin( 0.5 * time ) + 0.3;
//scene.add(shape);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
});
function animate() {
render();
requestAnimationFrame( animate );
}
function render() {
renderer.clear();
renderer.render( scene, camera );
}
animate();
</script>
I have made my own version with extra features like :
Gui auto resize based on content div.
Improved slidecontroller as unique controller (slide or number insert);
Multi language automatic support
Auto check for conflicts in options, then ask for confirm or cancel.
Auto Show/hide other controllers when option selected deselected (example show color list only if "custom color is selected")
ecc.. ecc..
here is the Video
Now is more confortable and easy to use.

Crash in Three.dart "Hello World" project

I've developed simple project using three.dart framework. It launches and shows web page ok. But after 3-5 seconds it crashes with unknown error. Dart editor and browser don't show the reason why it crashed
Here is a code:
import 'dart:html';
import 'dart:math' as Math;
import 'package:three/three.dart';
class MyClass {
Element container;
PerspectiveCamera camera;
Scene scene;
CanvasRenderer renderer;
Mesh plane;
num targetRotation;
num targetRotationOnMouseDown;
num windowHalfX;
num windowHalfY;
var evtSubscriptions = [];
void run() {
init();
animate(0);
}
void init() {
targetRotation = 0;
targetRotationOnMouseDown = 0;
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
container = new Element.tag('div');
document.body.nodes.add( container );
Element info = new Element.tag('div');
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHtml = 'Drag to spin the cube';
container.nodes.add( info );
scene = new Scene();
camera = new PerspectiveCamera( 70.0, window.innerWidth / window.innerHeight, 1.0, 1000.0 );
camera.position.y = 150.0;
camera.position.z = 500.0;
scene.add( camera );
// Plane
plane = new Mesh( new PlaneGeometry( 200.0, 200.0 ), null);
scene.add( plane );
renderer = new CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.nodes.add( renderer.domElement );
}
void render() {
renderer.render( scene, camera );
}
animate(num time) {
window.requestAnimationFrame(animate);
render();
}
}
void main() {
new Canvas_Geometry_Cube().run();
}
How to fix a crash?
I found out the problem. It works with Web GL properly (NOT canvas).
Sergio three.dart might need some work to be updated, its been awhile since a latest version was published on pub. Sorry. Please feel free to checkout the latest branch or code review on the https://github.com/threeDart/three.dart site

THREE JS TextureLoader

I am trying to add texture to a model that I converted to json and imported from 3ds Max. I searched but didn't find any code online which applies texture to json models using three.js r53. I guess the way Three.js handles textures changed from previous version. Any guidance?
Following is my code:
var texloader = new THREE.TextureLoader();
var tex=texloader.load("second.jpg");
var mat = new THREE.MeshBasicMaterial({ map: tex });
loader = new THREE.JSONLoader();
loader.load( "js/JsonModels/toothz.js", function( geometry, mat ) {
mat[0].shading = THREE.SmoothShading;
var material = new THREE.MeshFaceMaterial( mat);
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 3, 3, 3 );
mesh.position.y = 0;
mesh.position.x = 0;
scene.add( mesh );
} );
May be the other answer worked on the older version, this is how I got it working
var textureLoader = new THREE.TextureLoader();
textureLoader.load(url);
// Add the event listener
textureLoader.addEventListener('load', function(event){
// The actual texture is returned in the event.content
sphere.material.map = event.content;
});
EDIT:
This post was a year old when I answered it, and it seems like my answer got posted shortly before the API changed.
This answer won't work (trusting the words of Kumar Sanket Sahu, haven't tested)
Even if this is older than a year, since I came around it now when searching for the solution:
textureloader gives you a callback once the texture is loaded:
var texloader = new THREE.TextureLoader();
texloader.load("second.jpg", function(tex) {
var mat = new THREE.MeshBasicMaterial({ map: tex });
var loader = new THREE.JSONLoader();
loader.load( "js/JsonModels/toothz.js", function( geometry, mat ) {
mat[0].shading = THREE.SmoothShading;
material = new THREE.MeshFaceMaterial( mat);
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 3, 3, 3 );
mesh.position.y = 0;
mesh.position.x = 0;
scene.add( mesh );
} );
});
This works for the example.
This worked for me on September 2019
load(
url: string,
onLoad?: ( texture: Texture ) => void,
onProgress?: ( event: ProgressEvent ) => void,
onError?: ( event: ErrorEvent ) => void
): Texture;
setCrossOrigin( crossOrigin: string ): TextureLoader;
Usage:
// instantiate a loader & load a resource
new THREE.TextureLoader().load(
// resource URL
'textures/land_ocean_ice_cloud_2048.jpg',
// onLoad callback
( texture )=> {
// in this example we create the material when the texture is loaded
var material = new THREE.MeshBasicMaterial( {
map: texture
} );
},
// onProgress callback currently not supported
undefined,
// onError callback
( err )=> {
console.error( 'An error happened.' );
}
);

Resources