I'm trying to create a three.js cube with different textures on each face.
Basically a dice. This is in my sandbox environment, so should just product a rotating cube with dice images (1-6) on each side. Once done I intend to use this for a browser base game. This example I have only tested in Chrome, although contemplating changing it to a canvas renderer for additional browser support.
Had a look at a few questions here on SO and a substantial amount of other googling, and though I had the answer (seemed reasonably simple actually) but I simply cannot get it to work.
I am reasonably new to three.js, but not JavaScript.
Pages I used for reference are
SO - three.js cube with different texture on each face
SO - three.js cube with different texture faces
evanz - Test three.js cube
and enriquemorenotent.com - three.js building a cube with different materials on each face
My Code
var camera, scene, renderer, dice;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(110, 110, 250);
camera.lookAt(scene.position);
scene.add(camera);
var materials = [
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-1-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-2-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-3-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-4-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-5-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-6-hi.png')
})
];
dice = new THREE.Mesh(
new THREE.CubeGeometry(562, 562, 562, 1, 1, 1, materials),
new THREE.MeshFaceMaterial());
scene.add(dice);
}
function animate() {
requestAnimationFrame(animate);
dice.rotation.x += .05;
dice.rotation.y += .05;
dice.rotation.z += .05;
renderer.render(scene, camera);
}
The error I am getting is
Uncaught TypeError: Cannot read property 'map' of undefined
from three.js line 19546 (not the min version) WHichi is the bufferGuessUVType(material) function - material is undefined. Which leads me to believe something is not right in one/all of my material definitions.
Using three.js r58.
There is really no HTML or CSS, just the JS at this point
I can quite happily get a cube rotating with the same image on all six sides but not with different images. The images are just the images of a dice dots, 1 - 6.
Given a bit more time I could do a fiddle if required
EDIT: THREE.MultiMaterial has been deprecated. You can now pass the materials array directly into the constructor. Like so:
dice = new THREE.Mesh( new THREE.BoxGeometry( 562, 562, 562, 1, 1, 1 ), materials );
scene.add( dice );
Be careful of copying old examples from the net.
Always check the Migration Wiki for help upgrading to the current version.
three.js r.85
Related
I'm trying to learn the capabilities of ThreeJS by making a small game. I have an animated sprite that is working great in my scene by using a PlaneGeometry and using a png texture in my MeshBasicMaterial but unfortunately even though my png has an alpha channel, the mesh is displaying the alpha channel as black when instead I'd prefer it to obviously be transparent. Is there a way to correct this?
//this is a customer function you can see at the top of my codepen
texture = new THREE.SpriteSheetTexture('assets/monster.png', 4, 1, 250, 4);
//loading the basic material here
var material = new THREE.MeshBasicMaterial({
map: texture
});
geometry = new THREE.PlaneGeometry(1, 1, 1, 1);
monster = new THREE.Mesh( geometry, material );
scene.add( monster );
You can view how I have the code laid out here, note though, I cannot get the png resource working on codepen:
https://codepen.io/GreedFeed/pen/yrqpQY
You've to set the .transparent property of the THRRE.Material which states the material transparent and activates the special treatment of transparent objects:
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true
});
I'm following along with this youTube tutorial https://www.youtube.com/watch?v=axGQAMqsxdw to create a POV game. I got to episode 8 of the tutorial, then google chrome began showing a white screen no matter what I changed in the javascript. There are no warnings or problems when inspecting the code with chrome's developer tools either.
I've tried to start from scratch with completely new files. I've cleared the caches for chrome. I've double checked the source code with my altered code, but none of my alterations seem like they would cause a problem (I am new to javascript though, so that could be a problem). Below is the newly started js file based 100% off the youTube tutorial.
var scene, camera, renderer, mesh;
function init(){
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x8CD9FF );
camera = new THREE.PerspectiveCamera (90, 1280/720, 0.1, 10);
mesh = new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshBasicMaterial ({color: 0xff9999, wireframe: true})
);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(1280/720);
document.body.appendChild(renderer.domElement);
animate();
}
function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
}
window.onload = init;
Take a look at the THREE documentation concerning renderer size here.
You need to set width and height pixels and not the ratio, so try to replace renderer.setSize(1280/720); with renderer.setSize(1280, 720)
I'm trying to create a three.js cube with different textures on each face.
Basically a dice. This is in my sandbox environment, so should just product a rotating cube with dice images (1-6) on each side. Once done I intend to use this for a browser base game. This example I have only tested in Chrome, although contemplating changing it to a canvas renderer for additional browser support.
Had a look at a few questions here on SO and a substantial amount of other googling, and though I had the answer (seemed reasonably simple actually) but I simply cannot get it to work.
I am reasonably new to three.js, but not JavaScript.
Pages I used for reference are
SO - three.js cube with different texture on each face
SO - three.js cube with different texture faces
evanz - Test three.js cube
and enriquemorenotent.com - three.js building a cube with different materials on each face
My Code
var camera, scene, renderer, dice;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(110, 110, 250);
camera.lookAt(scene.position);
scene.add(camera);
var materials = [
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-1-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-2-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-3-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-4-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-5-hi.png')
}),
new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('/Content/Images/dice-6-hi.png')
})
];
dice = new THREE.Mesh(
new THREE.CubeGeometry(562, 562, 562, 1, 1, 1, materials),
new THREE.MeshFaceMaterial());
scene.add(dice);
}
function animate() {
requestAnimationFrame(animate);
dice.rotation.x += .05;
dice.rotation.y += .05;
dice.rotation.z += .05;
renderer.render(scene, camera);
}
The error I am getting is
Uncaught TypeError: Cannot read property 'map' of undefined
from three.js line 19546 (not the min version) WHichi is the bufferGuessUVType(material) function - material is undefined. Which leads me to believe something is not right in one/all of my material definitions.
Using three.js r58.
There is really no HTML or CSS, just the JS at this point
I can quite happily get a cube rotating with the same image on all six sides but not with different images. The images are just the images of a dice dots, 1 - 6.
Given a bit more time I could do a fiddle if required
EDIT: THREE.MultiMaterial has been deprecated. You can now pass the materials array directly into the constructor. Like so:
dice = new THREE.Mesh( new THREE.BoxGeometry( 562, 562, 562, 1, 1, 1 ), materials );
scene.add( dice );
Be careful of copying old examples from the net.
Always check the Migration Wiki for help upgrading to the current version.
three.js r.85
In three.js, I am trying to create a texture whose image is the current scene as viewed from a Camera. Using a CubeCamera to create a similar effect is well-documented; and with CubeCamera I have created an example of a scene to illustrate my goal at:
http://stemkoski.github.com/Three.js/Camera-Texture-Almost.html
However, I would like to use a regular Camera (rather than a CubeCamera) as the texture. How could I do this?
Ideally this would work.
Init:
renderTarget = new THREE.WebGLRenderTarget( 512, 512, { format: THREE.RGBFormat } );
var planelikeGeometry = new THREE.CubeGeometry( 400, 200, 200 );
var plane = new THREE.Mesh( planelikeGeometry, new THREE.MeshBasicMaterial( { map: renderTarget } ) );
plane.position.set(0,100,-500);
scene.add(plane);
Render:
renderer.render( scene, topCamera, renderTarget, true );
renderer.render( scene, topCamera );
And it almost does, but we have some unfinished business with y-flipped textures that ruins the party here.
So the best solution at the moment is to use the intermediry quad for flipping the texture (also saves a render):
http://mrdoob.github.com/three.js/examples/webgl_rtt.html
Based on mrdoob's example and suggestions, I have created a working example with very detailed comments, available at:
http://stemkoski.github.com/Three.js/Camera-Texture.html
part of my series of tutorial-style Three.js series of examples at
http://stemkoski.github.com/Three.js/
I am trying to create a spherical panorama using THREE.js. It works great on Safari Desktop but crashes on Safari Mobile on the iPAD. It has something to do with the way I'm loading up the texture image.
A few things I've tried
I'm using the Canvas Renderer
Tried loading up an image of a smaller size.
Tried loading up a power of 2 texture image.
Tried loading the Sphere with a wireframe material - It works!
Here's my code.
http://pastebin.com/1nwTMHJV
sceneHolder = document.getElementById( 'sceneHolder' );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 60, SCENE_WIDTH / SCENE_HEIGHT, 1, 10000 );
camera.position.z = 0;
scene.add( camera );
var sphereGeom = new THREE.SphereGeometry( 200, 20, 20 );
//NOTE: If we add {},function(){render()} in the following, it stops working!
var sphereTexture = THREE.ImageUtils.loadTexture('media/vr/testpot.jpg');
mesh = new THREE.Mesh(sphereGeom,new THREE.MeshBasicMaterial({map:sphereTexture,overdraw:true}));
//So that we see the inside of the sphere too!
mesh.doubleSided=true;
scene.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( SCENE_WIDTH, SCENE_HEIGHT );
sceneHolder.appendChild( renderer.domElement );
Here's my post on THREE.js
https://github.com/mrdoob/three.js/issues/1529
Also: https://github.com/mrdoob/three.js/issues/1550
Thanks
smaira
I tried, lowering number of faces can run on iPad, but it's just ugly.
you may try:
var sphereGeom = new THREE.SphereGeometry( 200, 10, 10 );
and the safari crash at the time of render
renderer.render( scene, camera );
conclusion:
if load image texture to sphere with too many faces, iPad will crash