three.js texture is not loading - three.js

by trying a tutorial ( http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/ ) the needed texture is not loading.
Here is my trying code in the index.html script area
<script src="js/jquery.js"></script>
<script src="js/threejs/build/three.js"></script>
<script>
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000 );
camera.position.z = 1.5;
var texture = THREE.ImageUtils.loadTexture('images/earthmap1k.jpg');
texture.anisotropy = 16;
var material = new THREE.MeshPhongMaterial( { map: texture } );
/*material.bumpMap = THREE.ImageUtils.loadTexture('images/earthbump1k.jpg');
material.bumpScale = 0.05;*/
var scene = new THREE.Scene();
var light = new THREE.AmbientLight(0x888888);
scene.add(light);
var light = new THREE.DirectionalLight( 0xCCCCCC, 1 );
light.position.set(5,3,5);
scene.add(light);
var earthMesh = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32), material);
scene.add(earthMesh);
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(window.innerWidth, window.innerHeight);
var $container = $('#container');
$container.append(renderer.domElement);
renderer.render(scene, camera);
</script>
so what I'm doing wrong here???
thanks for your help in advance
best regards
Karsten

try this..
var tUrl = "images/earthbump1k.jpg";
var texture = THREE.ImageUtils.loadTexture(tUrl, {}, createMesh);
function createMesh(texture){
var material = new THREE.MeshPhongMaterial( { map: texture } );
var earthMesh = new THREE.Mesh(new THREE.SphereGeometry(0.5, 32, 32), material);
scene.add(earthMesh);
}

Related

THREE.js Image aspect ratio

