How do you use textures with transparency in three.js? - javascript

I would like to assemble a group of meshes like this:
The black outlined rectangles represent how I would like to assemble them. I have 8 pieces, 4 edges, and 4 corners, as textures (with transparency). Then, I have a 9th texture that I would like to have underneath the others, and that one is represented by the purple area. The geometries seem to be good, and the texture images are 16x16 pngs. First, I tried the basic approach with just MeshBasicMaterial, and I get my rectangles, but not my textures. Following some advice seen elsewhere on SO I tried something like this:
material = new THREE.MeshBasicMaterial({
transparent: true,
map: texture
});
material.needsUpdate = true;
var materials = [];
materials.push(material);
materials.push(new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
transparent: true
}));
mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
But this did not work either. I've also tried using the ShaderMaterial but I guess I do not get GLSL well enough yet to make it work. How in the world do I get transparent png textures to map onto ShapeGeometries?

Related

Threejs - Maintain aspect ratio while adding texture map to threejs object

We want to create a 3d shoe designing tool, where you can design patterns and upload them to the shoe.
I am trying to place an image on a Threejs material. I am able to update the map, but the texture is blurry. I am new to Threejs, so I do not have concepts clear. I don't understand if aspect ratio is the issue or something else.
This how I am loading texture:
var texture_loader = new THREE.TextureLoader();
var texture = texture_loader.load( 'https://ik.imagekit.io/toesmith/pexels-photo-414612_D4wydSedY.jpg', function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.offset.set( 0, 0 );
texture.repeat.set( 1, 1 );
vamp.material = new THREE.MeshPhongMaterial({
map: texture,
color: new THREE.Color('#f2f2f2'),
shininess: 20,
});
});
This is what I am getting
But the expected behavior should be
If anyone could help, that would be great. Thanks
Here is the link to the Codepen code
The problem is that your UVs are occupying a very small area in texture coordinates. As they are now, it looks like your UVs are taking up this much room (see red area):
And that's why it gives the impression that your texture is blurry. What you need to do is make your UVs take up more space, like this:
There are 2 ways to achieve this.
Scale UVs up: Import your model into Blender, and change the UV mapping of the mesh to occupy more of the [0, 1] range.
Scale texture down: You could get creative with the texture.repeat property and use it to scale down your texture to match your existing UVs. Then you'd need to offset it so it's centered correctly. Something like:
texture.repeat = new THREE.Vector2(10, 10);
texture.offset = new THREE.Vector2(xx, yy);

Texture on Sphere fuzzy after version upgrade

After upgrading from r67 to r86, our footballs are not very sexy anymore. Did anyone have similar issues in the past?
The code that used to render the spheres nicely, messes up the texture (and some lighting, but I can live with that) in version r86.
The part that creates the spheres:
const material = new THREE.MeshPhongMaterial({ map: texture, transparent: false });
material.alphaTest = 0.5;
const geometry = new THREE.SphereGeometry(radius, res, res);
const mesh = new THREE.Mesh(geometry, material);
Fiddle using r86.
In my comment, I suggested checking the UVs. My suggestion to try different min/mag filter values (http://threejs.org/docs/#api/constants/Textures) was more to correct the image quality, than the texture mapping its self.
What I didn't notice was that your texture was already spherical. The standard linear filter mapped the texture, well, linearly. The weighting/averaging of the linear filter caused the mapping to become compressed toward the top (and bottom, though it wasn't noticeable).
Setting texture.minFilter = THREE.NearestFilter; ditched the weighting/averaging of the texture coordinates, instead mapping to the nearest pixel, which was perfect because of your spherical texture.

Three.js: Weird render result

How can I fix the reflection around the cycles?
I got some weird results on my object. I hope the pictures show the problem.
Three.js result
Expected result
loader.load( "model.js", function(geometry){
geometry.computeVertexNormals();
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( {
color: 0xffffff,
specular: 0xffffff,
shininess: 65,
metal: true,
envMap: cubeCamera.renderTarget
}));
scene.add(mesh);
});
I have exported the model with the three.js json exporter from blender. The model has vertices, faces and UVs.
Hmm, this is hard to explain, but basically it is because you are using triangle polygons and your topology is not good.
It is often referred to as "pinching" if I recall correctly.
When modelling for Three.js, it is basically modelling for a game engine and all the same rules need to be followed.
Things you could try to get a better reflection:
Reduce the amount of polygons as it seems you have WAY more polygons than are needed.
Try for a cleaner topology using quads and minimising tris.
Set up smoothing groups
An easy fix would be to use a simple plane in the correct shape with holes cut out as it seems the sides are not really visible anyway. (I am talking about the large flat piece specifically here). I suggest this because I have found that reflections when using MeshPhongMaterial are often not adversely affected by the use of ngons and tris when all the vertices are flat and in the same smoothing group.

How to get rid of tile outlines when tiling textures to a mesh?

I'm creating a sphere and attaching images to each face of the sphere. In my code I have sphere 12 sections by 6 sections high. I've managed to tile the textures by setting the wrap to repeating and setting the repeat size like so:
var texture = new THREE.ImageUtils.loadTexture( path );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( geo_width, geo_height );
return new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide, overdraw: true });
It works but now I have these lines between each texture. Is there a way to get rid of them or is there another technique for face-tiling that I should be using?
The lines are the opposite edge of each texture tile appearing at the edges of the geometry. This is what repeating textures do, which is not appropriate in this case.
You don't say what happens when you don't use repeating, but it sounds like what you need to do is adjust the texture coordinate generation so that the coordinates are 0...1 on each tile rather than only on the “0th tile” of the entire sphere.
I don't know Three.js so I can't advise you specifically on its API, sorry.

three.js transparent maps issue

I'm creating loads of particles (80.000 to be exact) and I have set a transparent map, though, not all particles are transparent.
I'm using a transparent PNG image: (it's barely visible but it's there alright) as the material map, though it shows a black background as seen here:
If you look closely, some particles blend together well (no overlapping black edges) though some do not. Could it be because there are so many overlapping transparent objects or shouldn't this be an issue?
Here's the snippet responsible for the generation of my particles:
// load the texture
var map = THREE.ImageUtils.loadTexture('img/particle.png');
// create temp variables
var geometry, material;
// create an array with ParticleSystems (I need multiple systems because I have different colours, thus different materials)
var systems = [];
// Loop through every colour
for(var i = 0; i < colors.length; i++) {
// Create a new geometry
geometry = new THREE.Geometry();
// create a new material
material = new THREE.ParticleBasicMaterial({
color: colors[i],
size: 20,
map: map, // set the map here
transparent: true // transparency is enabled!!!
});
// create a new particle system
systems[i] = new THREE.ParticleSystem(geometry, material);
// add the system to the scene
scene.add(systems[i]);
}
// vertices are added to the ParticleSystems' geometry here
Why do some of the particles have a black background?
You can set the alphaTest property of the material instead of transparency. For example,
material.alphaTest = 0.5;
material.transparent = false;
three.js no longer sorts particles; they are rendered in the order they appear in the buffer.
three.js r.85
Those particles with black corners are rendered before anything behind them. So GL doesn't know yet there is something behind to blend. In order to make it look right you have to render these particles in the order of their z coordinates from back to front.
Disable the depthWrite attribute on the material.
// create a new material
material = new THREE.ParticleBasicMaterial({
color: colors[i],
size: 20,
map: map,
transparent: true,
depthWrite: false,
});
Try webgl_particles_billboards.html.
If I'm right it does the same thing you expect.

Categories