1. Переходим в осесимметричное пространство,
2. Считаем сдвиг для каждого канала отдельно
3. Переходим обратно
4. Сэмплим каждый канал отдельно
Чтобы было физично, у красного k1 должен быть положительный, у синего - отрцательный, у зеленого - ноль
static inline float2 distortion(float2 uv, float2 C, float2 aspect, float2 k) {
float2 d = uv - C;
float2 diso = d * aspect;
float r2 = dot(diso, diso);
float r4 = r2 * r2;
float s = 1.0 + k.x * r2 + k.y * r4; // 1 + k1 r^2 + k2 r^4
float2 xu_iso = diso / max(s, 1e-6);
return C + xu_iso / aspect;
}
потом
//...
float2 uvR = distortion(in.uv, U.center, U.aspect, U.kR);
float2 uvG = distortion(in.uv, U.center, U.aspect, U.kG);
float2 uvB = distortion(in.uv, U.center, U.aspect, U.kB);
float r = src.sample(S, uvR).r;
float g = src.sample(S, uvG).g;
float b = src.sample(S, uvB).b;