11

I want to pass a float to my metal shader. I cannot figure out how.

Here is my shader:

vertex float4 model_vertex(unsigned int iid[[instance_id]]
                           constant float angle) {
    float number = float(iid) / 64.0;
    return float4(number * sin(angle), number * cos(angle), 0.0, 1.0);
}

Now I want to pass it to the shader:

let renderPassDescriptor = MTLRenderPassDescriptor()
let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
// ...
let angle: Float = 0.5
renderEncoder.setUniform1(angle) // What do I do here?

How do I pass the single float value?

Hallgrim
  • 15,143
  • 10
  • 46
  • 54

2 Answers2

11

Also in 10.11+ and iOS 9+ you can use:

public func setVertexBytes(bytes: UnsafePointer<Void>, length: Int, atIndex index: Int)

Which is documented to be better than creating a MTLBuffer if you're only using the buffer once (and your data is less than 4K long).

Wil Shipley
  • 9,343
  • 35
  • 59
  • 1
    Maybe this is obvious, but OP's question has a vertex shader and `setFragmentBytes` sends data to fragment shaders, so if like OP you want to send data to a vertex shader use `setVertexBytes` instead. – Bjorn Aug 11 '16 at 14:36
8

I haven't seen setUniform* before. To pass uniforms to your vertex shader, use:

setVertexBuffer(buffer: MTLBuffer?, offset: Int, atIndex index: Int)

Where buffer would be an array with a single float, in your example. To pass uniforms to a fragment shader use setFragmentBuffer.

aoakenfo
  • 914
  • 1
  • 7
  • 9