效果图
思路
利用内置的refract函数,因为要画的是球形,所以有球心和半径,利用distance函数计算距离,如果和球心的距离小于半径就利用refract函数实现折射,如果不是就显示原图。
Shader
顶点shader
attribute vec4 position;
attribute vec4 textureCoord;
varying vec4 textureCoordinate;
uniform mat4 cameraTransform;
void main() {
textureCoordinate = cameraTransform * textureCoord;
gl_Position = position;
}
其中cameraTransform是使用Android Camera的时候系统会返回给我们的矩阵。
片段shader
#extension GL_OES_EGL_image_external : require
varying highp vec4 textureCoordinate;
uniform samplerExternalOES inputImageTexture;
uniform highp float u_radius;
uniform highp float u_refractiveIndex;
uniform highp float u_aspectRatio;
uniform highp vec2 u_center;
void main(){
highp vec2 textureCoordinateToUse = textureCoordinate.xy;
textureCoordinateToUse.y = textureCoordinateToUse.y * 2.0 - 1.0;
textureCoordinateToUse.y = textureCoordinateToUse.y * u_aspectRatio;
textureCoordinateToUse.y = (textureCoordinateToUse.y + 1.0 ) * 0.5;
highp float distanceFromCenter = distance(u_center, textureCoordinateToUse);
highp float distance1 = distanceFromCenter / u_radius;
highp float normalizedDepth = u_radius * sqrt(1.0 - distance1 * distance1);
highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - u_center, normalizedDepth));
highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, u_refractiveIndex);
if( distanceFromCenter > u_radius ) gl_FragColor = texture2D(inputImageTexture, textureCoordinate.xy);
else {
highp vec2 texCoord = vec2(-refractedVector.x, -refractedVector.y);
texCoord = (texCoord + 1.0) * 0.5;
gl_FragColor = texture2D(inputImageTexture, texCoord);
}
-
u_aspectRatio :显示view宽高比 width/height
textureCoordinateToUse.y = textureCoordinateToUse.y * u_aspectRatio;
如果没有这一行代码,就会变成椭圆形 -
u_refractiveIndex:折射率 0.7