回顾上一篇 ShaderToy入门教程(2) - 光照和相机
这篇涵盖以下黑体所示内容
- 符号距离函数
- Ray-marching算法
- 曲面法线和光照
- 相机变换
- 构造实体形状(CSG)
- 模型变换
- 平移和旋转
- 比例缩放
- 非均匀缩放
- 结论
- 参考
构造实体形状(CSG)
构造实体形状(简称CSG)是一种通过布尔运算从简单几何形状创建复杂几何形状的方法。 WikiPedia的这张图表显示了该技术的可能性:
CSG建立在3个原始操作上:交集,合并和差异
事实证明,当组合表示为SDF的两个表面时,这些操作都是简单的。
float intersectSDF(float distA, float distB) {
return max(distA, distB);
}
float unionSDF(float distA, float distB) {
return min(distA, distB);
}
float differenceSDF(float distA, float distB) {
return max(distA, -distB);
}
如果您设置这样的场景:
float sceneSDF(vec3 samplePoint) {
float sphereDist = sphereSDF(samplePoint / 1.2) * 1.2;
float cubeDist = cubeSDF(samplePoint) * 1.2;
return intersectSDF(cubeDist, sphereDist);
}
然后你得到这样的东西(参见下面关于缩放的部分,看看1.2的除法和乘法的缘由)。
代码在这里
在同一个Shadertoy中,如果编辑代码,也可以使用联合和差异操作。
考虑由这些二进制操作产生的SDF来尝试建立它们工作原理的直觉是很有趣的。
记住SDF为负的区域代表在面的内部,上面图中相交,sceneSDF只有在cube§和sphere§都是负的时候才是负的。就是说一个点必须都在立方体和球体内部,才会在场景面的内部,这符合CSG对交集的定义。
同样的逻辑也适合于并集,如果一点只要在两者之一的SDF为负,场景SDF则为负,那么就在面的内部
差异操作对我来说是最棘手的
SDF为负值意味着什么?
如果你再想一想SDF的负面和正面区域是什么意思,你可以看到SDF的负值是表面内外的反转。 表面内的部分被认为现在都被视为外部,反之亦然。
这意味着您可以将差异视为第一个SDF和第二个SDF的反转的交集。 因此,当第一个SDF为负且第二个SDF为正时,得到的场景SDF仅为负。
切换回几何术语,这意味着当且仅当我们在第一个表面内和第二个表面之外时,我们才在场景表面内 - 正好是CSG差异的定义!
模型变换
能够移动相机给我们一些灵活性,但能够独立地移动场景的各个部分肯定会提供更多灵活性。 让我们来探索一下如何做到这一点。
SDF的旋转和平移
建模为SDF的曲面的变换或旋转