Three.js not rendering cube with custom texture - three.js

I'm trying to render a three.js box that has custom textures which I'm loading using THREE.TextureLoader().
While I see THREE.WebGLRenderer 87 in my console, there doesn't seem to be any cube being rendered.
I've created a fiddle to show how I'm attempting to do it: http://jsfiddle.net/hfj7gm6t/4786/
Note that I'm just using one url for all 6 side's textures for simplicity's sake.
Can anybody please help me understand why my beloved cube isn't showing?

First you need a render loop, you cannot just call renderer.render once. Then you need to position your camera correctly and make sure it is actually looking at your cube:
let textureUrls = [
'https://i.imgur.com/wLNDvZV.png', 'https://i.imgur.com/wLNDvZV.png', 'https://i.imgur.com/wLNDvZV.png',
'https://i.imgur.com/wLNDvZV.png', 'https://i.imgur.com/wLNDvZV.png', 'https://i.imgur.com/wLNDvZV.png'
];
let renderer = null
let camera = null
let scene = null
function renderMap(urls) {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
60, window.innerWidth / window.innerHeight, 1, 100000 );
camera.position.x = 500;
camera.position.y = 500;
camera.position.z = -500;
camera.lookAt(new THREE.Vector3(0, 0, 0))
let textureLoader = new THREE.TextureLoader();
let materials =
urls.map((url) => {
return textureLoader.load(url);
}).map((texture) => {
return new THREE.MeshBasicMaterial({map: texture})
});
let mesh = new THREE.Mesh(new THREE.BoxGeometry(200, 200, 200), materials);
scene.add(mesh);
}
function init() {
renderMap(textureUrls);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
render();
}
function render() {
requestAnimationFrame(render)
renderer.render(scene, camera)
}
init()

Related

Create cone geometry with flat base in three.js?

Trying to figure out how to create something that looks like the image below... Tried searching around but couldn't really figure it out...
Try it with CylinderGeometry. This class allows to define different radii for the top and bottom.
let mesh;
let camera, scene, renderer;
init();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 2;
scene = new THREE.Scene();
const geometry = new THREE.CylinderGeometry(0.2, 0.5, 1, 16);
const material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);
}
function animation(time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.133.1/build/three.min.js"></script>

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

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

Rendering to texture within a-frame

I'm trying to implement something very similar to this...
https://stemkoski.github.io/Three.js/Camera-Texture.html
... as an a-frame component. However, I'm getting merely a blank white on the quad which is supposed to be "monitoring" this extra camera. It changes to black when entering VR mode.
Here is my code:
AFRAME.registerComponent('viewfinder', {
schema:{
//
},
init:function(){
this.renderer = new THREE.WebGLRenderer({antialias:true});
this.renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild(this.renderer.domElement);
this.dronecamera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
this.dronecamera.position.z=5;
this.monitorbuffercam = new THREE.OrthographicCamera(window.innerWidth/-2, window.innerWidth/2, window.innerHeight/2, window.innerHeight/-2, -10000, 10000);
this.monitorbuffercam.position.z=1;
this.buffertexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { format: THREE.RGBFormat });
this.monitortexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { format: THREE.RGBFormat });
this.bufferscene = new THREE.Scene();
var ambientlight = new THREE.AmbientLight(0xffffff);
this.bufferscene.add(ambientlight);
var bufferplaneG = new THREE.PlaneGeometry( window.innerWidth, window.innerHeight);
var bufferplaneM = new THREE.MeshBasicMaterial({map:this.buffertexture});
this.bufferplane = new THREE.Mesh(bufferplaneG, bufferplaneM);
this.bufferscene.add(this.bufferplane);
this.bufferscene.add(this.monitorbuffercam);
this.el.sceneEl.object3D.add(this.dronecamera);
this.monitorplaneG = new THREE.PlaneGeometry(10, 10);
this.monitorplaneM = new THREE.MeshBasicMaterial({map:this.monitortexture});
this.monitor = new THREE.Mesh(this.monitorplaneG, this.monitorplaneM);
this.el.setObject3D('monitor', this.monitor);
},
tick:function(){
var r = this.renderer;
var s = this.el.sceneEl.object3D;
var bs = this.bufferscene;
var dc = this.dronecamera;
var bt = this.buffertexturee;
var mbc = this.monitorbuffercam;
var mt = this.monitortexture;
requestAnimationFrame(draw);
function draw(){
r.render(s, dc, bt, true);
r.render(bs, mbc, mt, true);
}
}
});
Any help is greatly appreciated. I'm attempting to follow the model from the three.js example, rendering from a camera in the main scene to a quad texture map in a separate off-screen scene, then pointing an orthographic camera at it, and rendering that camera's view to a texture map back in the main scene. I have a hunch that there is merely some boilerplate code I'm forgetting or I'm doing wrong.
Thanks in advance!
I'm not sure if this what you're looking for, but maybe this answer to AFrame: How to render a camera to a texture could be of some help. In short, it shows how to use a component that creates a renderer for a secondary camera, that can be referenced as material for an object.

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.

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