three.js - Model showing with blank (black) texture despite material loaded - three.js

I have a 3D model file 3dbaotang.obj and a material file 3dbaotang.mtl. I've loaded both of them using three.js OBJLoader and MTLLoader. The model has shown up, but not the material, as it's solely covered with black. Can anyone help?
Here is my code:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth /
window.innerHeight, 0.1, 10000);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var keyLight = new THREE.DirectionalLight('hsl(30, 100%, 75%)', 1.0);
var fillLight = new THREE.DirectionalLight('hsl(240, 100%, 75%)', 0.75);
var backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
keyLight.position.set(-100, 0, 100);
fillLight.position.set(100, 0, 100);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.update();
renderer.setSize(window.innerWidth, window.innerHeight, false);
renderer.setClearColor(new THREE.Color(0xf2f2f2), 1);
document.body.appendChild(renderer.domElement);
// LOAD MODEL
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setResourcePath('/models/');
mtlLoader.setPath('/models/');
mtlLoader.load('/3dbaotang.mtl', (materials) => {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('/models/');
objLoader.load('3dbaotang.obj', (object) => {
scene.add(object);
});
});
camera.position.z = 200;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
Result:

Adding to Brother Eye's answer, I'm brand new and and spent quite a lot of time in the dark but this got me on to the solution so I thought I'd elaborate for anyone in the same position.
Adding a light can be some simply as follows;
//Add light
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
The reference docs are located at https://threejs.org/docs/#api/en/lights/AmbientLight

It was the lack of light that caused this problem, not the material. After adding ambient light to the scene, the object can be seen normally

Related

Bringing back the object to the starting position

Here I'm trying to bring back the object to the starting position in the button click. I tried with some fixing the position of the object with the static position where I have no idea where it works or not. I have searched for solutions where they say to move the camera to FOV direction axis(say calculating the x, y, z).
In detail, if I pan or rotate aa object from initial position to different position, in button click I have to undo it to the the start position.
Here's the https://jsfiddle.net/Ajay_Venkatesh/thpb8csv/1/
'use strict';
var camera, scene, renderer;
var cube, cube_geometry, cube_material;
var controls;
init();
render();
function init() {
scene = new THREE.Scene();
// renderer
renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// camera
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 12;
// controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.enableZoom = false;
// mesh - cube
cube_geometry = new THREE.CubeGeometry(5, 5, 5);
for (var i = 0; i < cube_geometry.faces.length; i += 2) {
var color = Math.random() * 0xffffff;
cube_geometry.faces[i].color.setHex(color);
cube_geometry.faces[i + 1].color.setHex(color);
}
cube_material = new THREE.MeshLambertMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors
});
cube = new THREE.Mesh(cube_geometry, cube_material);
scene.add(cube);
// Lights
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
var light = new THREE.DirectionalLight(0x002288);
light.position.set(-1, -1, -1);
scene.add(light);
var light = new THREE.AmbientLight(0x222222);
scene.add(light);
// events
window.addEventListener('resize', onWindowResize, false);
}
function render() {
renderer.render(scene, camera);
}
function onWindowResize(event) {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}

three.js: Image in panorama viewer is rippled

Currently I'm making myself familiar with three.js and created a simple panorama viewer:
http://webentwicklung.ulrichbangert.de/threejs-image-on-sphere-inside.html
Unfortunately the vertical edges of the pillars are rippled.
When using the panorama viewer of Panorama Studio everything is fine:
http://ulrichbangert.de/heimat/Halberstadt/2018-06-10_Halberstadt_Dom_Panorama.html
var width = window.innerWidth,
height = window.innerHeight;
var scene = new THREE.Scene();
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 3, 5);
scene.add(light);
var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000);
camera.position.z = 1;
camera.fov = Math.max(100, Math.min(200, camera.fov));
camera.updateProjectionMatrix();
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var loader = new THREE.TextureLoader();
loader.load('images/panorama.jpg', function (texture) {
texture.anisotropy = renderer.getMaxAnisotropy();
var material = new THREE.MeshBasicMaterial({
map: texture
});
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(20, 32, 32),
material
);
sphere.scale.x = -1;
sphere.rotation.x = -0.5;
scene.add(sphere);
var animate = function () {
requestAnimationFrame(animate);
sphere.rotation.y += 0.002;
renderer.render(scene, camera);
};
animate();
});
What's going wrong here?
Try adding more subdivisions to your SphereGeometry. Right now you have 32 lat & long subdivisions, which creates some unsightly straight-line deformations to your texture. If you do something like new THREE.SphereGeometry(20, 100, 100), you'll get better fidelity when texture mapping.

Basic THREE.js scene setup

