[Metaballs] Do all the texture generation in the fragment shader
This commit is contained in:
parent
8b4f2d8cc2
commit
dfa603012f
2 changed files with 45 additions and 14 deletions
|
@ -86,22 +86,29 @@ class Renderer: NSObject, MTKViewDelegate {
|
||||||
Vertex(position: Point(x: 1, y: 1), textureCoordinate: Point(x: 1, y: 1))
|
Vertex(position: Point(x: 1, y: 1), textureCoordinate: Point(x: 1, y: 1))
|
||||||
]
|
]
|
||||||
|
|
||||||
let buffer = commandQueue.makeCommandBuffer()
|
|
||||||
buffer.label = "Compute + Render"
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let _ = try field.computeEncoderForSamplingKernel(withDevice: device, commandBuffer: buffer)
|
try field.updateBuffers()
|
||||||
} catch let e {
|
} catch let e {
|
||||||
print("\(e)")
|
NSLog("Error updating buffers: \(e)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buffer = commandQueue.makeCommandBuffer()
|
||||||
|
buffer.label = "Render"
|
||||||
|
|
||||||
|
// do {
|
||||||
|
// let _ = try field.computeEncoderForSamplingKernel(withDevice: device, commandBuffer: buffer)
|
||||||
|
// } catch let e {
|
||||||
|
// print("\(e)")
|
||||||
|
// }
|
||||||
|
|
||||||
if let renderPass = view.currentRenderPassDescriptor {
|
if let renderPass = view.currentRenderPassDescriptor {
|
||||||
let encoder = buffer.makeRenderCommandEncoder(descriptor: renderPass)
|
let encoder = buffer.makeRenderCommandEncoder(descriptor: renderPass)
|
||||||
encoder.label = "Render Pass"
|
encoder.label = "Render Pass"
|
||||||
encoder.setViewport(MTLViewport(originX: 0.0, originY: 0.0, width: Double(view.drawableSize.width), height: Double(view.drawableSize.height), znear: -1.0, zfar: 1.0))
|
encoder.setViewport(MTLViewport(originX: 0.0, originY: 0.0, width: Double(view.drawableSize.width), height: Double(view.drawableSize.height), znear: -1.0, zfar: 1.0))
|
||||||
encoder.setRenderPipelineState(renderPipelineState)
|
encoder.setRenderPipelineState(renderPipelineState)
|
||||||
encoder.setVertexBytes(points, length: points.count * MemoryLayout<Vertex>.size, at: 0)
|
encoder.setVertexBytes(points, length: points.count * MemoryLayout<Vertex>.stride, at: 0)
|
||||||
encoder.setFragmentTexture(field.sampleTexture, at: 0)
|
encoder.setFragmentBuffer(field.parametersBuffer, offset: 0, at: 0)
|
||||||
|
encoder.setFragmentBuffer(field.ballBuffer, offset: 0, at: 1)
|
||||||
encoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 6)
|
encoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 6)
|
||||||
encoder.endEncoding()
|
encoder.endEncoding()
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,13 @@ typedef struct {
|
||||||
float2 textureCoordinate;
|
float2 textureCoordinate;
|
||||||
} RasterizerData;
|
} RasterizerData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int2 size;
|
||||||
|
int numberOfBalls;
|
||||||
|
} Parameters;
|
||||||
|
|
||||||
|
typedef half3 Ball;
|
||||||
|
|
||||||
vertex RasterizerData
|
vertex RasterizerData
|
||||||
passthroughVertexShader(uint vid [[vertex_id]],
|
passthroughVertexShader(uint vid [[vertex_id]],
|
||||||
constant Vertex* vertexes [[buffer(0)]])
|
constant Vertex* vertexes [[buffer(0)]])
|
||||||
|
@ -35,19 +42,36 @@ passthroughVertexShader(uint vid [[vertex_id]],
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float sampleAtPoint(float2, constant Ball*, uint);
|
||||||
|
|
||||||
fragment float4
|
fragment float4
|
||||||
sampleToColorShader(RasterizerData in [[stage_in]],
|
sampleToColorShader(RasterizerData in [[stage_in]],
|
||||||
texture2d<half> samples [[texture(0)]])
|
constant Parameters& parameters [[buffer(0)]],
|
||||||
|
constant Ball* balls [[buffer(1)]])
|
||||||
{
|
{
|
||||||
constexpr sampler textureSampler(mag_filter::linear, min_filter::linear);
|
const float sample = sampleAtPoint(in.textureCoordinate, balls, parameters.numberOfBalls);
|
||||||
const half4 sample = samples.sample(textureSampler, in.textureCoordinate);
|
|
||||||
|
|
||||||
float4 out;
|
float4 out;
|
||||||
if (sample.r > 1.0) {
|
if (sample > 1.0) {
|
||||||
out = float4(0.0, 1.0, 0.0, 0.0);
|
out = float4(0.0, 1.0, 0.0, 0.0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
out = float4(0.0, 0.0, 0.0, 0.0);
|
out = float4(0.0, 0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
sampleAtPoint(float2 point,
|
||||||
|
constant Ball* balls,
|
||||||
|
uint count)
|
||||||
|
{
|
||||||
|
float sample = 0.0;
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
constant Ball& ball = balls[i];
|
||||||
|
float r2 = ball.z * ball.z; // Radius stored in z coordinate.
|
||||||
|
float xDiff = point.x - ball.x;
|
||||||
|
float yDiff = point.y - ball.y;
|
||||||
|
sample += r2 / ((xDiff * xDiff) + (yDiff * yDiff));
|
||||||
|
}
|
||||||
|
return sample;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue