2

What is the best way to render glass/ice materials on Android devices with no ray tracing?

I have seen aplha+blending but even with proper lighting, the results just looked "plastic".

Can we do better?

genpfault
  • 51,148
  • 11
  • 85
  • 139
daemontus
  • 1,047
  • 10
  • 17

2 Answers2

0

You need proper reflection and refraction to draw good looking transparent materials.

You basically need environment texture as a source of reflection/refraction. I recommend to render the scene without transparent material to make the environmental source texture. Cube-mapping is usually recommended.

Visit here to see how to implement reflection and refraction.

eonil
  • 83,476
  • 81
  • 317
  • 516
0

To create a simple glass effect in Android (OpenGL ES 3.0), you can use: refraction + shininess + transparency.

Vertex Shader:

#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;
uniform mat4 u_mvMatrix;

in vec4 a_position; 
in vec3 a_normal;

out vec3 v_normal;
out lowp float SpecularIntensity;

out vec3 v_eyeDirectModel;

float getSpecularIntensity(vec4 position, vec3 a_normal, vec3 eyeDirectModel) {
    float shininess = 30.0;
    vec3 lightPosition = vec3(-20.0, 0.0, 0.0);
    // We ignore that N dot L could be negative (light coming from behind the surface)
    mediump vec3 LightDirModel = normalize(lightPosition - position.xyz);
    mediump vec3 halfVector = normalize(LightDirModel + eyeDirectModel);
    lowp float NdotH = max(dot(a_normal, halfVector), 0.0);
    return pow(NdotH, shininess);
}

void main() {
    v_normal = a_normal;
    vec4 eyePositionModel = u_mvMatrix * a_position;
    // Eye direction in model space
    vec3 eyeDirectModel = normalize(- eyePositionModel.xyz);
    // specular lighting
    SpecularIntensity = getSpecularIntensity(a_position, a_normal, eyeDirectModel);
    v_eyeDirectModel = eyeDirectModel;
    gl_Position = u_mvpMatrix * a_position;
}

Fragment Shader:

#version 300 es
precision lowp float;
uniform mat4 u_mvpMatrix;

in vec3 v_normal;
in lowp float SpecularIntensity;
in vec3 v_eyeDirectModel;

out vec4 outColor; 
uniform samplerCube s_texture; // skybox

const float eta = 0.65;
void main() {
    // Calculate refraction direction in model space
    vec3 refractDirect = refract(v_eyeDirectModel, normalize(v_normal), eta);
    // Project refraction
    refractDirect = (u_mvpMatrix * vec4(refractDirect, 0.0)).xyw;
    // Map refraction direction to 2d coordinates
    vec2 refractCoord = 0.5 * (refractDirect.xy / refractDirect.z) + 0.5;

    vec4 glassColor = texture(s_texture, vec3(refractCoord, 1.0));
    outColor = glassColor + SpecularIntensity;
    outColor.a = 0.8; // transparent
}

Result:

enter image description here

enter image description here

The code is partially taken from PVRShamanGUI.

alexrnov
  • 2,346
  • 3
  • 18
  • 34