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.' );
}
);
Related
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 );
}
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.
After draw a circle in my map, I exported it with:
getAsJson : function() {
var geojson = new ol.format.GeoJSON();
var features = this.vectorSource.getFeatures();
var jsonData = geojson.writeFeatures( features,{
featureProjection: ol.proj.get('EPSG:3857'),
dataProjection: ol.proj.get('EPSG:4326')
});
return jsonData;
}
and the result was:
{"type":"FeatureCollection","features":[
{"type":"Feature","geometry":{
"type":"GeometryCollection","geometries":[]
},"properties":{
"circleCenter":[-4805776.093508227,-2600749.7153150304],"circleRadius":6658.801529937424
}
}]}
This is how I take the circle center and radius:
var draw = new ol.interaction.Draw({
source: vectorSource,
type: value, // Can be Circle,Point,Line,Polygon
// No Geometry Function when type is 'Circle' (omited code to simplify)
geometryFunction: geometryFunction,
maxPoints: maxPoints
});
draw.on('drawend', function( evt ){
var geometry = evt.feature.getGeometry();
// Check the type before try to get this! (omited code to simplify)
var center = geometry.getCenter();
var radius = geometry.getRadius();
evt.feature.set('circleCenter', center );
evt.feature.set('circleRadius', radius );
});
map.addInteraction( draw );
Now I'm trying to use this JSON to draw the same circle again, but it have no geometry and this is not working (work for all other geometries like point, polygong and line so the problem is it not the code):
var features = new ol.format.GeoJSON().readFeatures( jsonData, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
Just a note: I can see now the projection of center and radius was not changed. Must work on this too...
GeoJSON does not support Circle Geometry. So ol.format.GeoJSON() format doesnot convert JSON to ol.Feature object. So write a custom method which consumes the JSON data and creates a Circle geometry
var featuresJson = geoJson.features;
for ( var i=0; i<featuresJson.length; i++ ) {
var radius = featuresJson[i].properties.circleRadius;
var center = featuresJson[i].properties.circleCenter;
var feature = new ol.Feature(new ol.geom.Circle(center,radius);
vectorSource.addFeature(feature);
}
I think this can help me somehow... will see.
map.getViewport().addEventListener("dblclick", function(e) {
var coordinate = map.getEventCoordinate(e);
vectorSource.addFeature(new ol.Feature(new ol.geom.Circle(coordinate, dist)));
});
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.
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