我必须在 android 中的图像上应用球形滤镜,我已经附加了输入和预期的输出图像。输出图像将从输入图像的平方中心区域处理,并将其映射到球体。知道如何在 Android 中执行此操作。我是否必须使用 openGL 来执行此操作,或者仅使用 2D 转换来完成该任务。
4 回答
我刚刚在 iOS 上使用 OpenGL ES 2.0 实现了这项工作:
虽然这是在 iOS 上,但我使用的片段着色器可以直接带到 Android 上。球面折射部分是使用以下片段着色器完成的:
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float aspectRatio;
uniform highp float refractiveIndex;
void main()
{
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
highp float distanceFromCenter = distance(center, textureCoordinateToUse);
lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);
distanceFromCenter = distanceFromCenter / radius;
highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);
highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));
highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);
gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;
}
是球体中心的center
归一化坐标(从两个维度的 0.0 - 1.0 空间),radius
是归一化半径,refractiveIndex
是球体的空气/材料指数,aspectRatio
是图像的纵横比(以确保球体在归一化坐标空间中是圆形而不是椭圆形)。
这将使用提供的中心和半径计算球体的表面法线,并使用 GLSLrefract()
函数折射传入矢量并提供图像纹理中的查找坐标。
使用我在此答案中描述的可分离高斯模糊来模糊背景。
此过滤器的速度足以在 iPhone 上实时过滤实时视频,因此它在大多数 Android 设备上的性能应该相当不错。它的源代码可以在我的开源GPUImage框架中的 GPUImageSphereRefractionFilter 中找到。
以下代码Fish Eye lens用于创建球体并应用一些修改来缩放球体和背景生成,它主要适用于方形图像。
这是一个光线追踪问题。OpenGL 很可能对您没有帮助,因为 OpenGL 不提供基于光线的 3D。但是,这可能是您正在寻找的。
http://www1.cs.columbia.edu/CAVE/publications/pdfs/Garg_TR04.pdf
我同意蒂姆的观点。将一个位图转换为另一个位图不需要 3d 点,也不需要 Ray-trace,完全忘记它,它只是 2d。我不知道 opengl 是否内置了一些东西,但我有足够的 3d 经验来为您指明正确的方向。您必须迭代您选择的 *circle 区域内的所有点 *这是线索,并使用 FISH-EYE 变换找到颜色。你在网上有很多。希望这可以帮助