Blender Exported UV Map Texture Not Showing In Three JS - image

Blender Exported UV Map Texture Not Showing In Three JS
Greetings, Nov 13th 2014
Briefly, I am attempting to use the below code to aid three.js in recognizing the material from a blender exported file that has been successfully loaded while the morph influences work great! However, the UV mapped texture from within blender doesn't show up and there are no thrown errors to the console? I can easily use the imageutils to load the texture separately but of course the UV mapping is lost! Oddly when I do load the UV graphic separately I get the odd pattern that symbolizes a UV graphic but the significance defeats me?...I, new to three.js, have tried numerous code combinations as the below last attempt represents. Any ideas how to attempt three.js to recognize the UV material?
Appreciatively,
Ted
mesh = new THREE.Mesh(
geometry,
new THREE.MeshLambertMaterial({
THREE.UVMapping(THREE.ImageUtils.loadTexture("clothtexturegreenuv.jpg"),
morphTargets: true
})
);
mesh.scale.set( 35, 35, 35 );
scene.add( mesh );

Try this:
var mesh = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture( "clothtexturegreenuv.jpg"),
morphTargets: true
});
mesh.scale.set( 35, 35, 35 );
scene.add( mesh );

It works in the examples with MeshFaceMaterial automatically, no UVMapping or loadTexture calls are needed when the exported json already has the UVs and the texture reference I think. From the example at http://threejs.org/examples/webgl_loader_json_blender.html :
var loader = new THREE.JSONLoader();
loader.load( 'models/animated/monster/monster.js', function ( geometry, materials ) {
var faceMaterial = new THREE.MeshFaceMaterial( materials );
//(...) that example uses morph anims too but I cut the extras (...)
morph = new THREE.MorphAnimMesh( geometry, faceMaterial );
scene.add( morph );
}
We also document use of UVs + different maps in a manual there and it's similar (but only updated last spring for now whereas the threejs.org example is current): https://forge.fi-ware.org/plugins/mediawiki/wiki/fiware/index.php/3D-UI_-WebTundra-_User_and_Programmers_Guide#Exporting_3D_scenes_from_authoring_applications

Related

Color a tetrahedron in three.js

In three.js, I'm trying to draw a tetrahedron using THREE.TetrahedronGeometry where each face is a different color. When I use MeshNormalMaterial, each vertex has a different color but the faces are color gradients between the vertexes. This works for a BoxGeometry, but not for TetrahedronGeometry.
I tried using PhongMaterial with shading: THREE.FlatShading but that just gives me black or white faces.
I tried writing my own ShaderMaterial and in the fragment material, I color using the normal vector, but that also gets the gradient affect.
I'm sure I'm missing something obvious, but can't see it...
For versions of three.js prior to r125*, this is how you do it:
var geo = new THREE.TetrahedronGeometry(sphereRadius, 0);
for ( var i = 0; i < geo.faces.length; i ++ ) {
geo.faces[ i ].color.setHex( Math.random() * 0xffffff );
}
var material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
shading: THREE.FlatShading,
vertexColors: THREE.VertexColors
})
var mesh = new THREE.Mesh( geo, material );
So you need THREE.FlatShader, THREE.VertexColors, and then you need to assign the face colors.
For later versions, see how to render a tetrahedron with different texture on each face (using three.js)?.
* THREE.Geometry will be removed from core with r125

Why does this ThreeJs plane appear to get a kink in it as the camera moves down the y-axis?

I have an instance of THREE.PlaneBufferGeometry that I apply an image texture to like this:
var camera, scene, renderer;
var geometry, material, mesh, light, floor;
scene = new THREE.Scene();
THREE.ImageUtils.loadTexture( "someImage.png", undefined, handleLoaded, handleError );
function handleLoaded(texture) {
var geometry = new THREE.PlaneBufferGeometry(
texture.image.naturalWidth,
texture.image.naturalHeight,
1,
1
);
var material = new THREE.MeshBasicMaterial({
map: texture,
overdraw: true
});
floor = new THREE.Mesh( geometry, material );
floor.material.side = THREE.DoubleSide;
scene.add( floor );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, texture.image.naturalHeight * A_BUNCH );
camera.position.z = texture.image.naturalWidth * 0.5;
camera.position.y = SOME_INT;
camera.lookAt(floor.position);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
appendToDom();
animate();
}
function handleError() {
console.log(arguments);
}
function appendToDom() {
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene,camera);
}
Here's the code pen: http://codepen.io/anon/pen/qELxvj?editors=001
( Note: ThreeJs "pollutes" the global scope, to use a harsh term, and then decorates THREE using a decorator pattern--relying on scripts loading in the correct order without using a module loader system. So, for brevity's sake, I simply copy-pasted the source code of a few required decorators into the code pen to ensure they load in the right order. You'll have to scroll down several thousand lines to the bottom of the code pen to play with the code that instantiates the plane, paints it and moves the camera. )
In the code pen, I simply lay the plane flat against the x-y axis, looking straight up the z-axis, as it were. Then, I slowly pan the camera down along the y-axis, continuously pointing it at the plane.
As you can see in the code pen, as the camera moves along the y-axis in the negative direction, the texture on the plane appears to develop a kink in it around West Texas.
Why? How can I prevent this from happening?
I've seen similar behaviour, not in three.js, not in a browser with webGL but with directX and vvvv; still, i think you'll just have to set widthSegments/heightSegments of your PlaneBufferGeometry to a higher level (>4) and you're set!

