마우스를 사용하여 카메라 위치를 제어하려면 compute function
으로 계산합니다.Shaders.metal은 마우스의 y 값만 가져옵니다.
import MetalKit
public class MetalView: MTKView, NSWindowDelegate {
var queue: MTLCommandQueue! = nil
var cps: MTLComputePipelineState! = nil
var timer: Float = 0
var timerBuffer: MTLBuffer!
var mouseBuffer: MTLBuffer!
var pos: NSPoint!
required public init(coder: NSCoder) {
super.init(coder: coder)
self.framebufferOnly = false
device = MTLCreateSystemDefaultDevice()
registerShaders()
}
override public func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
if let drawable = currentDrawable {
let command_buffer = queue.commandBuffer()
let command_encoder = command_buffer.computeCommandEncoder()
command_encoder.setComputePipelineState(cps)
command_encoder.setTexture(drawable.texture, atIndex: 0)
command_encoder.setBuffer(timerBuffer, offset: 0, atIndex: 1)
command_encoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2)
update()
let threadGroupCount = MTLSizeMake(8, 8, 1)
let threadGroups = MTLSizeMake(drawable.texture.width/threadGroupCount.width, drawable.texture.height/threadGroupCount.height, 1)
command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
command_encoder.endEncoding()
command_buffer.presentDrawable(drawable)
command_buffer.commit()
}
}
func registerShaders() {
queue = device!.newCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.newFunctionWithName("compute")!
timerBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: [])
cps = try device!.newComputePipelineStateWithFunction(kernel)
} catch let e {
Swift.print("\(e)")
}
}
func update() {
timer += 0.01
var bufferPointer = timerBuffer.contents()
memcpy(bufferPointer, &timer, sizeof(Float))
bufferPointer = mouseBuffer.contents()
memcpy(bufferPointer, &pos, sizeof(NSPoint))
}
override public func mouseDragged(event: NSEvent) {
pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil))
let scale = layer!.contentsScale
pos.x *= scale
pos.y *= scale
debugPrint("Hello",pos.x,pos.y)
}
}
내 쉐이더 코드 :
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
constant float &timer [[buffer(1)]],
constant float2 &mouse [[buffer(2)]],
uint2 gid [[thread_position_in_grid]])
{
int width = output.get_width();
int height = output.get_height();
float2 uv = float2(gid)/float2(width, height);
uv = uv * 2.0 - 1.0;
// scale proportionately.
if(width > height) uv.x *= float(width)/float(height);
if(width < height) uv.y *= float(height)/float(width);
float2 mpos = mouse * 2.0 - 1.0;
float3 cameraPosition = float3(mpos.x,mpos.y, -10.0);///<-- mouse position to set camera position
...
}
어쨌든 나는 단지 mpos.y
가치를 내 view
코드입니다. mpos.x
은 compute
기능으로 전송되지 않는 것 같습니다. 이 문제를 어떻게 해결할 수 있습니까?
쉐이더에 mpos.x 값이 없다는 증거를 더 많이 제공 할 수 있습니까? – Marius
나는'float3 (mpos.x, 0.0, -10.0)'과'float3 (0.0, mpos.x, -10.0)'과 같이'float3 cameraPosition = float3 (mpos.x, mpos.y, -10.0))''mpos.x'가 작동 하는지를보기 위해서입니다. – sooon