added particles
This commit is contained in:
parent
996ebf1260
commit
3bb25af63a
|
|
@ -29,3 +29,4 @@ Repository to accompany the following blog posts:
|
|||
- [Introducing Metal 2](http://metalkit.org/2017/06/30/introducing-metal-2.html)
|
||||
- [Using ARKit with Metal](http://metalkit.org/2017/07/29/using-arkit-with-metal.html)
|
||||
- [Using ARKit with Metal part 2](http://metalkit.org/2017/08/31/using-arkit-with-metal-part-2.html)
|
||||
- [Working with Particles in Metal](http://metalkit.org/2017/09/30/working-with-particles-in-metal.html)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
import MetalKit
|
||||
import PlaygroundSupport
|
||||
|
||||
let frame = NSRect(x: 0, y: 0, width: 400, height: 400)
|
||||
let delegate = MetalView()
|
||||
let view = MTKView(frame: frame, device: delegate.device)
|
||||
view.delegate = delegate
|
||||
PlaygroundPage.current.liveView = view
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
|
||||
struct Particle {
|
||||
float2 center;
|
||||
float radius;
|
||||
};
|
||||
|
||||
float distanceToParticle(float2 point, Particle p) {
|
||||
return length(point - p.center) - p.radius;
|
||||
}
|
||||
|
||||
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
|
||||
constant float &time [[buffer(0)]],
|
||||
uint2 gid [[thread_position_in_grid]]) {
|
||||
int width = output.get_width();
|
||||
int height = output.get_height();
|
||||
float2 uv = float2(gid) / float2(width, height);
|
||||
float2 center = float2(0.5, time);
|
||||
float radius = 0.05;
|
||||
float stop = 1 - radius;
|
||||
if (time >= stop) { center.y = stop; }
|
||||
else center.y = time;
|
||||
Particle p = Particle{center, radius};
|
||||
float distance = distanceToParticle(uv, p);
|
||||
float4 color = float4(1, 0.7, 0, 1);
|
||||
if (distance > 0) { color = float4(0.2, 0.5, 0.7, 1); }
|
||||
output.write(float4(color), gid);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
import MetalKit
|
||||
|
||||
public class MetalView: NSObject, MTKViewDelegate {
|
||||
|
||||
public var device: MTLDevice! = nil
|
||||
var queue: MTLCommandQueue! = nil
|
||||
var cps: MTLComputePipelineState! = nil
|
||||
var timerBuffer: MTLBuffer! = nil
|
||||
var timer: Float = 0
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
device = MTLCreateSystemDefaultDevice()
|
||||
queue = device.makeCommandQueue()
|
||||
registerShaders()
|
||||
}
|
||||
|
||||
func registerShaders() {
|
||||
guard let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") else { return }
|
||||
do {
|
||||
let input = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
|
||||
let library = try device.makeLibrary(source: input, options: nil)
|
||||
guard let kernel = library.makeFunction(name: "compute") else { return }
|
||||
cps = try device.makeComputePipelineState(function: kernel)
|
||||
} catch let e {
|
||||
Swift.print("\(e)")
|
||||
}
|
||||
timerBuffer = device.makeBuffer(length: MemoryLayout<Float>.size, options: [])
|
||||
}
|
||||
|
||||
func update() {
|
||||
timer += 0.01
|
||||
let bufferPointer = timerBuffer.contents()
|
||||
memcpy(bufferPointer, &timer, MemoryLayout<Float>.size)
|
||||
}
|
||||
|
||||
public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {}
|
||||
|
||||
public func draw(in view: MTKView) {
|
||||
if let drawable = view.currentDrawable,
|
||||
let commandBuffer = queue.makeCommandBuffer(),
|
||||
let commandEncoder = commandBuffer.makeComputeCommandEncoder()
|
||||
{
|
||||
commandEncoder.setComputePipelineState(cps)
|
||||
commandEncoder.setTexture(drawable.texture, index: 0)
|
||||
commandEncoder.setBuffer(timerBuffer, offset: 0, index: 0)
|
||||
update()
|
||||
let threadGroupCount = MTLSizeMake(8, 8, 1)
|
||||
let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1)
|
||||
commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
|
||||
commandEncoder.endEncoding()
|
||||
commandBuffer.present(drawable)
|
||||
commandBuffer.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
7
particles/particle.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
particles/particle.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
||||
Loading…
Reference in New Issue