three js envMap using one texture

I have a code:
var urls = [ 'img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png' ];
var textureCube = THREE.ImageUtils.loadTextureCube( urls, new THREE.CubeRefractionMapping );
var cubeMaterial3 = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube, refractionRatio: 0.98, reflectivity:0.9 } );
mesh = new THREE.Mesh( wormholeGeom, cubeMaterial3 );
scene.add(mesh);
This successfully works and inserts sphere with refraction map.
But i do not using skybox, but skysphere where is whole sky represented by one texture.
Is the way to make a refraction mapping from one texture?
Not by array of six textures?
I tried many thinks (THREE.ImageUtils.loadTexture,THREE.SphericalRefractionMapping too) but no luck.
Documentation is "TODO".
This is my goal, but with one texture in skydome. There are used 6 textures in square to make sky.

Setting texture on mesh in three.js

I have a mesh that I load as a .dae (collada). However, my texture file is separate (as a PNG)
Currently, my loading code is
loader.load("./assets/map_tutorial.dae", function(collada) {
var terrain = collada.scene.children[0];
var texture = new THREE.ImageUtils.loadTexture("./assets/map_tutorial_tex.png");
terrain.rotation.x = Math.PI / 2;
terrain.rotation.y = Math.PI;
scene.add(terrain);
console.log("There are " + collada.scene.children.length + " meshes!");
});
However, I'm uncertain as to how to apply the texture to my mesh (terrain)
Thanks in advance!
You will definitely have to create new material object from your texture. Assuming you want lambert, it would be like this:
var material = new THREE.MeshLambertMaterial( { map:texture } );
I am not familiar with collada loader, but it seems that it already created a mesh for you. In this case I am not sure whether you can change material of this mesh. What should definitely work is to create new mesh from geometry that you loaded from .dae file and material that you created from png image.
var mesh = new THREE.Mesh( terrain.geometry, material );
scene.add( mesh );
I hope this helps, normally I use three.js native JSON model files where this approach is working. Difference is that THREE.JSONLoader gives you two objects for your usage: geometry and materials. Collada loader seems to provide you with already created mesh so try to change it's geometry if possible or "steal" the geometry from this mesh and create a new one like I did in the example.

Materials in exported Blender model for Three.js not working

I am trying to use a model created with Blender with Three.js The model is very basic, two cubes on top of each other. One cube is red and the other is green.
I have exported the model using the Blender exporter plugin of Three.js When I assign a material manually to the object like:
loader.load("model.js", function ( geometry, material ) {
material = new THREE.MeshBasicMaterial( { color: 0xFF0000 } );
mesh = new THREE.Mesh( geometry, material);
scene.add(mesh);
animate();
});
there is no problem as shown at https://googledrive.com/host/0B9t0vRo6sUnzWndDTGxicENIdDg/index.html
However when I remove the line:
material = new THREE.MeshBasicMaterial( { color: 0xFF0000 } );
the material of the model is used. Which produces an error of Three.js:
TypeError: program is undefined [Break On This Error]
p_uniforms = program.uniforms,
You can see this for yourself at https://googledrive.com/host/0B9t0vRo6sUnzWndDTGxicENIdDg/index2.html
Does anyone have an idea what could cause this problem? You can download the Blender file at https://googledrive.com/host/0B9t0vRo6sUnzWndDTGxicENIdDg/model.blend
Easy. The materials is an array. You need to do the following:
loader.load( "model.js", function ( geometry, materials ) {
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
animate();
} );
three.js r.88

Resources