I am having trouble figuring out how to set a PlaneGeometry to a good aspect ratio based on the image size.
var material = new THREE.MeshBasicMaterial({
map : THREE.ImageUtils.loadTexture('img/bunny.png')
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(20, 20*.75), material);
plane.position.set(0, 10, -60)
scene.add(plane);
What I've tried so far sort of works, but I realise I'm still setting a fixed width/height on the Plane.
I'd like the plane to set the size of the image, then I could scale it down.
var planeGeom = new THREE.PlaneGeometry(20, 20);
var imgSrc = "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"
var mesh;
var tex = new THREE.TextureLoader().load(imgSrc, (tex) => {
tex.needsUpdate = true;
mesh.scale.set(1.0, tex.image.height / tex.image.width, 1.0);
});
var material = new THREE.MeshLambertMaterial({
color: 0xffffff,
map: tex
});
mesh = new THREE.Mesh(planeGeom, material);
scene.add(mesh);
//Working snippet is below...
var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
45, // Field of view
w / h, // Aspect ratio
0.1, // Near
10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.PointLight(0xFFFFFF);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);
var planeGeom = new THREE.PlaneGeometry(20, 20);
var imgSrc = "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"
var mesh;
var tex = new THREE.TextureLoader().load(imgSrc, (tex) => {
tex.needsUpdate = true;
mesh.scale.set(1.0, tex.image.height / tex.image.width, 1.0);
});
var material = new THREE.MeshLambertMaterial({
color: 0xffffff,
map: tex
});
mesh = new THREE.Mesh(planeGeom, material);
scene.add(mesh);
renderer.setClearColor(0xdddddd, 1);
(function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
The accepted answer works but has to use the callback to set the width since the loader is asynchronous. Nowadays one can also use the loadAsync method, which IMO makes the code more readable:
const getImageRatioPlane = async () => {
const texture = await new TextureLoader().loadAsync(imgSrc);
const material = new MeshBasicMaterial({ map: texture });
const geometry = new PlaneGeometry(texture.image.width, texture.image.height);
const plane = new Mesh(geometry, material);
}

Three.js PlaneBufferGeometry not rendering

I'm not able to render a planeBufferGeometry. Not sure what Im doing wrong. This is my first attempt with BufferGeometry. This works fine if I replace the code with a Geometry.Sphere or any other Geometry object.
var geometry = new THREE.PlaneBufferGeometry( 5, 20, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xCC0000, side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
scene.add(plane);
function update () {
// Draw!
renderer.render(scene, camera);
// Schedule the next frame.
requestAnimationFrame(update);
}
// Schedule the first frame.
requestAnimationFrame(update);
CAmera Position
const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;
// Set some camera attributes.
const VIEW_ANGLE = 45;
const ASPECT = WIDTH / HEIGHT;
const NEAR = 0.1;
const FAR = 10000;
// Get the DOM element to attach to
const container =
document.querySelector('#container');
// Create a WebGL renderer, camera
// and a scene
const renderer = new THREE.WebGLRenderer();
const camera =
new THREE.PerspectiveCamera(
VIEW_ANGLE,
ASPECT,
NEAR,
FAR
);
const scene = new THREE.Scene();
Thanks
Just an example with your code of instancing the buffer plane:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10); // set the position of the camera
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var geometry = new THREE.PlaneBufferGeometry(5, 20, 32, 32);
var material = new THREE.MeshBasicMaterial({
color: 0xCC0000,
side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material);
scene.add(plane);
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Assigning displacement/normal map to a single side of a cylinder

I have a cylinder created like this:
var geometry = new THREE.CylinderGeometry( 50, 50, 2, 128 );
It is a flat cylinder, like a coin. When I ad a displacementMap & normalMap, I end up with textures on both side of the cylinder, but I only want the maps to be on one side.
How can I do this?
For a THREE.CylinderGeometry a separated material for the shaft, the top plane and the bottom plane can be set:
var material1 = new THREE.MeshBasicMaterial({color:'#ff0000'});
var material2 = new THREE.MeshBasicMaterial({color:'#00ff00'});
var material3 = new THREE.MeshBasicMaterial({color:'#0000ff'});
var materialList = [material1, material2, material3];
var geometry = new THREE.CylinderGeometry( 50, 50, 2, 128 );
var mesh = new THREE.Mesh(geometry, materialList);
See the code snippet:
(function onLoad() {
var container, loader, camera, scene, renderer, controls, mesh;
init();
animate();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, -100, -100);
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
scene.add(camera);
window.onresize = resize;
var material1 = new THREE.MeshBasicMaterial({color:'#ff0000'});
var material2 = new THREE.MeshBasicMaterial({color:'#00ff00'});
var material3 = new THREE.MeshBasicMaterial({color:'#0000ff'});
var materialList = [material1, material2, material3];
var geometry = new THREE.CylinderGeometry( 50, 50, 2, 128 );
mesh = new THREE.Mesh(geometry, materialList);
scene.add(mesh);
controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
mesh.rotation.x += 0.01;
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://threejs.org/build/three.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script-->
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>
Use the thetaLength option of CylinderGeometry to separate it into two pieces.
// Create two half-cylinders.
var part1 = new THREE.CylinderGeometry( 50, 50, 2, 128, 1, false, 0, Math.PI );
var part2 = new THREE.CylinderGeometry( 50, 50, 2, 128, 1, false, Math.PI, Math.PI );
// Add the half-cylinders to a group, with different materials on each.
var group = new THREE.Group();
group.add( new THREE.Mesh( part1, material1 ) );
group.add( new THREE.Mesh( part2, material2 );
If you need more custom control than this, you probably want to use a modeling program like Blender to set up UVs and texture the cylinder.

ThreeJS BoxHelper scale Not working

var sphere = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ));
var box = new THREE.BoxHelper( object, 0xffff00 );
var gui = new dat.GUI();
gui.add(box.scale,'x',0,50).name('Width').listen();
the datgui shows the slider for box scale but changing it does not have any effect.Please help.
First, you have to set the color property ot the THREE.MeshBasicMaterial:
var boxGeometry = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( boxGeometry, new THREE.MeshBasicMaterial( {color:0xff0000} ));
Then you have to add the THREE.BoxHelper to the scene:
var box = new THREE.BoxHelper( object, 0xffff00 );
scene.add(boxHelper);
Further you have to change the scale property of the THREE.Mesh and not the scale property of the THREE.BoxHelper. But you have to update (onUpdate) the THREE.BoxHelper:
var gui = new dat.GUI();
gui.add(object.scale,'x',0.1,5).name('Width').onChange(function(){
boxHelper.update();
} );
See the code snippet:
(function onLoad() {
var container, loader, camera, scene, renderer, controls, boxHelper;
init();
animate();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(15, -20, 15);
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
controls = new THREE.OrbitControls(camera, renderer.domElement);
var boxGeometry = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( boxGeometry, new THREE.MeshBasicMaterial( {color:0xff0000} ));
scene.add(object);
boxHelper = new THREE.BoxHelper( object, 0x000000 );
scene.add(boxHelper);
var gui = new dat.GUI();
gui.add(object.scale,'x',0.1,5).name('Width').onChange(function(){
boxHelper.update();
} );
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://threejs.org/build/three.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script-->
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script>
<div id="container"></div>

Three.js load Image as texture not render

The g.png success loaded,but it not render.
Is it not loaded but render first?
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
Full code
https://gist.github.com/EasonWang01/410046ababc1af4f7f2db4b294b591ca
I write a sample based on your code, hope that will help you.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"> </script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry1 = new THREE.BoxGeometry( 12, 1, 1 );
var material1 = new THREE.MeshBasicMaterial( { color: 0x00FFCC } );
var cube1 = new THREE.Mesh( geometry1, material1 );
scene.add( cube1 );
var geometry2 = new THREE.BoxGeometry( 10, 1, 1 );
var material2 = new THREE.MeshBasicMaterial( { color: 0xCCFF33 } );
var cube2 = new THREE.Mesh( geometry2, material2 );
scene.add( cube2 );
var geometry3 = new THREE.CircleBufferGeometry( 3, 32 );
var material3 = new THREE.MeshBasicMaterial( { color: 0xCCFFCC } );
var circle3 = new THREE.Mesh( geometry3, material3 );
scene.add( circle3 );
var geometry4 = new THREE.BoxBufferGeometry( 10, 1, 1 );
material4 = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube4 = new THREE.Mesh( geometry4, material4 );
scene.add( cube4 );
var geometry = new THREE.CubeGeometry(150, 200, 150, 2, 2, 2);
var materials = [];
cube = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add(cube);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
camera.position.z = 5;
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube1.rotation.x += 0.02;
cube1.rotation.y += 0.02;
cube2.rotation.x += 0.03;
cube2.rotation.y += 0.03;
renderer.render(scene, camera);
};
setTimeout(() => {render();},500)
</script>
</body>
</html>

Resources