my question is simple but for the life of me i cannot figure out what is going on. I am trying to set up a basic three.js scene and add a simple cube with a BaiscMaterial however the cube is not showing up in my scene.
"use strict";
var renderer, scene, camera;
var light;
function init() {
var canvasWidth = 850;
var canvasHeight = 450;
var canvasRatio = canvasWidth / canvasHeight;
camera = new THREE.PerspectiveCamera(45, canvasRatio, 0.9, 1000);
camera.position.set(0, 200, -550);
camera.lookAt(0, 0, 0);
light = new THREE.AmbientLight(0xFFFFFF, 1);
light.position.set(-800, 900, 300);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(canvasWidth, canvasHeight);
renderer.setClearColorHex(0x000000, 1.0); //canvas color
renderer.gammaInput = true;
renderer.gammaOutput = true;
}
function cube() {
var cubeGeo = new THREE.CubeGeometry(1000, 1000, 1000);
var cubeMaterial = new THREE.MeshBasicMaterial();
var cube1 = new THREE.Mesh(cubeGeo, cubeMaterial);
cube1.position.set(0, 0, 0);
return cube1;
}
function fillScene() {
scene = new THREE.Scene();
scene.add(light);
var cube = cube();
scene.add(cube);
}
function addToDOM() {
var container = document.getElementById('container');
var canvas = container.getElementsByTagName('canvas');
if (canvas.length > 0) {
container.removeChild(canvas[0]);
}
container.appendChild(renderer.domElement);
}
function render() {
fillScene();
renderer.render(scene, camera);
}
try {
init();
fillScene();
addToDOM();
render();
} catch (e) {
var errorReport = "Your Program encountered an ERROR, cannot draw on canvas. Error was:<br/><br/>";
$('#container').append(errorReport + e);
}
First of all, Cube is updated to BoxGeometry now. And I see lots of problem on your code and improper function definition and usage.
Here's a very simple example from mr.doob's Github.
var scene, camera, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
geometry = new THREE.BoxGeometry( 200, 200, 200 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
See the demo here
P.S Three.js Docs is the best place for resources, it makes work alot easier with tons of example code.

Icosahedron geometry not rendering

I'm just learning how to do this three.js magic. I'm able to draw and animate a cube. But when I change the geometry to an Icosahedron nothing appears.
Inside my js src forlder I only have the three.min.js file. Do I need another .js file in there?
Here is a sample of my code. I'm just a beginner, and have been spending hours trying to figure this out. Please help.
<body>
<script src="js/three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
/*var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshLambertMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);*/
var geometry = new THREE.IcosahedronGeometry( 200,1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00, wireframe: false, wireframeLinewidth: 2 } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var pointlight = new THREE.PointLight(0xffffff);
pointlight.position.x = 10;
pointlight.position.y = 50;
pointlight.position.z = 1000;
scene.add(pointlight)
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.x += .01;
cube.rotation.y += .01;
renderer.render(scene, camera);
};
render();
</script>
</body>
I know this is an old post but for future visitors, here's the question answered with live code.
I also went ahead and cleaned it up a bit and annotated some comments to help point out how I solved your problem.
<body>
<script src="https://threejs.org/build/three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 5;
var pointlight = new THREE.PointLight(0xffffff);
pointlight.position.x = 10;
pointlight.position.y = 50;
pointlight.position.z = 1000;
scene.add(pointlight)
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var mesh = new THREE.Mesh(
// Notice radius decreased to 2 because it has to be smaller
// than camera.position. If camera is placed inside the mess,
// then we won't see it.
new THREE.IcosahedronGeometry(2, 0),
// I went ahead and added Phong shading in order to make result clearer
new THREE.MeshPhongMaterial({
color: 0x156289,
emissive: 0x072534,
side: THREE.DoubleSide,
flatShading: true,
}),
);
scene.add(mesh);
var render = function() {
requestAnimationFrame(render);
// fixed the rotation to reference your mesh
mesh.rotation.x += .01;
mesh.rotation.y += .01;
renderer.render(scene, camera);
};
render();
</script>
</body>

Importing 3D model exported from Blender/maya in Threejs and rendering it using CanvasRenderer for iPad

Am trying to create an app which will import the 3D model exported from Blender/Maya into ThreeJS. I have installed Blender and three js export option is also coming, however when am trying to load the exported JS (I tried renaming extension to json also) it is not working and showing blank screen. Can anyone help me with this by providing a sample code for this?
TIA.
Regards,
NileshW
add a div to the body
<div id="myScene"></div>
then..
<script>
// global
var scene, renderer, camera, cube, controls;
init();
animate();
function init() {
// scene box
var myScene = document.getElementById("myScene");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, .01, 10000);
camera.position.z = 500;
var light = new THREE.AmbientLight(0xffffff); // soft white light
scene.add(light);
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
/* ==== OPTIONAL SPOTLIGHT ====
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100, 1000, 2000);
spotLight.castShadow = true;
spotLight.shadowMapWidth = 1024;
spotLight.shadowMapHeight = 1024;
spotLight.shadowCameraNear = 500;
spotLight.shadowCameraFar = 4000;
spotLight.shadowCameraFov = 30;
scene.add(spotLight);
*/
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
myScene.appendChild(renderer.domElement);
loader = new THREE.JSONLoader();
loader.load("your_json_file.js", function (geometry, materials) {
mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial(materials));
scene.add(mesh);
});
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
Have you tried the code from chawk - just change to use your test.js (check folder path)
If the code in you function init() is complete then it looks like you've missed a couple of things
You have created a camera, created a scene, created a loader, loaded a file and added mesh to the scene
You need to add the camera to the scene
You also need to add some light(s) to your scene
var camera, scene, renderer;
var geometry, material, mesh;
var controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 5, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 50, 50, 50 );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
scene = new THREE.Scene();
var light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
// Load in the mesh and add it to the scene.
var loader = new THREE.JSONLoader();
loader.load( "models/testnew.js", function(geometry){
var material = new THREE.MeshNormalMaterial({color: 0x55B663});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
//
renderer = new THREE.CanvasRenderer();
renderer.setSize( 1000, 600);
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}

Resources