您可以使用我开源的
GPUImage框架中的GPUImageSphereRefractionFilter来实现这一点:
![Spherical refraction example](https://istack.dev59.com/j616B.webp)
我会详细描述在
这个答案中关于Android上类似影响的工作原理。基本上,我使用片段着色器折射通过想象中的球体穿过的光线,然后我使用它来查找包含源图像的纹理。背景使用简单的高斯模糊进行模糊处理。
如果您想获得与您展示的图像完全相同的外观,则可能需要调整此片段着色器以向球体添加一些刮擦角度颜色,但这应该可以让您接近。
出于乐趣,我决定尝试更加精确地复制上面的玻璃球。我添加了刮擦角度照明和球体上的镜面反射照明,以及不反转折射纹理坐标,导致了这个结果:
![Grazing angle lighting sphere](https://istack.dev59.com/R1da0.webp)
我为这个新版本使用了以下片段着色器:
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float aspectRatio;
uniform highp float refractiveIndex;
const highp vec3 lightPosition = vec3(-0.5, 0.5, 1.0);
const highp vec3 ambientLightPosition = vec3(0.0, 0.0, 1.0);
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 = 2.0 * refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);
refractedVector.xy = -refractedVector.xy;
highp vec3 finalSphereColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5).rgb;
highp float lightingIntensity = 2.5 * (1.0 - pow(clamp(dot(ambientLightPosition, sphereNormal), 0.0, 1.0), 0.25));
finalSphereColor += lightingIntensity;
lightingIntensity = clamp(dot(normalize(lightPosition), sphereNormal), 0.0, 1.0);
lightingIntensity = pow(lightingIntensity, 15.0);
finalSphereColor += vec3(0.8, 0.8, 0.8) * lightingIntensity;
gl_FragColor = vec4(finalSphereColor, 1.0) * checkForPresenceWithinSphere;
}
这个滤镜可以通过GPUImageGlassSphereFilter运行。
CoreImage
参考资料,滤镜CIGlassLozenge
在 iOS 上不可用。因此,这并没有让您的生活变得更加轻松,因为您必须找到第三方库或代码片段来达到此效果。 - holex