I am working on a custom Metal shader, and I am trying to replicate this particular effect from shader toy: https://www.shadertoy.com/view/3sfcR2
But I can't seem to understand how to convert their texture() function to the Metal shader format. Any ideas?
Here's what I have so far in Metal:
#include <metal_stdlib>
using namespace metal;
kernel void chromaticAberration(texture2d<float, access::read> inTexture [[ texture(0) ]],
texture2d<float, access::write> outTexture [[ texture(1) ]],
device const float *time [[ buffer(0) ]],
uint2 gid [[ thread_position_in_grid ]])
{
float ChromaticAberration = 0.0 / 10.0 + 8.0;
// get the width and height of the screen texture
uint width = outTexture.get_width();
uint height = outTexture.get_height();
// set its resolution
float2 iResolution = float2(width, height);
float4 orig = inTexture.read(gid);
float2 uv = orig.xy / iResolution.xy;
float2 texel = 1.0 / iResolution.xy;
float2 coords = (uv - 0.5) * 2.0;
float coordDot = dot (coords, coords);
float2 precompute = ChromaticAberration * coordDot * coords;
float2 uvR = uv - texel.xy * precompute;
float2 uvB = uv + texel.xy * precompute;
// How to convert these texture() functions?
float r = texture(iChannel0, uvR).r;
float g = texture(iChannel0, uv).g;
float b = texture(iChannel0, uvB).b;
float a = 1.;
const float4 colorAtPixel = float4(r,g,b,1.0);
outTexture.write(colorAtPixel, gid);
}
EDIT: Following the answer of @JustSomeGuy I was able to successfully replicate this shader in Metal. Here is the final version:
#include <metal_stdlib>
using namespace metal;
kernel void chromaticAberration(texture2d<float, access::read> inTexture [[ texture(0) ]],
texture2d<float, access::write> outTexture [[ texture(1) ]],
texture2d<float, access::sample> sampleTexture [[ texture(2) ]],
device const float *time [[ buffer(0) ]],
uint2 gid [[ thread_position_in_grid ]])
{
float ChromaticAberration = 0.0 / 10.0 + 8.0;
// get the width and height of the screen texture
uint width = inTexture.get_width();
uint height = inTexture.get_height();
// set its resolution
float2 iResolution = float2(width, height);
float2 uv = float2(gid) / iResolution.xy;
float2 texel = 1.0 / iResolution.xy;
float2 coords = (uv - 0.5) * 2.0;
float coordDot = dot (coords, coords);
float2 precompute = ChromaticAberration * coordDot * coords;
float2 uvR = uv - texel.xy * precompute;
float2 uvB = uv + texel.xy * precompute;
constexpr sampler s(address::clamp_to_edge, filter::linear);
float r = sampleTexture.sample(s, uvR).r;
float g = sampleTexture.sample(s, uv).g;
float b = sampleTexture.sample(s, uvB).b;
const float4 colorAtPixel = float4(r,g,b,1.0);
outTexture.write(colorAtPixel, gid);
}
Kudos to @JustSomeGuy! Thank you for your help!