Group Group Group Group Group Group Group Group Group

Drawing Sphere with Metal

Is there a way to draw a sphere in metal by calculating points and then connecting them using triangles?

Hi @hcrogman, and welcome to these forums!

The short answer is usually “yes” :grimacing:

It really depends what you want to do. You can use

let sphereMesh = MDLMesh(
  sphereWithExtent: [0.4, 0.4, 0.4], 
  segments: [10, 10], 
  inwardNormals: false, 
  geometryType: .triangles, 
  allocator: allocator)

to create a sphere instead of having to calculate vertices.

You can load a sphere obj that you created in Blender.

You can create an MTLBuffer of calculated vertices, just as you can do with one triangle as in this tutorial: Metal Tutorial: Getting Started | raywenderlich.com.

This looks like a place to start with a generating sphere algorithm, if that’s what you really want to do: c++ - OpenGL calculate UV sphere vertices - Game Development Stack Exchange.

1 Like

Thank you.
I understand that but the reason I am confused is because I want my sphere to become deformed but only way know how do that is calculate the vertices… this what I did in opengl. So how do I do this in metal? This would mean my radius is not fixed.

I can’t visualise what you mean.

I would guess that you would do it in Metal much the same way as you did in OpenGL. Did you create a vertex buffer and send it to the GPU? You can do the same in Metal.

What did your OpenGL shaders do?

I have calculate the points for the sphere but I am not clear create the vertex buffer from here.

Sorry @hcrogman - I missed this question.

To create a vertex buffer, you use:

let buffer = Renderer.device.makeBuffer(
                        bytes: InsertYourData,
                        length: MemoryLayout<YourDataLayout>.stride)

This project has a file Primitive.swift which contains an example of creating a cube mesh compatible with indexed drawing.

MeshGeneration.zip (179.4 KB)

If you don’t calculate vertex indices, you can do non-indexed drawing with:

renderEncoder.drawPrimitives(type:vertexStart:vertexCount:)
1 Like

Primitive.swift
WOW!!! I’ve always wondered how to create indexed geometry…

1 Like

I am still have problem: I made this modification in MeshGeneration… and I get a black output:
static func buildSphere(size: float3) → Mesh {
var submeshes: [Submesh] = []
let vertexArray: [Float] = matrixobj.computeMypoints(arg1: 5, arg2: 100)

    let vertexBuffer = Renderer.device.makeBuffer(bytes: vertexArray,
                                                  length: MemoryLayout<Vertex>.stride * vertexArray.count,
                                                  options: [])!
     let mesh = Mesh(vertexBuffer: vertexBuffer, submeshes: submeshes)
    return mesh
}

I set var submeshes: [Submesh] = []… because I am thinking to indexing would be quite difficult.
computeMypoints just computes points for a sphere in return a matix of points… Why can ge these point to plot.

Thank you

You don’t need submeshes to draw, if you’re not using indexing, but the Mesh code doesn’t draw unless there is at least one Submesh, so you’d have to extract the draw from that loop.

How about reviewing the early code in Chapter 4 where you set up individual vertices, and then draw a triangle?

You should just be able to put vertices in a buffer in the same way and render them.

With your code, instead of having sphere vertices, just make up a quad and render that. Then you can use Geometry in the GPU debugger to debug what’s happening to each of your vertices.

This is a cut-down version of the playground in Chapter 4 that renders one triangle.

3DTransforms.playground.zip (20.0 KB)