【发布时间】:2021-06-03 17:20:51
【问题描述】:
我正在开发一个自定义金属着色器,我正在尝试从着色器玩具中复制这种特殊效果:https://www.shadertoy.com/view/3sfcR2
但我似乎无法理解如何将他们的texture() 函数转换为金属着色器格式。有任何想法吗?
这是我目前在 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);
}
编辑: 按照@JustSomeGuy 的回答,我能够在Metal 中成功复制这个着色器。这是最终版本:
#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);
}
向@JustSomeGuy 致敬!感谢您的帮助!
【问题讨论】:
-
我觉得我还不错,但没那么好。所以考虑到这一点。高水平?你以前和 Metal 合作过吗?您是否从任何东西中完成了这种类型的复制 - 简单与否?问题与着色玩具纹理有关吗?或者将其转换为金属纹理?你有什么工作 - 什么? (老实说,最后一点是恭敬的。)从
CoreImage内核代码转换为 Metal 对我来说已经够难的了——如果它涉及到访问超出正在处理的像素之外的像素。所以我想我真正的问题是:你能让 any 着色器工作吗?我可能会帮助分析这个问题。
标签: swift graphics metal metalkit