2018.11.29

  • 人×技術

WebGL x 歪曲収差

歪曲収差

歪曲収差は、ザイデル収差の一種であり、要約してしまえば、像を陣笠に歪ませる効果と言える。今回は、写像に対し、この歪曲収差を反映させる実装、およびその結果を示す。

中心座標をcxとcy対象座標をpxとpyとした場合、中心からの距離dは

 

 

で求まる。

また、単位半径の半球面で考えると、対象座標の奥行pzは

 

 

になることがわかる。

奥行に対する角度θは

 

 

 

になるため、xy平面における半径rを

 

 

 

と仮定する。

距離dのx成分dxとy成分dyから、xy平面における角度ϕは

 

 

 

になる。

この時点で、xy平面における半径と角度が判明しているため、極座標系で示すことができる。

最終的には、極座標系ではなく、直交座標系で考えればよいので

 

 

 

により、歪曲収差後の座標px'とpy'が求まる。

以上の計算から

 

 

 

 

のように歪ませることが期待できる。

実装

通常のカメラ映像をバッファにレンダリングしておき、そのバッファに対して画像処理を施す、いわゆるポストエフェクトとして実装する。今回の歪曲収差効果において、頂点パイプラインでは、通常の MVP 変換行列をかけているだけであり、画素パイプラインで前述のアルゴリズムに従い計算を行う。下記は、WebGL (GLSL) の実装例になる。

頂点処理

varying vec2 vUv;
void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

画素処理

varying vec2 vUv;
uniform sampler2D inputBuffer;
void main() {
    vec2 coord = vUv * 2.0 - 1.0;
    float d = length(coord);
    if (d > 1.0) {
        gl_FragColor = vec4(texture2D(inputBuffer, vUv).rgb * 0.25, 1.0);
        return;
    }
    float r = atan(d, 1.0 - dot(coord, coord) * 0.5) / 3.1415926;
    float phi = atan(coord.y, coord.x);
    coord = vec2(cos(phi), sin(phi)) * r;
    gl_FragColor = texture2D(inputBuffer, coord + 0.5);
}

結果

下記のリンクで WebGL (GLSL) の実装例の結果が確認できる。

WebGL x 歪曲収差

この記事を書いた人 :
4009運営チーム

この記事をシェアする

すべての記事