液态玻璃

前述

液体玻璃效果,模仿苹果的液体玻璃效果。

实现思路

主要特点

  • 四边圆角
  • 透明-高斯模糊
  • 反射-最边缘有高光,而且可以反射出按钮周围的环境
  • 折射-中心到弯角的部分有弯曲的折射效果
  • 液态融合-距离靠近的按钮会融合在一起,形成液态的效果。

这里的折射有两种方式

  • 一是算法线,根据折射公式来计算,要算两次,首先是空气到玻璃的折射,然后是玻璃到空气的折射。再结合玻璃不同位置的厚度,玻璃地面到屏幕像素平面的距离即可。
  • 二是简单扭曲一下UV坐标,根据sdf,越靠近边缘扭曲程度越大,直接采样屏幕像素。

前者物理上正确,可以与光线追踪的结果对比,像素级精确,后者简单粗暴。
但后者性能更好,而且效果更可控,不会出现发生全反射导致的黑色区域。
# 实现步骤

圆角没啥好说的,用SDF就行,而且后续的液体效果也需要用sdf实现。

然后生成三种遮罩,分别对应三种效果。

接着是要计算法线,还是用sdf当高度,边缘想象成四分之一球体,得出法线。

最外圈的高光,如果要简单一点,就边缘给个亮色就行。复杂的话就就法线采样个cube贴图。

然后是高斯模糊,这也很简单,多采样几次完事。

折射部分也是用法线来计算折射角度,厚度也从SDF中获取,采样屏幕像素即可。

折射要计算两次,首先是空气到玻璃的折射,然后是玻璃到空气的折射。

第一次的折射长度就用玻璃的厚度,第二次就把参数暴露出来方便调整。
两次折射加上原本的位置,转成屏幕空间去模糊采样就行了。

view dir 是朝向相机的!!!!

生成法线

首先box的SDF

boxSDF

然后是圆角的SDF
cornerSDF

然后从SDF生成高度
height

然后是法线,从高度生成法线,再将法线、高度和SDF结合,得到光线的出射位置
pos

这里要考虑两次折射,首先是空气到玻璃的折射,然后是玻璃到空气的折射。
两次折射

然后是一个非常粗暴的高斯模糊,采样屏幕像素。
模糊

float2 UV = ScreenPosition;
float2 texelSize = 1.0 / SceneSize;



float weightSum = 0.0;
float3 result = float3(0, 0, 0);

for (int x = -kernelRadius; x <= kernelRadius; x++) {
    for (int y = -kernelRadius; y <= kernelRadius; y++) {

        float2 offset = float2(x, y) * texelSize;

        // 内联高斯函数:weight = e^(-(x^2 + y^2)/(2*sigma^2))
        float dist2 = x * x + y * y;
        float weight = exp(-dist2 / (2.0 * sigma * sigma));

        float3 sample = SHADERGRAPH_SAMPLE_SCENE_COLOR(UV + offset).xyz;

        result += sample * weight;
        weightSum += weight;
    }
}

Out = result / weightSum;

结果
SDF结果

模型

换一个思路,直接建模,从模型取法线和高度,也可以实现。

首先是折射
折射

然后是反射
反射

再加上边缘高光
高光

完工
模型


液态玻璃
https://www.kuanmi.top/2025/06/11/liquidGlass/
作者
KuanMi
发布于
2025年6月11日
许可协议