haze icon indicating copy to clipboard operation
haze copied to clipboard

Feature Request: Liquid Glass

Open kihaki opened this issue 7 months ago • 4 comments

I have already created a prototype shader for this, which can be dropped into ShaderToy:

#define PI 3.14159265

// ---------- tweakables ---------
const float  LENS_SCALE = 0.36;
const float  IOR        = 0.50;
const vec3   TINT       = vec3(1.05,1.10,1.25);
const float  EDGE_FADE  = 0.015;
const float  HIGHLIGHT  = 0.45;
const float  NZ         = 1.5;
const float  PWR        = 8.0;
// ---------------------------------

float superF(vec2 p, vec2 a){
    vec2 n = abs(p)/a;
    return pow(n.x, PWR) + pow(n.y, PWR) - 1.0;
}
vec2 superGrad(vec2 p, vec2 a){
    vec2 s = sign(p), n = abs(p)/a;
    return PWR * pow(n, vec2(PWR-1.0)) * s / a;
}

vec2 mousePos(){ return (iMouse.z>0.) ? iMouse.xy : 0.5*iResolution.xy; }

vec3 blur9(vec2 uv){
    vec2 r=1.0/iResolution.xy; vec3 c=texture(iChannel0,uv).rgb*4.0;
    c+=texture(iChannel0,uv+vec2( r.x,0)).rgb;  c+=texture(iChannel0,uv+vec2(-r.x,0)).rgb;
    c+=texture(iChannel0,uv+vec2(0, r.y)).rgb;  c+=texture(iChannel0,uv+vec2(0,-r.y)).rgb;
    c+=texture(iChannel0,uv+vec2( r.xy)).rgb;   c+=texture(iChannel0,uv+vec2(-r.xy)).rgb;
    c+=texture(iChannel0,uv+vec2( r.x,-r.y)).rgb;c+=texture(iChannel0,uv+vec2(-r.x, r.y)).rgb;
    return c/12.0;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2  uv   = fragCoord/iResolution.xy;
    vec2  res  = iResolution.xy;
    vec2  cent = mousePos()/res;
    float rad  = LENS_SCALE*min(res.x,res.y);
    vec2  dir  = fragCoord - cent*res;

    vec2 halfSize = vec2(1.4*rad, 0.6*rad);

    float f     = superF(dir, halfSize);
    vec2  g2    = superGrad(dir, halfSize);
    float sd    = f / length(g2);
    float inside= smoothstep( EDGE_FADE*rad, 0.0, sd );

    vec3 base = texture(iChannel0, uv).rgb;

    if(inside>0.0){
        vec3 normal = normalize(vec3(g2.x, -g2.y, NZ));

        vec3  I      = vec3(0,0,-1);
        vec3  R      = refract(I, normal, 5.0/IOR);
        vec2  refrUV = uv + R.xy*(rad*0.003);

        vec3  scene   = blur9(clamp(refrUV,0.0,1.0));
        float fresnel = pow(1.0 + dot(I,normal), 12.0);

        vec3  glass   = scene*TINT + fresnel*HIGHLIGHT;
        float alpha   = inside;
        fragColor     = vec4(mix(base, glass, alpha), 1.0);
    } else {
        fragColor = vec4(base,1.0);
    }
}

kihaki avatar Jun 10 '25 07:06 kihaki

Nice work!

I think it's too early to start introducing this into the library, but I will have a think about how you could provide your own 'effect' shader into Haze.

On Android, it would only work on API level 33+ but that's fine.

chrisbanes avatar Jun 10 '25 07:06 chrisbanes

Custom effect shaders in Haze would unlock amazing use cases! Sounds great!

kihaki avatar Jun 10 '25 10:06 kihaki

when I see apple Liquid glass, I also thought it could be added in Haze

akardas16 avatar Jun 10 '25 14:06 akardas16

Actually, there's a library to create Liquid Glass. And we don't need to recreate any wheels when there's a good solution.

6xingyv avatar Aug 07 '25 15:08 6xingyv