Android eyes spherical refraction

Keywords: Attribute github less Android

Design sketch

thinking

Use the built-in refract function, because what you want to draw is a sphere, so there is the center and radius of the sphere. Use the distance function to calculate the distance. If the distance between the center and the sphere is less than the radius, use the refract function to refract, if not, display the original picture.

Shader

Vertex shader

attribute vec4 position;
attribute vec4 textureCoord;
varying vec4 textureCoordinate;

uniform mat4 cameraTransform;

void main() {
    textureCoordinate =  cameraTransform * textureCoord;
    gl_Position = position;
}

cameraTransform is the matrix that the system will return to us when using Android Camera.

Fragment 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: display view aspect ratio width/height
    textureCoordinateToUse.y = textureCoordinateToUse.y * u_aspectRatio;
    Without this line of code, it would be an ellipse

  • Refractive index: refractive index 0.7

Github project code download

https://github.com/larry-kof/BallShaderDemo

Posted by php4geek on Sun, 20 Oct 2019 09:29:01 -0700