Fixed texture size

textures

#1

Hello

Is it possible to have a fixed-sized texture, for example 1x1, independent of the mesh to which it is applied?

https://codepen.io/andreamk5/pen/eVWXLo

This is a simple example where the texture should be identical for each panel but is resized.


#2

Take a look at this discourse thread:

And its jsfiddle examples with shaders, where the grid is independent from the size of planes.


#3

thanks for the reply but it is very complex :slight_smile:

It seems strange to me that we can’t have a texture that is valid for all the faces of a scene of the same mesh or even of different meshes.

I did some tests and the texture is deformed in every way.

I created a function that tries to calculate repetitions based on geometry.
It works little but something improves.

I have updated the example.

function getScaledTexture(geometry,fitTo) {
var texture = new THREE.TextureLoader().load( texture_image );
  texture.wrapS = THREE.RepeatWrapping;
  texture.wrapT = THREE.RepeatWrapping;
texture.mapping = THREE.CubeUVReflectionMapping;

geometry.computeBoundingBox ();
var bbox = geometry.boundingBox;
var dX = Math.abs(bbox.max.x - bbox.min.x);
var dY = Math.abs(bbox.max.y - bbox.min.y);
var dZ = Math.abs(bbox.max.z - bbox.min.z);


var repeat = Math.max(dX,dY,dZ) / fitTo;

	texture.repeat.set( repeat , repeat );
return texture;

}


#4

I used the suggested method in this SO thread to achieve this for planes.

I guess for boxes you could just apply this method to each face. Not sure about cylinders, spheres etc. though.


#5

Hello
Thank you for your suggestion. From there I started and I studied and I realized that a function regenerates the uv map based on the “fitTo” parameter inserted in the texture object.

The basic idea is that a texture must have a fixed dimension independent of the geometry to which it is applied as it happens in real world.

The “fitTo” variable is expressed in units.
The function works well enough but is not perfect on inclined surfaces like on octahedron.
I’ve taken pieces of code from various sources and I do not have a thorough understanding of geometry and UV map to do better.
If someone wanted to help me improve it, I would be happy.

Example
https://codepen.io/andreamk5/pen/GQELVX

Here’s how it works

set userData.fitTo = value

var fixTexture = new THREE.TextureLoader().load( texture_image );

fixTexture.userData = {
	fitTo : 1
};
fixTexture.wrapS = THREE.RepeatWrapping;
fixTexture.wrapT = THREE.RepeatWrapping;

var material = new THREE.MeshPhongMaterial( {
	color: 0x00ffff, 
	flatShading: true,
	transparent: false,
	opacity: 0.7,
	map: fixTexture
}); 

call meshFitUvMap on mesh

var geometry = new THREE.BoxGeometry( 2, 5, 2 );
var box = new THREE.Mesh( geometry, material );
meshFitUvMap(box);
console.log(box);
scene.add( box );

This is the function

function meshFitUvMap(mesh) {
  
   if (mesh.geometry && 
       mesh.material && 
       mesh.material.map && 
       mesh.material.map.userData && 
       mesh.material.map.userData.fitTo > 0) {
     
       
      var geometry = mesh.geometry;
      var textureFitTo = mesh.material.map.userData.fitTo; 
      var faces = mesh.geometry.faces;
     
       for (var i = 0, len = faces.length; i < len; i ++) {
	   var face = faces[i];
	   var uv = geometry.faceVertexUvs[0][i];

	   var components = ['x', 'y', 'z'].sort(function(a, b) {
	      return Math.abs(face.normal[a]) > Math.abs(face.normal[b]);
	   });
	 
	 var v1 = mesh.geometry.vertices[face.a];
	 var v2 = mesh.geometry.vertices[face.b];
	 var v3 = mesh.geometry.vertices[face.c];
	 
	 var newUv0 = new THREE.Vector2(v1[components[0]] / textureFitTo, v1[components[1]] / textureFitTo);
	 var newUv1 = new THREE.Vector2(v2[components[0]] / textureFitTo, v2[components[1]] / textureFitTo);
	 var newUv2 = new THREE.Vector2(v3[components[0]] / textureFitTo, v3[components[1]] / textureFitTo);

	   uv[0].copy(newUv0);
	   uv[1].copy(newUv1);
	   uv[2].copy(newUv2);

       }
   }
}