Hacker News 中文摘要

RSS订阅

二维光线步进软阴影(2020) -- Ray Marching Soft Shadows in 2D (2020)

文章摘要

这篇文章介绍了作者使用距离场技术实现2D软阴影效果的图形项目。核心是通过计算每个像素到形状的距离生成距离场,然后沿着像素到光源的射线进行步进检测,判断像素是否处于阴影中。作者使用自己开发的库快速生成距离场,并分享了实现原理。

文章总结

二维光线步进软阴影技术解析

免责声明:本文演示使用了部分移动设备可能不支持的WebGL功能。

核心原理:距离场

这项技术基于距离场实现——一种记录每个像素与图形边缘距离的特殊图像。浅灰色表示靠近图形,深灰色表示远离图形。项目启动时,系统会在2D画布上绘制文字并生成对应的距离场,这里使用了作者开发的高效距离场生成库

光线步进算法

光照计算的核心思路是:对每个待着色像素,发射一条指向光源的射线: 1. 若射线与文字相交,则该像素处于阴影中 2. 传统逐像素检测效率低下 3. 光线步进的核心优势:利用距离场数据,每次安全推进当前点到最近图形的距离,避免漏检

光线步进示意图

软阴影实现三原则

  1. 近似相交原则:射线越接近图形,阴影越深(通过sceneDist值判断)
  2. 距离衰减原则:像素离近似相交点越远,阴影扩散越明显(通过sceneDist/rayProgress比值控制)
  3. 光源衰减原则:光照强度随距离平方衰减

glsl // 核心算法代码示例 vec2 rayOrigin = ...; float rayProgress = 0.; float lightContribution = 1.; for (int i = 0; i < 64; i++) { float sceneDist = getDistance(rayOrigin + rayProgress * rayDirection); lightContribution = min(lightContribution, sceneDist / rayProgress); rayProgress += sceneDist; }

技术优化与挑战

  • 带状伪影问题:因步进采样不足导致,采用Inigo Quilez提出的改进方案
  • 随机扰动技术:通过sceneDist * randomJitter增加采样随机性,缓解带状伪影(但会产生噪点)
  • 性能平衡:使用固定步数循环替代while循环,避免极端情况下的性能问题

效果展示

最终实现的软阴影具有渐变效果,虽然不符合物理真实,但视觉效果更柔和美观。作者表示该技术仍在优化中,欢迎通过Twitter提供建议。

致谢:感谢Jessica Liu等同事对本文的审阅,同时欢迎加入Figma团队共事。

评论总结

这篇评论主要围绕一个技术博客中的实时演示效果展开讨论,主要观点如下:

  1. 对技术演示效果的赞赏
  • "It's always impressive to see a live demo...especially one that runs so fast and slick on mobile"(评论1)
  • "this looks great"(评论7)
  1. 相关技术联想与比较
  • 提到类似技术"radiance cascades"(评论2)
  • 联想到PICO-8上的阴影投射实现(评论3)
  1. 技术实现细节讨论
  • 认为计算方法很聪明:"a very clever series of calculations"(评论5)
  • 建议考虑SDF梯度:"I wonder if it would help if you looked at gradient of the SDF"(评论6)
  1. 交互提示与功能建议
  • 指出首图是交互式演示:"Note that the first image is an interactive demo"(评论4)
  • 建议增加动态光源:"make the light source a bouncing ball"(评论9)
  1. 性能对比反思
  • 对比企业仪表盘性能:"my company's 'enterprise dashboard' struggles to render 50 divs"(评论8)
  1. 演示链接询问
  • 询问演示链接:"is there no demo link?"(评论7)