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)

  • 相关阅读:
    第三周作业
    #第四周作业
    第十二周作业
    第十一周作业
    第九周作业
    第八周作业
    2019第七周作业
    第三次实验报告及第五次课程总结
    第二次课程总结&学习总结
    第三周实验和学习总结
  • 原文地址:https://www.cnblogs.com/psklf/p/6075088.html
Copyright © 2011-2022 走看看