我设计软件的中心问题总是
这是什么意思?
对于函数式编程,这个问题特别明确。对于我定义的每个数据类型,我都希望有一个精确而简单的数学模型。(例如,我的行为模型是时间函数,我的图像模型是2D空间函数。)类型上的每一个操作也都被赋予了该语义模型的含义。
这个规范过程是应用于数据类型的指称语义,它为
- 实施的正确性,
- 无实施细节的用户文档,
- 生成和证明属性,然后可用于自动测试,以及
- 评估和比较设计决策的优雅性和表现力。
有关示例(2D图像)、此过程的一些动机和讨论,请参阅Luke Palmer的帖子语义设计。另请参阅我关于类型类态射为指称设计提供了附加结构。
2008年春天,我开始开发一个功能强大的3D库,现场跳闸。我以前设计过功能性3D库,作为TBAG公司,活动VRML、和弗兰。出于上述所有原因,这次我想要一个基于语义的设计。一如既往,我想要一个
对于3D,我还希望该模型对GPU友好,即在(现代)GPU上执行良好,并允许使用其功能。
我没有想到或听到过一个我喜欢的模型,因此我在FieldTrip的工作中没有那种坚定的立场。去年二月,我想到了这样一个模型。从那时起,我就有了这篇博客文章。最近,我再次专注于基于GPU的功能3D渲染,然后是Sean McDirmid提出了类似的问题,这让我再次思考。
几何图形
3D图形涉及多种概念。让我们从3D几何开始,使用表面(而不是固体)模型。
3D(曲面)几何图形的示例包括
- 实体长方体、球体或圆环体的边界(表面),
- 实心三角形、矩形或圆形,
- 几何图形集合,以及
- 几何的空间变换。
第一个模型:几何图元集
一个几何模型是一组几何图元。在这个模型中,联盟
表示集合并集,空间变换表示变换集合中所有图元中的所有3D点。基本体包含无穷多(甚至不可数)点,因此需要进行大量变换。幸运的是,我们谈论的是什么(语义),而不是如何(实现)。
什么是几何基本体?
我们可以说它是一个三角形,由三个坐标指定。毕竟,计算机图形学将一切简化为一组三角形。哦,我们混淆了语义和实现。细分(Tessellation)近似值曲面由一组三角形组成,但在此过程中会丢失信息。我想要一个故事,包括这个近似过程,但要保持它与语义上理想的曲面有明显区别。然后,用户可以使用理想的、简单的语义,并依靠实现来执行智能的、动态的、与视图相关的细分,以适应可用的硬件资源。
几何图元的另一个模型是从二维空间到三维空间的函数,即曲面的“参数化”表示。除了函数之外,我们可能还需要一些方法来描述定义曲面的2D子集,以便修剪曲面。简单的形式化是
类型Surf=R2->可能是R3
哪里
类型R—实数类型R2=(R,R)R3型=(R、R、R)
对于着色,我们还需要法线,可能还需要切线和双切线,我们可以通过包含导数来获得这些特性以及更多特性,无论是一阶导数还是所有导数。查看我的衍生品帖子和纸张美丽的差异化。
除了位置和导数之外,基本体上的每个点还具有材质属性,这些属性决定了光在该点处如何被曲面反射和透射。
类型Surf=R2->可能(R2:>R3,材质)
哪里a:>b
包含类型为的函数的某一点的所有导数(包括零)a->b
。请参见高维、高阶导数,函数。我们也许还可以包括材料性质的衍生物:
类型Surf=R2:~>可能(R3,材质)
哪里甲:~>乙
是无穷可微函数的类型。
组合几何图形值
这个联盟
函数提供了一种组合两个几何体值的方法。另一个是位置和材质属性的变形(插值)。变形的语义是什么?
两人之间的变形曲面更容易定义。曲面是一个函数,所以我们可以插值指向(point-wise):给定曲面对
和秒
,对于每个点第页
在参数空间中,在(a)之间插值对
在第页
和(b)秒
在第页
,这就是提升A2
(关于功能)会建议。
这个定义有效如果我们有一种方法可以在也许 吧
值。如果我们使用提升A2
再一次,现在开始也许 吧
值,然后只是
/没有什么
(和没有什么
/只是
)案例将产生没有什么
。这种语义是可取的吗?例如,考虑一个中间有孔的方形平面。一个正方形有一个小洞,另一个有一个大洞。如果孔的大小对应于映射到的参数空间部分的大小没有什么
则点式插值将始终生成较大的孔,而不是在孔大小之间进行插值。另一方面,有孔的两个表面可能只是
在完全相同的一组参数上,函数确定只是
空间被拉伸。
描述这种变形笨拙的一种方法是,这两个函数(曲面)可能具有不同的域。这种解释来自于观察a->也许b
作为对来自子集属于一
(即a部分上的函数一
).
即使我们有一种令人满意的方法来组合曲面(点式),我们如何将其扩展到组合可以包含任意数量曲面的完整几何体值?一个想法是将几何图形建模为结构化的表面的集合,例如列表。然后我们可以将这些集合元素组合在一起。同样,我们必须处理集合不匹配的可能性。
曲面元组
让我们简单地回到一个更简单的曲面模型:
类型Surf=R2->R3
我们可以将此类曲面的集合表示为结构化集合,例如列表:
type Geometry=[冲浪]
但是,该类型不会捕获曲面的数量,从而导致在逐点组合几何体值时出现不匹配。
或者,我们可以通过元组(可能是嵌套的)在类型中显式显示曲面的数量。例如,两个曲面的类型(冲浪,冲浪)
。
该模型中的插值变得非常简单。通用插值器适用于向量空间:
lerp::VectorSpace v=>v->v->标量v->vlerp a b t=a^+^t*^(b^-^a)
或在仿射空间上:
alerp::(AffineSpace p,VectorSpace(Diff p))=>p->p->标量(Diff p)->palerp p p’s=p.+^s*^(p'.-.p)
这两个定义都在向量空间包裹。该套餐还包括矢量空间
和仿射空间
函数和元组的实例。这些实例以及实值的实例足以使(可能嵌套的)曲面元组成为向量空间和仿射空间。
从产品到总额
函数对允许一些有用的同构。用产品替换产品:
(a→b)×(a→c)≅a→(b×c)
使用这个乘积/乘积同构,我们可以用来自R(右)2到的元组R(右)三。
在函数的上下文中,还有一个方便的同构,它将乘积与和联系起来:
(b→a)×(c→a)≅(b+c)→a
如果我们将曲面的概念推广到包含比R(右)2。
事实上,这两个同构是一般的和有用的Haskell函数的未组合形式(&&&)
和(|||)
,在箭头上定义:
(&&&)::箭头(~>)=>(a~>b)->(a~>c)->(a ~>(b,c))(|||)::ArrowChoice(~>)=>(a~>c)->(b>c)->(b~>c之一)
仅限于功能箭头,(|||)==其中之一
。
第二种同构,未结婚(|||)
还有另一个好处。放宽域类型以允许求和也为其他域变量打开了道路。例如,我们可以有三角域的类型、带孔的形状以及其他类型的有界和无界参数空间。所有这些域都是二维的,尽管它们可能是由几个补丁造成的。
我们的几何图形
类型现在变为参数化:
类型几何形状a=a->(R3,材料)
第一个同构,未修剪(&&&)
,在几何设置中也很有用。考虑范围类型的每个组件(此处R3级
和材料
)作为曲面“属性”。然后(&&&)
合并两个兼容的几何体,包括每个几何体的属性。属性可以包括位置(和导数)和与着色相关的材质,以及温度、弹性、粘性等非视觉属性。
考虑到这种灵活性,几何图形
获取第二个类型参数,即范围类型。现在什么都没有了几何图形
类型但通用功能:
类型Geometry=(->)
回想一下,我们正在寻找语义学用于3D几何图形。这个类型对于几何图形
可能是抽象的(->)
作为其语义模型。在这种情况下,模型表明几何图形
具有所有相同类型的类实例(->)
(及其全部或部分应用)具有,包括单体
,Functor(仿真器)
,适用
,莫纳德
、和箭头
。这些实例的语义将由相应的实例给出(->)
。(请参阅上的帖子类型类态射和报纸具有类型类形态的指称设计.)
或者放弃几何图形
并直接使用函数。
域
我很满意几何函数的简单性。函数适合可编程GPU的灵活性,并提供简单、强大和熟悉的属性合并概念((&&&)
)和工会((|||)
/任何一个
).
我剩下的主要问题是:域是什么?
一个简单的域是一维区间,比如[-1,1]。
两个有用的领域构建块是总和和乘积。我在上面提到了和,关于几何并集((|||)
/任何一个
)产品将域组合为高维域。例如,两个1D间隔的乘积是一个2D间隔(轴对齐的填充矩形),这对于某些参数化曲面很方便。
其他域如何,例如三角形域或多了一个孔?还是多路分支曲面?还是无界?
一个想法是使用求和将简单的域缝合在一起。我们不必构建任何特定的空间形状或大小,因为“几何”函数本身可以生成形状和大小。例如,方形区域可以映射为三角形甚至圆形区域。无限域可以从无限多个有限域缝合在一起。或者它可以从单个有限域映射到。例如,函数x->x/abs(1-x)
映射[-1,1]到[-∞,∞]。
或者,我们可以将域表示为类型化谓词(特征函数)。例如,闭合区间[-1,1]将为x->abs x≤1
。更换防抱死制动系统
具有量级
(用于内积空间),将此公式推广到包含[-1,1](1D)、单位圆盘(2D)和单位球(3D)。
我喜欢谓词方法的简单通用性,而我喜欢纯类型方法如何支持插值和其他逐点操作(通过提升A2
等)。
细分(Tessellation)
我特意在连续空间上制定了图形语义,这使得它独立于解析,并且易于编写。(此公式是3D几何和2D矢量图形的典型公式。连续性的好处通常适用于图像和至动画/行为.)
图形硬件专门用于有限的三角形集合。对于渲染,曲面必须镶嵌的即近似为三角形集合。理想的细分选择取决于曲面和视图的特性,以及场景复杂性和可用的CPU和GPU资源。以理想的曲线形式表示几何体可以进行自动分析和选择细分。例如,由于三角形是线性的,三角形相对于其近似曲面的误差取决于非线性曲面位于三角形对应的域子集之上。使用区间分析和衍生产品,非线性可以作为二阶导数或一阶导数范围上的大小界限来测量。误差也可以根据结果图像而不是表面进行分析。
对于基于GPU的实现,可以在“几何着色器”或(我猜想)更通用的框架(如CUDA或OpenCL)中动态细分。
抽象
当指称模型等同于观测等价项时,它是“完全抽象的”。曲面的参数化模型并不是完全抽象的,因为重新参数化曲面会产生一个看起来与曲面相同的不同函数。(表面重成像改变了域和范围之间的关系,同时从几何角度覆盖了完全相同的表面。)独立于特定参数化的属性称为“几何”,我认为它对应于完全抽象(将这些属性视为语义函数)。
几何的完全抽象(几何)模型可能是什么?
我在设计软件时的中心问题总是什么意思?对于函数式编程,这个问题特别明确。对于我定义的每个数据类型,我希望。。。