Рыбий глаз Широкоугольный с камерой комплекта сцены: возможно?
Как получить искажение, подобное тому, что объектив "рыбий глаз" делает с изображением с помощью SCNCamera в наборе сцен?
Что-то вроде этого типа "изгиба" образов:
// как указал Рикстер, этот вид искажения известен как "искажение по бочонку".
Из документов, это та часть, которая меня заинтриговала возможностью делать такие искажения с камерой:
Если вы вычисляете свою собственную матрицу проекционного преобразования, вы можете использовать этот метод, чтобы установить ее напрямую, переопределив преобразование, синтезированное из геометрических свойств камеры.
К сожалению, я ничего не знаю о возможностях и возможностях вычисления собственной матрицы проекционного преобразования. Я надеюсь, что это возможно сделать с помощью этого искажения... но не знаю, отсюда и вопрос.
Любое другое средство с помощью камеры идеально. Тоже. Желание избежать хитрости постобработки и получить более "органичный" вид такого искажения, когда камера вращается и перемещается по сцене.
Посмотрите любое видео о скейтбординге, чтобы узнать, как это выглядит в реальной жизни.
1 ответ
То, что вы ищете, называется "бочонок".
Есть несколько способов сделать это, все они используют шейдеры 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/
РЕДАКТИРОВАТЬ: вот пример кода:
баррель.json (это должно идти в вашем комплекте scnassets)
{
"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;