I’m trying to create a 3D playing card with a little thickness by using extrudeGeometry, but the images for the card face and back appear tiny and at the center of the card rather than stretched to the edges of the selected faces. Oddly, the colors seem to be stretched, but not the image.
(That tiny dot at the center of the card is the actual image)
I’ve tried using an image with dimensions of power of 2, but same result.
In the past I’ve used pretty much the same approach with cylinderGeometry, and it’s worked fine:
Here’s my current code. I’ve tested to ensure I’ve assigned the right materials to the right faces.
/// RENDERER
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( window.innerWidth*2, window.innerHeight*2 ); //sets the canvas at double-size for higher resolution
let canvasDiv = document.getElementById("canvas_div");
canvasDiv.appendChild( renderer.domElement );
let canvas = document.getElementsByTagName('canvas')[0];
canvas.style.width = window.innerWidth + "px"; //shrinks the canvas to the window's size while keeping high resolution
canvas.style.height = window.innerHeight + "px"; //shrinks the canvas to the window's size while keeping high resolution
/// 3D ENVIRONMENT
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera( 35, window.innerWidth/window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, 150 );
scene.add( camera );
let controls = new THREE.OrbitControls( camera, renderer.domElement );
/// LIGHT
renderer.setClearColor ( 0xF2F2F2, 1 ); // background color
let lightA1 = new THREE.AmbientLight(0xFFFFFF, 0.8);
scene.add(lightA1);
let lightD1 = new THREE.DirectionalLight( 0xFFFFFF, 0.3 );
lightD1.position.set( -250, 300, 150 );
scene.add( lightD1 );
/// CARD
let cardWidth = 25;
let cardHeight = 35;
let cardDepth = cardWidth/50;
let hw = cardWidth/2; // half width
let hh = cardHeight/2; // half height
let hd = cardDepth/2; // half depth
let cr = 1.4; // corner radius
let bhl = cr*.552; // bezier handle length (for perfect circle curve)
let bdc = cr-bhl; // bezier handle distance from corner
let cardShape = new THREE.Shape();
cardShape.moveTo( -hw+cr, hh );
cardShape.lineTo( hw-cr, hh );
cardShape.bezierCurveTo( hw-bdc, hh, hw, hh-bdc, hw, hh-cr );
cardShape.lineTo( hw, -hh+cr );
cardShape.bezierCurveTo( hw, -hh+bdc, hw-bdc, -hh, hw-cr, -hh );
cardShape.lineTo( -hw+cr, -hh);
cardShape.bezierCurveTo( -hw+bdc, -hh, -hw, -hh+bdc, -hw, -hh+cr );
cardShape.lineTo( -hw, hh-cr);
cardShape.bezierCurveTo( -hw, hh-bdc, -hw+bdc, hh, -hw+cr, hh );
let extrudeGeometry = new THREE.ExtrudeGeometry( cardShape, { depth: cardDepth, bevelEnabled: false } );
let materialsArray = [];
let cardBackImage = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/409445/figgie-card-back-po2.png";
let cardHeartImage = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/409445/figgie-card-heart-1.png";
let cardSidesMaterial = new THREE.MeshLambertMaterial( { color: "red" /*0x444FA1*/ } );
materialsArray.push( cardSidesMaterial ); //(materialindex = 0)
let cardBackLoader = new THREE.TextureLoader();
cardBackLoader.load( cardBackImage, function ( texture ) {
let cardBackMaterial = new THREE.MeshBasicMaterial( { map: texture } );
materialsArray.push( cardBackMaterial ); //(materialindex = 1)
});
let cardHeartLoader = new THREE.TextureLoader();
cardHeartLoader.load( cardHeartImage, function ( texture ) {
let cardHeartMaterial = new THREE.MeshBasicMaterial( { map: texture } );
materialsArray.push( cardHeartMaterial ); //(materialindex = 2)
});
let faceCount = extrudeGeometry.faces.length;
for ( let i=0; i<faceCount; i++ ) {
if ( i < 50 ) {
extrudeGeometry.faces[i].materialIndex = 1;
} else if ( i < 100 ) {
extrudeGeometry.faces[i].materialIndex = 2;
} else {
extrudeGeometry.faces[i].materialIndex = 0;
}
}
let card = new THREE.Mesh( extrudeGeometry, materialsArray );
scene.add( card );
/// RENDERING
function render() {
requestAnimationFrame( render );
camera.updateProjectionMatrix();
renderer.render( scene, camera );
};
render();
/// INTERACTION
function onWindowResize() {
let sceneHeight = window.innerHeight;
let sceneWidth = window.innerWidth;
canvas.style.width = window.innerWidth + "px";
canvas.style.height = window.innerHeight + "px";
camera.aspect = sceneWidth/sceneHeight;
camera.updateProjectionMatrix();
}
window.addEventListener('resize', onWindowResize, false);