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[0].x , coorAroundOrigin[0].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)
    scene.add(final_mesh )

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*=
    //Add center point
    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++){

        //Add corresponding vertex
        vertices.push(points[i%points.length].x, points[i%points.length].y, 0)

        //Add correspoding normal
        normals.push( 0, 0, 1 );

        //Add correspoding uvs
        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