I have one large image that I am loading as a texture. I then have several cubes that I am trying to apply this texture to. The problem is that when the texture is applied, it scales the image to the width and height of the cube. What i want to do is to ensure that no scaling happens, then I can move the "offset" of the texture to pick the portion I want to show.
Can anyone point me in the right direction?
For example , if my texture is 800x2000. And I have a 100x100 cube, I want to show a 100x100 portion of that big texture, offset at like 300x400. So something like:
tex = THREE.ImageUtils.loadTexture('texture.png');
tex.left = 300
tex.top = 400
var pictureMaterial = new THREE.MeshBasicMaterial({map: tex});
Do I need to leverage canvas textures for this?
Ok I am getting there, but I need to find documentation for how to use the offset and repeat parameters. They seem to need to be between 0 and 1, and not sure how to get a value that converts to pixels.
tex = THREE.ImageUtils.loadTexture('texture.png');
tex.offset.x = ?
tex.offset.y = ?
tex.repeat.x = ?
tex.repeat.y = ?
Posting my solution in case it is helpful to anyone else. I ended up using canvas for the texture and loading/cropping the image on there instead. Seems to work fine so far.
canvas = document.createElement('canvas');
canvas.height=200;
canvas.width=200;
ctx = canvas.getContext('2d');
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, 200, val.200);
//this is where we set the "offset"
offx = -1 * 200;
offy = -1 * 200;
//img is a standard loaded image object
ctx.drawImage(img,offx,offy);
tex = new THREE.Texture(canvas);
That's a way of doing it, but if you want to use the GPU you can do this:
tex.scale.x = 800 / 100;
tex.scale.y = 2000 / 100;
tex.offset.x = ( 300 / 100 ) * tex.scale.x;
tex.offset.y = ( 400 / 100 ) * tex.scale.y;
Or something along the lines :)
Cool! Thanks for the follow up
Doing this on the gpu is certainly more performant. However when i try to set the scale.x property of the texture I keep getting "cannot set property of x" errors. Any ideas? I tried it using the tex.scale.set(w,h) method as well with the same result.
tex = THREE.ImageUtils.loadTexture(img.src);
scalex = img.width / 100;
scaley = img.height / 100;
tex.scale.x = scalex;
tex.scale.y = scaley;
tex = THREE.ImageUtils.loadTexture(img.src);
That's weird, if the image already has a src, means that it has already been loaded. Why load it again?
I think you want to do this instead:
tex = new THREE.Texture( img );
Thanks, yes just using THREE.Texture() directly on the img object seems to have sped things up. Still getting an error on tex.scale operations though. Anyway to translate scaling using tex.repeat? I can tweak those values no problem.
Ah, true. Texture
doesn't have .scale
, it has .repeat
. Try this:
tex.repeat.x = 100 / 800;
tex.repeat.y = 100 / 2000;
tex.offset.x = ( 300 / 100 ) * tex.repeat.x;
tex.offset.y = ( 400 / 100 ) * tex.repeat.y;
I came here to figure out how to scale a texture only to learn about the repeat and offset properties.. but how can I scale them?
@nightlifelover As stated in the guidelines, help requests should be directed to stackoverflow.
Most helpful comment
Ah, true.
Texture
doesn't have.scale
, it has.repeat
. Try this: