Hi,

I'm building a model of Saturn and need to create the ring. I'm doing this by trying to texture a plane using the this resource here.

How can I use this texture to create a ring?

This is what I have so far:

Thanks

Godot version 3.4.2
in Engine
edited

+1 vote

I dont think Godot has a built-in way to do this. It is easy to do, though.

Assuming you really want to use this texture, a first way is to create a ring in a modeling program like Blender. Then give UVs to that ring, such that the inner border uses the left of the image, and the right border uses the right of the image, while the whole ring uses the same Y coordinate.

Another way is to use a shader and some math to obtain a perfect ring. I don't have much time to write an example unfortunately. This can be done with a quad, but a ring geometry will still perform a bit better if it matches the shape of the rings so less pixels will need to be processed.

An extra way to create the geometry is to use CSGPolygon Spin mode. By default it uses a quad, but if you lower vertices thinner you can reproduce a ring. However, I don't know if you can make it generate the appropriate UVs, so IMO you might have more control using a 3D modeler.

There is yet another way which can cost a bit of loading time, but you can also generate the mesh from a script:

#tool
extends MeshInstance

var _segments = 64

var positions = []
var uvs = []

for si in _segments + 1:
var angle = TAU * float(si) / _segments
var dir = Vector3(cos(angle), 0, sin(angle))
var inner_pos = _inner_radius * dir
var outer_pos = _outer_radius * dir
positions.append(inner_pos)
positions.append(outer_pos)
uvs.append(Vector2(0,0.5))
uvs.append(Vector2(1,0.5))

var indices = []
var i = qi * 2
var i0 = i
var i1 = i + 1
var i2 = i + 2
var i3 = i + 3
indices.append(i0)
indices.append(i1)
indices.append(i2)
indices.append(i2)
indices.append(i1)
indices.append(i3)

var surface = []
surface.resize(Mesh.ARRAY_MAX)
surface[Mesh.ARRAY_VERTEX] = PoolVector3Array(positions)
surface[Mesh.ARRAY_TEX_UV] = PoolVector2Array(uvs)
surface[Mesh.ARRAY_INDEX] = PoolIntArray(indices)
mesh = ArrayMesh.new()