鱼眼广角与场景工具包相机:可能? [英] Fish Eye Wide-angle with a Scene Kit Camera: Possible?

查看:298
本文介绍了鱼眼广角与场景工具包相机:可能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用场景工具包中的SCNCamera来获得鱼眼镜头对于视图的畸变?



像这样的弯曲图像:



>



//如Rickster指出的,这种失真被称为Barrel Distortion。



从文档中,这部分让我对使用相机进行这种变形的可能性感兴趣:


如果你计算自己的投影变换矩阵,你可以使用
方法直接设置它,覆盖从相机的几何属性合成的变换
。 / p>

不幸的是,我不知道计算自己的投影变换矩阵的能力和可能性。我希望这可能通过它做这种扭曲...但dunno,因此的问题。



任何其他手段通过相机是理想的。太。想要避免后处理的诡计,并获得更多的有机的外观,当相机旋转和移动的场景这种扭曲。



查看任何滑板视频如何

解决方案

您正在寻找的是Barrel Distrortion。



有几种方法可以使用GLSL着色器。



您可以使用传统的OpenGL代码,例如这个例子为Occulus Rift(你需要改变着色器一点点) ,或我个人最喜欢的: SCNTechnique



创建一个包含Barrel Fragment Shader(.fsh)将其 draw 参数设置为 DRAW_QUAD



您可以在这里找到一个Barrel Distortion着色器的示例: http://www.geeks3d.com/20140213/ glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters / 2 /






编辑:这里是一个示例代码:



barrel.json (这应该放在你的scnassets包) / p>

  {
passes:{
barrel:{
outputs {
color:COLOR
},
inputs:{
colorSampler:COLOR,
noiseSampler:noiseSymbol ,
a_position:a_position-symbol
},
program:art.scnassets / barrel,
draw:DRAW_QUAD

},
sequence:[
barrel
],
symbols:{
a_position-symbol
semantic:vertex
},
noiseSymbol:{
image:noise.png,
type:sampler2D
},
barrelPower:{
type:float
}
}
}



barrel.vsh

  attribute vec4 a_position; 
varying vec2 uv;

void main(){
gl_Position = a_position;
uv = a_position.xy;
}

barrel.fsh
$ b

  //改编自:
// 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扭曲(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);
}

something.m
$ b

  NSURL * url = [[NSBundle mainBundle] URLForResource:@art.scnassets / barrelwithExtension:@json]; 
NSDictionary * tecDic = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:url] options:nil error:nil];

SCNTechnique * technique = [SCNTechnique techniqueWithDictionary:tecDic];

[technique setValue:[NSNumber numberWithFloat:0.5] forKey:@barrelPower];


cameraNode.technique = technique;


How do I get a distortion like what a fisheye lens does to a view with a SCNCamera in Scene Kit?

Something like this kind of "bowing" of the imagery:

// as Rickster pointed out, this kind of distortion is known as "Barrel Distortion".

From the docs, this is the part that got me intrigued by the possibility of doing this kind of distortion with the camera:

If you compute your own projection transform matrix, you can use this method to set it directly, overriding the transformation synthesized from the camera’s geometric properties.

Unfortunately I know nothing about the powers and possibilities of computing ones own projection transform matrix. I'm hoping it's possible to do this kind of distortion via it... but dunno, hence the question.

Any other means via a camera is ideal. Too. Wanting to avoid post processing trickery and get the more "organic" look of this kind of distortion when the camera rotates and moves through the scene.

See any skateboarding video for how this looks in real life.

解决方案

What you are looking for is called Barrel Distrortion.

There are a few ways of doing this, all of them using GLSL shaders.

You can either use classic OpenGL code, such as this example for the Occulus Rift (you will need to change the shader a little bit), or my personal favorite: SCNTechnique.

Create a technique containing a Barrel Fragment Shader (.fsh), and set its draw parameter to DRAW_QUAD. Then, simply apply the technique to your camera.

You can find an example of Barrel Distortion shader here : http://www.geeks3d.com/20140213/glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters/2/


EDIT: here's a sample code:

barrel.json (this should go in your scnassets bundle)

{
  "passes" : {
    "barrel" : {
      "outputs" : {
        "color" : "COLOR"
      },
      "inputs" : {
        "colorSampler" : "COLOR",
        "noiseSampler" : "noiseSymbol",
        "a_position" : "a_position-symbol"
      },
      "program" : "art.scnassets/barrel",
      "draw" : "DRAW_QUAD"
    }
  },
  "sequence" : [
    "barrel"
  ],
  "symbols" : {
    "a_position-symbol" : {
      "semantic" : "vertex"
    },
    "noiseSymbol" : {
      "image" : "noise.png",
      "type" : "sampler2D"
    },
    "barrelPower" : {
      "type" : "float"
    }
  }
}

barrel.vsh

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = a_position.xy;
}

barrel.fsh

// 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);
}

something.m

NSURL *url = [[NSBundle mainBundle] URLForResource:@"art.scnassets/barrel" withExtension:@"json"];
NSDictionary *tecDic = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL: url] options:nil error:nil];

SCNTechnique* technique = [SCNTechnique techniqueWithDictionary:tecDic];

[technique setValue: [NSNumber numberWithFloat:0.5]  forKey:@"barrelPower"];


cameraNode.technique = technique;

这篇关于鱼眼广角与场景工具包相机:可能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