使用 OpenGL ES 在运行时为图像添加鱼眼效果 [英] Add Fisheye effect to images at runtime using OpenGL ES

查看:33
本文介绍了使用 OpenGL ES 在运行时为图像添加鱼眼效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的情况是我从服务器接收到不同的图像到 iPhone 客户端.

我需要做的是为这些图像添加鱼眼效果.

我的幻觉是我可以构建一个圆顶对象,然后在图像出现时将它们附加到它.

如果有人能给我任何正确方向的指点,我将不胜感激.

解决方案

你有没有试过看 Paul Bourke 的例子OpenGL的代码?我不知道它是否与 OpenGL-ES 兼容.请注意有关使用glCopyTexSubImage2D 而不是执行缓慢的 glReadPixels"的反馈.

AFAICT,Paul Bourke 基本上按照您所说的做,创建了一个扭曲的网格(您的圆顶对象")来放置图像.根据this question,这是一个好方法.

更新:

或者,由于 iPhone 的 OpenGL-ES 支持着色器(至少在某些版本中),您可以使用像 这个.您只需更改 uv.xuv.y 的公式.那么您就不必担心将图像分解成一个由小多边形组成的网格……您将免费获得单像素分辨率.:-)

嗯...也许你需要定义你正在寻找什么样的鱼眼"效果.似乎有不止一个.

另请参阅这个问题.p>

再次更新:

这是我编写的一些 GLSL 代码,用于在着色器中制作镜头效果.我相信这是一个半球形的鱼眼镜头.它运行在使用OpenGL ES的WebGL下,因此它应该适用于iPhone.

#ifdef GL_ES高精度高浮点;#万一统一的 vec2 分辨率;统一的 vec4 鼠标;统一的sampler2D tex0;//镜头无效主要(无效){vec2 p = gl_FragCoord.xy/resolution.xy;vec2 m = mouse.xy/resolution.xy;浮动镜头大小 = 0.4;vec2 d = p - m;浮动 r = sqrt(点(d, d));//像素到鼠标的距离vec2紫外线;if (r >= lensSize) {紫外线 = p;} 别的 {//感谢 Paul Bourke 提供这些公式;看//http://paulbourke.net/miscellaneous/lenscorrection///和 .../lenscorrection/lens.c//选择一个公式取消注释://正方形://uv = m + vec2(d.x * abs(d.x), d.y * abs(d.y));//平方:紫外线 = 米 + d * r;//又名 m + normalize(d) * r * r//正弦://uv = m + normalize(d) * sin(r * 3.14159 * 0.5);//ASINR://uv = m + normalize(d) * asin(r)/(3.14159 * 0.5);}vec3 col = texture2D(tex0, vec2(uv.x, -uv.y)).xyz;gl_FragColor = vec4(col, 1.0);}

要对此进行测试,请将其粘贴到支持 WebGL 的浏览器中的 ShaderToy 中.将输入 0 设置为纹理,例如 http://www.iquilezles.org/apps/shadertoy/presets/tex0.jpghttp://www.iquilezles.org/apps/shadertoy/presets/tex4.jpg

单击播放按钮,然后在渲染区域上拖动鼠标.镜头以鼠标指针为中心.

my situation is that i receive different images from the server onto the iPhone client.

what i need to do is to add a Fisheye effect to those images.

what my hallucination is that i can build a dome object, then attach images to it as they come to me.

if anyone can give me any pointers to the right direction i'll be thankful.

解决方案

Have you tried looking at Paul Bourke's example code for OpenGL? I don't know if it's compatible with OpenGL-ES. Note the feedback about using "glCopyTexSubImage2D instead of doing a slow glReadPixels".

AFAICT, Paul Bourke is doing essentially what you said, creating a distorted grid (your "dome object") to lay the image on. According to this question, that's a good approach.

Updated:

Or, since iPhone's OpenGL-ES supports shaders (at least in some versions), you could get better performance using a plane distortion technique like this. You'd just have to change the formulas for uv.x and uv.y. Then you wouldn't need to be concerned about breaking up the image into a grid of small polygons... you'd have single-pixel resolution for free. :-)

Hm... maybe you need to define what kind of "fisheye" effect you are looking for. Seems there is more than one.

See also this question.

Updated again:

Here is some GLSL code I wrote to do a lens effect in a shader. I believe it's a hemispherical fisheye lens. It runs under WebGL, which uses OpenGL ES, so it should be adaptable for iPhone.

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform vec4 mouse;
uniform sampler2D tex0;

// lens
void main(void)
{
    vec2 p = gl_FragCoord.xy / resolution.xy;
    vec2 m = mouse.xy / resolution.xy;
    float lensSize = 0.4;

    vec2 d = p - m;
    float r = sqrt(dot(d, d)); // distance of pixel from mouse

    vec2 uv;
    if (r >= lensSize) {
        uv = p;
    } else {
        // Thanks to Paul Bourke for these formulas; see
        // http://paulbourke.net/miscellaneous/lenscorrection/
        // and .../lenscorrection/lens.c
        // Choose one formula to uncomment:
        // SQUAREXY:
        // uv = m + vec2(d.x * abs(d.x), d.y * abs(d.y));
        // SQUARER:
        uv = m + d * r; // a.k.a. m + normalize(d) * r * r
        // SINER:
        // uv = m + normalize(d) * sin(r * 3.14159 * 0.5);
        // ASINR:
        // uv = m + normalize(d) * asin(r) / (3.14159 * 0.5);
    }

    vec3 col = texture2D(tex0, vec2(uv.x, -uv.y)).xyz;

    gl_FragColor = vec4(col, 1.0);
}

To test this, paste it into ShaderToy in a WebGL-enabled browser. Set input 0 to a texture like http://www.iquilezles.org/apps/shadertoy/presets/tex0.jpg or http://www.iquilezles.org/apps/shadertoy/presets/tex4.jpg

Click the play button, and drag the mouse around on the rendering area. The lens is centered on the mouse pointer.

这篇关于使用 OpenGL ES 在运行时为图像添加鱼眼效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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