openGL之API学习(一三四)smooth minimum smin

本文探讨了平滑最小值函数SMin的工作原理及其优势。相较于传统的Min函数和Mix函数,SMin能在参数相近时提供更平滑的过渡效果,尤其在图形渲染中,能有效避免尖锐过度,实现更自然的视觉效果。

 

https://www.iquilezles.org/www/articles/smin/smin.htm

 

为什么需要这个函数存在,要么用min取最小值,要么用mix取混合中间值。通过这么复杂的算法取值,意义不大。

mix只能在中间取值,而smin可以取比最小值还小的值,从而达到平滑的目的。如下图所示,在两条线的交点附近,采用smin后,有一个弧度过度,避免过度过于尖锐:

如果a,b相差较大,则smin塌缩成min,如果a,b相差较小,就体现出smin的优势了。这是mix比不了的。

 

### Shadertoy 中 `smin` 函数的用法 `smin` 是一种平滑最小值函数,在 GLSL 和 Shadertoy 中广泛用于生成更柔和、连续的效果。它通过引入一个额外参数(通常称为半径或光滑度),使得两个输入之间的过渡更加自然。 #### 平滑最小值定义 在数学上,`smin(a, b, k)` 可以被描述为计算两个值 \(a\) 和 \(b\) 的加权平均数,其中权重由它们的距离决定[^1]。具体实现可以采用以下形式: ```glsl float smin(float a, float b, float k) { float h = max(k - abs(a - b), 0.0) / k; return min(a, b) - h * h * k * 0.25; } ``` 此版本中的第三个参数 \(k\) 控制着平滑程度;较大的 \(k\) 值会产生更强的平滑效果[^2]。 #### 使用场景分析 当绘制多个形状并希望其边缘融合时,`smin` 尤其有用。例如,考虑两圆相交的情况,如果直接取两者距离场的较小者,则会形成尖锐边界。而应用 `smin` 后,该区域变得渐变且视觉友好[^3]。 以下是基于上述逻辑的一个简单例子: ```glsl void mainImage(out vec4 fragColor, in vec2 fragCoord){ vec2 uv = fragCoord/iResolution.xy; // 定义两个圆形的距离字段 float d1 = length(uv - vec2(0.3, 0.5)) - 0.2; float d2 = length(uv - vec2(0.7, 0.5)) - 0.2; // 应用 smin 进行混合处理 float dist = smin(d1, d2, 0.1); // 渲染最终颜色 vec3 color = mix(vec3(1., .8,.9),vec3(.1,.3,.6),(dist+0.2)*5.); fragColor = vec4(color,1); } // 调用了前面提到过的自定义 smin 方法 ``` 以上片段展示了如何利用 `smin` 来创建具有柔化边界的双圈图案。 #### 参数调整的影响 改变 `smin` 的第三项参数会对输出图形造成显著影响。较低数值会使对象间联系紧密但界限模糊不清;反之则趋向于清晰分离状态却保留一定缓冲区。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值