zoukankan      html  css  js  c++  java
  • 鱼眼投影方式(Fisheye projection)的软件实现

    简单实现

    鱼眼模式(Fisheye)和普通的透视投影(Perspective projection),一个很大的区别就是鱼眼的投影算法是非线性的(non-linear),实际照相机的情况是在镜头外面包围一个半球体,将场景通过半球体投影到画布上。大致如下:

                   M
                     x                 
                                      
                         ______       
                     M'_x'      `-.
                     ,' |         `.
                    /   |           
                   /    |            
                  |     |             |
        __________|_____|____\_________|_________
                        M"    O        1
                        
    M: world position
    M': projection of M on the unit hemisphere
    M": projection of M' on the unit disc (= the screen)
    
    

    上面这个示意图来自stack exchange 的回答,是Sam Hocever画的

    vertex shader 绘制一个长宽均为1的正方形,作为远处的物体,纹理实际贴在这个正方形上面。

    在 fragement shader 内将上面的这个算法实现即可。

    设我们在屏幕上的点为(x0, y0) 直接得到外面球面上的点是
    (x0, y0, z0) and z0 = sqrt(1 - x0^2 - y0^2)
    远处平面上的点和球面上的点共线所以坐标成比例关系,直接设x1 = a * x0然后假设我们的远处的物体就是一个平面,处于 z1 = -1 的位置,直接得到:

    因为: 
    abs(z1) = 1 = z0 * a
    z0 = sqrt(1 - x0^2 - y0^2)
    所以:
    a = 1.0 / z0 = 1.0 / (sqrt(1 - x0^2 - y0^2))
    

    当然远处平面的位置可以调整,离的近就大,离的远就小,但是大小是不变的,仍然是一个边长为 1 的正方形。所以可以调整的就是这个距离,也是 z1 的值。Sam Hocever 提供的思路是改变这个投影的 fov 的值。当 fov = PI / 2 时,和我刚刚设定的值一样,z1 = -1。两者关系为
    z1 = 0.5 / tan(theta / 2)

    总结:a = z1 / z0 = 0.5 / ((sqrt(1 - x0^2 - y0^2)) * tan(theta / 2))

    其他实现方式

    主要参考 Computer Generated Angular Fisheye Projections
    上文介绍了两种投影的方式,第一种前文已经解释,后一种方式我正在学习中。

    另外还有一个经典的项目,blinky
    提供另外一种解决的办法,先弄出一个包围盒,纹理贴在包围盒上,然后在转换成鱼眼效果。
    具体的实现看源码。

    本文的主要参考链接

    [How do I create a wide-angle / fisheye lens with HLSL?](http://
    gamedev.stackexchange.com/questions/20626/how-do-i-create-a-wide-angle-fisheye-lens-with-hlsl)

  • 相关阅读:
    PAT B1045 快速排序 (25 分)
    PAT B1042 字符统计 (20 分)
    PAT B1040 有几个PAT (25 分)
    PAT B1035 插入与归并 (25 分)
    PAT B1034 有理数四则运算 (20 分)
    PAT B1033 旧键盘打字 (20 分)
    HDU 1231 最大连续子序列
    HDU 1166 敌兵布阵
    HDU 1715 大菲波数
    HDU 1016 Prime Ring Problem
  • 原文地址:https://www.cnblogs.com/psklf/p/6075088.html
Copyright © 2011-2022 走看看