# Texture mapping on a custom geometry

I’ve been struggling to get a 256x256 image textured onto a custom geometry I have.
There are many questions that have great answers like artificially creating the UV map for the custom geometry. However these answers are all pre 2017 and I am too stoopid to implement the solution with the new way of storing geometry information as attributes (uv, position, normal).

I have a nice texture but it only displays as what seems to be the mean colour of the image…

There are 13 vertices arranged in a circle ish

``````    //First loading the points centered around the origin
//coorAroundOrigin has 13 points
let vertices = []
for(let k = 0;k < coorAroundOrigin.length;k++){
vertices.push(new THREE.Vector2( coorAroundOrigin[k].x , coorAroundOrigin[k].y ))
}
vertices.push(new THREE.Vector2( coorAroundOrigin.x , coorAroundOrigin.y ))

let geo = new THREE.ShapeBufferGeometry(new THREE.Shape(vertices))

//Now the material
//SLIME_TEXTURE is a material that has a map of a 256x256 image that is definitely loaded -only displays as a solid colour though
let final_mesh = new THREE.Mesh(geo , SLIME_TEXTURE)
``````

Here is a related problem with the old solution:

Thanks!

Look at the code of the circle.

In the
Collection of examples from discourse.threejs.org
other examples:

RoundedRectangle

SlicedConeMergedGeometry

UVgenerator

TetrahedronSpecificUVs

SphereWithoutTrigonometry

Thanks @hofk looking at the circle geometry set me on the right path - almost got my slime texture contorting how it should be based on the changing vertices:

Here’s the algorithm - it’s very similar to circle geometry except you start with points and the radius is calculated differently:

``````//Function for generating geometries from points
function getGeometryFromSetOfPoints(points){//[vertx1, vertex2, vertex3, ...] *** Centered around (0, 0, 0)

const newGeometry = new THREE.BufferGeometry();

//Get the min / max of x and y from the points (used in place of radius that's usually given to circle geometry constructor)
let minX=0,minY=0,maxX=0,maxY=0;
for(let i = 0; points.length && points[i];i++){
minX=Math.min(minX, points[i].x)
minY=Math.min(minY, points[i].y)
maxX=Math.max(maxX, points[i].x)
maxY=Math.max(maxY, points[i].y)
}

let rangeX = maxX - minX
rangeX /= 2
let rangeY = maxY - minY
rangeY /= 2

//Buffers that the geometries attributes will be set to
const indices = [];
const vertices = [];
const normals = [];
const uvs = [];

// helper variables
const uv = new THREE.Vector2();

//  =*Circular design*=
vertices.push( 0, 0, 0 );
normals.push( 0, 0, 1 );
uvs.push( 0.5, 0.5 );

//Each iteration of the loop will be a "segment" from the circle example
for(let i = 0;i <= points.length;i++){

vertices.push(points[i%points.length].x, points[i%points.length].y, 0)

normals.push( 0, 0, 1 );

let indexOfVertexToUse = vertices.length - 3
uv.x = ( vertices[ indexOfVertexToUse ] / rangeX + 1 ) / 2;
uv.y = ( vertices[ indexOfVertexToUse + 1 ] / rangeY + 1 ) / 2;

uvs.push( uv.x, uv.y )
}

//Indices
for(let i = 1; i <= points.length;i++){
indices.push( i, i + 1, 0 );
}

//Finally build geometry
newGeometry.setIndex(indices)
newGeometry.setAttribute("position", new THREE.Float32BufferAttribute( vertices, 3 ) );
newGeometry.setAttribute("normal", new THREE.Float32BufferAttribute( normals, 3 ) );
newGeometry.setAttribute("uv", new THREE.Float32BufferAttribute( uvs, 2 ) );

return newGeometry
}
``````

Last problem is one slice per slime now
^^^*Edit : fixed the code now