How can I apply PNG as a 2side pattern texure on a RingBufferGeometry

want to use three.js to complete the following effect, which is create a RingBufferGeometry and use png as texture,But I don’t know how to turn the image into a fan shape.


i may need to use geometry.attributes.uv.setXY(),but i completely dont know how it works.
it would be better that the repeat times also can set in different value…

UV map for ring isn’t great for this. Instead, I used a torus and made it flat by setting z to 0.1. As for the loaded texture, you might need to set rotation to PI/2 and set repeat value to get the right scale over the torus.
See this example of Saturn’s rings uses this technique. Code is here
Hope this helps

aligning uv’s is normally not something you do by code, it’s easier to unwrap in blender and do it there.

@John_Doe
Distort PlaneGeometry into a ring.

this white part in png actullary is opacity,so it make torus looks overlap
and also, i cant change repeat value by dat.gui, sad
I am a newcomer of three.js, so I dont really understand your example…
not like processing,three.js manual completly confusing me, its absolute newbee unfriendly.

but thanks for help!

i have a lot of png to randomly combine to ring, and also the size of ring can changed.
so blender might not suit me

how to distort, can i have a example or tutorial?

so i create this function and it worked, but new problem occur: i cant change the size(ringIn,ringOut) and patternNum and thetaSeg by dat.GUI, anyone can help ?

function drawRing(group,path,color,ringIn,ringOut,patternNum,thetaSeg){
for(var i = 0;i<patternNum;i++){
var ringStart = iMath.PI2/patternNum;
var ringEnd = (i+1)Math.PI2/patternNum;
var ring_vertices = ;
var ring_uv = ;
var ring_indices = ;
for(var x=thetaSeg;x>-1;x–){
var angle = x*(ringEnd-ringStart)/thetaSeg+ringStart;
ring_vertices.push((ringIn+5)Math.cos(angle));
ring_vertices.push((ringIn+5)Math.sin(angle));
ring_vertices.push(0);
ring_vertices.push((ringOut-5)Math.cos(angle));
ring_vertices.push((ringOut-5)Math.sin(angle));
ring_vertices.push(0);
}
for(var x=0;x<thetaSeg+1;x++){
ring_uv.push(x/thetaSeg);
ring_uv.push(0);
ring_uv.push(x/thetaSeg);
ring_uv.push(1);
}
for(var x=0;x<thetaSeg;x++){
ring_indices.push(x
2);
ring_indices.push(x
2+1);
ring_indices.push(x
2+3);
ring_indices.push(x
2);
ring_indices.push(x2+2);
ring_indices.push(x
2+3);
}
const ringGeo = new THREE.BufferGeometry();
ringGeo.setAttribute(‘position’,new THREE.BufferAttribute(new Float32Array(ring_vertices),3));
ringGeo.setAttribute(‘uv’,new THREE.BufferAttribute(new Float32Array(ring_uv),2));
ringGeo.setIndex( new THREE.BufferAttribute(new Uint32Array(ring_indices),1));
const pattern = new THREE.TextureLoader().load(path);
const ringMat = new THREE.MeshBasicMaterial({map:pattern,color:color,transparent:true,opacity:1,side: THREE.DoubleSide});
const ring = new THREE.Mesh(ringGeo,ringMat);
group.add(ring);
}
scene.add(group);
}

To bend.
For a specific point, its angle depends, for example, on UV.x, thus Math.PI * 2 * uv.x.
And coords will be:
x = Math.cos(angle) * (desired_radius - point.y)
y = Math.sin(angle) * (desired_radius - point.y)
Creativity with radii is up to you )

It is similar but easier than bending a cylinder or a cuboid.

From the Collection of examples from discourse.threejs.org

CurvedArrowHelper
SpiralFromCylinder
SineWaveGrooveRing

1 Like

Bending of a plane

4 Likes

here i used a plane geometry and bender
repeat image (https://jsfiddle.net/seanwasere/o45hvr0z/)
image

2 Likes

it shows good, thanks!
but one more question, im trying to change value of bend and repeat times by dat.GUI, but its stuck and GUI cant control.

here’s my GUI code

var controls = new function () {
this.ringIn = 12;
this.ringOut = 20;
this.patternNum = 12;
};
var gui = new dat.GUI();
gui.add(controls, ‘ringIn’, 0, 60,1).onChange(reSize);
gui.add(controls, ‘ringOut’, 0, 60,1).onChange(reSize);
gui.add(controls, ‘patternNum’, 0, 20,1).onChange(reSize);
function reSize() {
bend(g,ringIn,ringOut);
o.geometry = g;
}

@John_Doe
Everything works as expected, when you set g.needsUpdate = true;.
I modified my previous codepen: https://codepen.io/prisoner849/pen/VwxxbMJ?editors=0010

1 Like

wow it works!
thank you bro!

@John_Doe
you’re welcome :handshake: