this siteに出て、しばらくの間SDFを学び始めました。しかし、私はまだ非常にこのコードの後ろにアイデアを得ることはありません:GLSL関数をメタルに変換する
float pMod1(inout float p, float size) {
float halfsize = size*0.5;
float c = floor((p + halfsize)/size);
p = mod(p + halfsize, size) - halfsize;
return c;
}
私は私のMetal
コードに変換します
#define _inout(T) T
...
float pMod1(_inout (float) p, float size) {
float halfsize = size*0.5;
float c = floor((p + halfsize)/size);
p = mod(p + halfsize, size) - halfsize;
return c;
}
ではなく、期待される結果を得ます。しかし、私が
に変更した場合#define _inout(T) T
...
float pMod1(_inout (float) p, float size) {
float halfsize = size*0.5;
float c = floor((p + halfsize)/size);
p = mod(p + halfsize, size) - halfsize;
return p; // <-- change from c to p
}
私は期待したものを得ます。
私の変換方法は、
inout
が完全ではないと思われます。私はShadertoy
コードからそれを借りましたが、私はそれが実際にそのように機能することを納得させるものではありません。c
はどのように便利ですか?サイドからのコードでは、コメント:私はそれが本当に何を意味するのか理解していない
Many of the operators partition space into cells. An identifier or cell index is returned, if possible. This return value is intended to be optionally used e.g. as a random seed to change parameters of the distance functions inside the cells.
。誰かがセルインデックスを使用する方法のいくつかの例を提案することができますか?
アップデート1:
私は、コードを変更します。
float pMod1(thread float &p, float size) {
float halfsize = size*0.5;
float c = floor((p + halfsize)/size);
p = mod(p + halfsize, size) - halfsize;
return c;
}
、今、私は別のエラーメッセージが出ます:
fatal error: unexpectedly found nil while unwrapping an Optional value
このラインから:
command_encoder.setComputePipelineState(cps)
をなぜなら、私は
Metal
ファイルを分割する方法のためである 私はエラーを疑う
アップデート1中:
import MetalKit
public class MetalView: MTKView, NSWindowDelegate {
var queue: MTLCommandQueue! = nil
var cps: MTLComputePipelineState! = nil
var timer: Float = 0
var timerBuffer: MTLBuffer!
var mousexBuffer: MTLBuffer!
var mouseyBuffer: MTLBuffer!
var pos: NSPoint!
var floatx: Float!
var floaty: Float!
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) ///////<-- This line throw an error.
command_encoder.setTexture(drawable.texture, atIndex: 0)
command_encoder.setBuffer(timerBuffer, offset: 0, atIndex: 1)
command_encoder.setBuffer(mousexBuffer, offset: 0, atIndex: 2)
command_encoder.setBuffer(mouseyBuffer, offset: 0, atIndex: 3)
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: [])
mousexBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
mouseyBuffer = device!.newBufferWithLength(sizeof(Float), 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 = mousexBuffer.contents()
memcpy(bufferPointer, &floatx, sizeof(NSPoint))
bufferPointer = mouseyBuffer.contents()
memcpy(bufferPointer, &floaty, 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
floatx = Float(pos.x)
floaty = Float(pos.y)
debugPrint("Hello",pos.x,pos.y)
}
}
アップデート2:10
はここMetaView.swiftから、全体のコードです。だから私は1つのMetal
ファイルにすべての機能をコピーして、今私は新しいエラーを生み出すことによってそれを簡素化:
float pMod1(thread float &p, float size) {
float halfsize = size*0.5;
float c = floor((p + halfsize)/size);
p = mod(p + halfsize, size) - halfsize;
return c;
}
static float map(float3 p)
{
float size = 10.0;
p.x = pMod1(p.x,size);/////<--- this produce the error.
float box = fBox(p, float3(1));
float sphere = length(p - float3(1)) - 1;
float d = min(box,sphere);
float guard = -fBoxCheap(p, float3(size*0.5));
guard = abs(guard) + size*0.1;
return min(d,guard);
}
エラー:
Call to
pMod1
is ambiguous
アドバイスごとに変更されましたが、新しいエラーがあります。私の** Update1 **にすべての詳細を確認してください。 – sooon
残念ながら、スイッツベクトルコンポーネントは参照渡しできません。 'p.x'をローカル変数にコピーし、関数に_that_を渡し、関数呼び出しの後に_back_を' p.x'に代入する必要があります。また、関数の結果を 'p.x'に代入しないでください。戻り値はセルインデックスであり、参照パラメータで返す値とはまったく異なります。 – warrenm
'pMod()'関数で 'thread float&p'の値を' c'を返すので、どのように使うことができますか?私は彼らが同じ機能を使用しているビデオをチェックしますが、何とか彼らは値 'p'を取り戻しました。 – sooon