Camera 鱼眼广角镜头:可能吗?

Camera 鱼眼广角镜头:可能吗?,camera,scenekit,Camera,Scenekit,如何获得像鱼眼镜头对场景套件中带有SCNCamera的视图所做的失真 类似于这种“鞠躬”的意象: //正如里克斯特所指出的,这种变形称为“桶形变形” 从文档中可以看出,这一部分让我对使用相机进行这种失真的可能性产生了兴趣: 如果您计算自己的投影变换矩阵,您可以使用 方法直接设置它,并重写所合成的转换 从摄影机的几何特性 不幸的是,我对计算自己的投影变换矩阵的能力和可能性一无所知。我希望有可能通过它来做这种失真。。。但不知道,这就是问题所在 通过相机的任何其他方式都是理想的。也希望避免后期处理技

如何获得像鱼眼镜头对场景套件中带有SCNCamera的视图所做的失真

类似于这种“鞠躬”的意象:

//正如里克斯特所指出的,这种变形称为“桶形变形”

从文档中可以看出,这一部分让我对使用相机进行这种失真的可能性产生了兴趣:

如果您计算自己的投影变换矩阵,您可以使用 方法直接设置它,并重写所合成的转换 从摄影机的几何特性

不幸的是,我对计算自己的投影变换矩阵的能力和可能性一无所知。我希望有可能通过它来做这种失真。。。但不知道,这就是问题所在

通过相机的任何其他方式都是理想的。也希望避免后期处理技巧,并在摄影机旋转和移动场景时获得这种失真的更“有机”外观


查看任何滑板视频,了解这在现实生活中的表现。

你所寻找的是所谓的桶形失真

有几种方法可以做到这一点,它们都使用GLSL着色器

您可以使用经典的OpenGL代码,例如用于Occulus Rift(您需要稍微更改着色器),也可以使用我个人最喜欢的:
SCNTechnique

创建包含桶碎片着色器(.fsh)的技术,并将其
draw
参数设置为
draw\u QUAD
。然后,简单地将该技术应用到您的相机上

您可以在此处找到桶形失真着色器的示例:


编辑:以下是示例代码:

barrel.json(这应该放在您的scnassets包中)

barrel.vsh

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = a_position.xy;
}
// Adapted from :
// http://www.geeks3d.com/20140213/glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters/2/

uniform sampler2D colorSampler;
const float PI = 3.1415926535;
uniform float barrelPower;

varying vec2 uv;


vec2 Distort(vec2 p)
{
    float theta  = atan(p.y, p.x);
    float radius = length(p);
    radius = pow(radius, barrelPower);
    p.x = radius * cos(theta);
    p.y = radius * sin(theta);
    return 0.5 * (p + 1.0);
}


void main() {

    vec2 rg = 2.0 * uv.xy - 1.0;
    vec2 uv2;
    float d = length(xy);
    if (d < 1.0){
        uv2 = Distort(xy);
    }else{
        uv2 = uv.xy;
    }

    gl_FragColor = texture2D(colorSampler, uv2);
}
桶。fsh

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = a_position.xy;
}
// Adapted from :
// http://www.geeks3d.com/20140213/glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters/2/

uniform sampler2D colorSampler;
const float PI = 3.1415926535;
uniform float barrelPower;

varying vec2 uv;


vec2 Distort(vec2 p)
{
    float theta  = atan(p.y, p.x);
    float radius = length(p);
    radius = pow(radius, barrelPower);
    p.x = radius * cos(theta);
    p.y = radius * sin(theta);
    return 0.5 * (p + 1.0);
}


void main() {

    vec2 rg = 2.0 * uv.xy - 1.0;
    vec2 uv2;
    float d = length(xy);
    if (d < 1.0){
        uv2 = Distort(xy);
    }else{
        uv2 = uv.xy;
    }

    gl_FragColor = texture2D(colorSampler, uv2);
}

文档中说有xFov和yFov(视野)参数可以控制。将它们设置为高值(默认值为60度)将导致失真。它们不是独立的,将它们设置为高值也不会产生这种失真。它只是通过透视来加宽视图。更准确地说,调整x或y视场意味着自动调整另一个视场以匹配当前窗口的纵横比。高视场只会导致直线失真,而不是桶形失真。好的调用-
SCNTechnique
用于渲染后处理,因此,使用一种技术在着色器中完成这一切可以让您将管道的其余部分放在一边,并将代码保持在最低限度(只是一个片段着色器和技术列表中用于配置它的一些内容)。这很好,但我特别想知道,SCNCamera是否可以使用矩阵变换和其他奇迹,这就是问题的标题。简短回答:还没有。不过,多亏了ModelIO和新版本,您应该很快就能获得鱼眼效果,而无需额外的代码。就目前而言,我们所能访问的还不够。@m如果3D管道没有多大作用,它又有什么意义呢?为什么要宣传它(就像WWDC的视频那样),好像它是完全整合和兼容的。。。当它离那不远的时候。还有:这里有一个列表,列出了它可以做什么,与SceneKit兼容还是不兼容。PBR不通过模型I/O成为SceneKit的一部分是一个真正的WTF时刻。使整个WWDC视频看起来像Unity所做的那种“营销”“我假设你为苹果公司工作。”我添加了一个代码示例。我在这里写的,所以它可能需要一些调试,但总体工作流程在那里。如果你有任何问题,请告诉我!