Hi again @caroline
I need to send the vertices of an imported geometry to GPU, update the position with a noise algorithm, send back to CPU, update the normals, and send it again to GPU to draw it.
My approach:
init(metalView:)
let computeFunction = Renderer.library.makeFunction(name: "computeFunction")!
let descriptor = MTLComputePipelineDescriptor()
descriptor.computeFunction = computeFunction
let ioDescriptor = MTLStageInputOutputDescriptor()
var offset = 0
let att = MTLAttributeDescriptor()
att.bufferIndex = 0
att.offset = 0
att.format = MTLAttributeFormat.float3
ioDescriptor.attributes[0] = att
offset += MemoryLayout<float3>.stride
att.offset = offset
ioDescriptor.attributes[1] = att
offset += MemoryLayout<float3>.stride
let layout = MTLBufferLayoutDescriptor()
layout.stride = offset
layout.stepFunction = .threadPositionInGridX
layout.stepRate = 1
ioDescriptor.layouts[0] = layout
descriptor.stageInputDescriptor = ioDescriptor
do {
computePipelineState = try Renderer.device.makeComputePipelineState(descriptor: descriptor, options: [], reflection: nil)
}catch let error{
fatalError(error.localizedDescription)
}
draw()
computeEncoder.setComputePipelineState(computePipelineState)
let width = computePipelineState.threadExecutionWidth
let threadsPerGroup = MTLSizeMake(width,1,1)
let bufferSize = model.meshes[0].mtkMesh.vertexBuffers[0].length
let threadsPerGrid = MTLSizeMake(bufferSize,1,1)
computeEncoder.setBuffer(model.meshes[0].mtkMesh.vertexBuffers[0].buffer, offset: 0, index: 0)
computeEncoder.dispatchThreads(threadsPerGrid, threadsPerThreadgroup: threadsPerGroup)
computeEncoder.endEncoding()
Metal shader:
**struct** VertexIn {
**float4** position [[ attribute(0) ]];
**float3** normal [[ attribute(1)] ];
};
**kernel** **void** computeFunction ( VertexIn in [[stage_in]]){
in.position=noise();
}
I’m going in a good way?
Not draws updated positions with noise
Can you give some advice, please
Thks in advance!!