mpr-gui项目是论文《Massively Parallel Rendering of Complex Closed-Form Implicit Surfaces》的配套项目,由MATTHEW J. KEETER发布,采用了libfive作为模型构建的计算内核,主要用于充分利用现代GPU的高度并行性来绘制复杂封闭式隐式曲面。
这篇文章介绍了mpr-gui项目的文本编辑器的内容格式,以及可以直接使用的基本模型、CSG操作、模型变换的API,最后结合上述文本内容规则和API,编写文本脚本来创建一个“天使熊”测试模型。
你可以理解为这一过程是使用标准库中的API,编写合适的scheme脚本来作为mpr-gui项目的文本编辑器输入,从而得到渲染结果。渲染的过程由mpr-gui项目底层提供计算。
mpr-gui项目的介绍及部署详见:https://blog.csdn.net/qq_38327353/article/details/108148836
- 文本编辑器是指mpr-gui项目的指令输入框——Text editor面板,它可以作为即时编译器使用,数值计算结果会在面板的下方输出,几何图形会在背景处实时展示,如下图所示:
Text editor中的指令脚本是使用scheme语言编写的,所以需要我们学习Scheme语言的语法规范,例如:定义函数、理解S表达式、理解let表达式等。推荐网站:https://www.kancloud.cn/kancloud/yast-cn/64461
- 定义函数:(define (函数名 变量名) (函数体))或(define 函数名(函数体))
- S表达式:S指Symbolic,S表达式即符号表达式,是一种使用前缀表示法的代码规范,如计算7+1,对应:(+ 7 1)
- let表达式:用于定义局部变量,作用域为let两侧的圆括号内,例如:
(let ((i 1) (j 2))
(+ i j))
;运行输出:
;Value: 3
- 向量操作(列表类似):
;向量(vector),其元素索引从0开始,到第n-1结束,与数组类似
;表示方法
#(1 2 3 4 5)
;正常定义
(define v (vector 1 2 3 4 5))
>v
#(1 2 3 4 5)
;直接定义
(define v #(1 2 3 4 5))
>v
#(1 2 3 4 5)
;求第n个元素的值
>(vector-ref v 0)
1
;求vector的长度
>(vector-length v)
5
;设定vector第n个元素的值
>(vector-set! v 2 "abc")
>v
(1 2 "abc" 4 5)
;创建向量表
>(define x (make-vector 5 6))
>x
#(6 6 6 6 6)
- do循环:
;(do ((变量1 初值 (变换规则)) (变量2 初值 (变换规则))
; ((变量1终止条件) (返回值,可以省略))
; (循环体))
(define a o)
(do ((i 1 (+ 1 i)))
((> i 4))
(set! a (+ a 1)))
a
;value a=4
- 模型创建及操作:
;为注释符号,#表示可以省略的参变量
- 可以直接调用的模型:
文字(2D/3D)
;简单写法
(text "Hello,\nWorld!")
;组合写法
(sequence
(text "Hello,\nWorld!")
(move [-1.6 0.1])
(scale-xyz [0.5 0.5 1])
(extrude-z -0.5 0.5)
(intersection
(scale-z (sphere 2) 0.5))
(rotate-y -0.3)
(rotate-x -0.1)
)
2D:圆、圆环、多边形、矩形、圆角矩形、三角形,etc.
;圆
(circle r #center)
;圆环
(ring ro外径 ri内径)
;多边形
;-r 中心到各个顶点的距离
;-n 边数
(polygon r n #center[0 0])
;矩形
(rectangle [x0 y0] [x1 y1])
;圆角矩形
(rounded-rectangle [x0 y0] [x1 y1] r)
;三角形
(triangle point1 point2 point3)
3D:盒子、球体、圆柱、圆锥、金字塔、甜甜圈、极小曲面、圆角长方体,etc.
;盒子
(box/cubu [x0 y0 z0] [x1 y1 z1])
(box-centered size大小 #位置)
(box-exact-centered size_x size_y size_z #位置)
;球
(sphere r #位置)
;圆柱 解释一下:cylinder是cylinder-z的缩写
(cylinder/-z r h #位置)
;圆锥
(cone-any/-z r ang倾斜角 #位置)
(cone/-z r height #位置)
;金字塔(四棱锥) 解释一下:a、b为vec2,构成矩形
(pyramid/-z a b zmin height)
;甜甜圈
(tortus/-z R r #位置)
;极小曲面 Gyroid surface 解释一下:不太好描述是一个什么样子的几何形状,可以按照例子感受一下
(gyroid [x-period y-period z-period] thickness)
;例如:
(gyroid [1 1 1] 1)
;圆角盒子(长方体)
(rounded-box/cube [x0 y0 z0] [x1 y1 z1] r)
高阶形状:阵列(沿x方向、沿xy方向、沿xyz方向)、二维图形挤出三维实体、绕轴阵列,etc.
;阵列:
;沿x方向
(array-x shape i个数 dx间距)
;沿x、y方向
(array-y shape i j [dx dy])
;沿x、y、z方向
(array-xyz shape i j k [dx dy dz])
;挤出:
;沿z轴
(extrude/-z shape_2d zmin zmax)
;绕轴阵列
(array-polar shape_2dor3d n数量 #绕转中心[x0 y0])
用距离场函数定义模型:
;绘制球体:x^2 + y^2 + z^2 = 1
(lambda-shape (x y z)
(- (sqrt (+ (* x x) (* y y) (* z z))) 1))
- CSG操作
并交差补集
;并集
(union shape1 shape2)
;交集
(intersection shape1 shape2)
;差集
(difference shape1 shape2)
;补集
(inverse shape)
扩张/收缩
size > 0 扩张;size < 0 收缩;
(offset shape size)
造壳 o为负值时有效
(shell shape o)
平滑融合
3Dshape1和3Dshape2融合成新物体:
;指数融合
(blend-expt 3Dshape1 3Dshape2 m)
;线性融合 m=0→3Dshape1 m=1→3Dshape2
(morph 3Dshape1 3Dshape2 m)
2Dshape1和2Dshape2之间平滑差值构成封闭实体:
(loft 2Dshape1 2Dshape2 zmin zmax)
(loft-between 2Dshape1 2Dshape2 [x0 y0 zmin] [x1 y1 zmax])
;x0、y0和x1、y1决定了映射关系
;zmin、zmax决定了两个二维图形的初始位置
- 模型变换
移动、沿轴向移动:
;移动
(move shape delta)
;沿轴向移动
(reflect-x/y/z shape distance)
等比缩放、沿轴向缩放:
;沿某轴缩放
(scale-x/y/z shpe size #沿x的偏移量x0=0)
;缩放
(scale-xyz shape [size_x size_y size_z] #位置[x0 y0 z0])
绕轴旋转:
(rotate-x/y/z shape radians #偏移量[x y])
- 按照scheme的语法和标准库中的基本模型和操作API,创建天使熊头像模型
包含的操作有:绘制心形隐式曲面,挤出多边形构成三棱柱,绘制球体、甜甜圈、圆锥,对上述模型进行移动、旋转变换,最后对各部分进行求并集或差集,形成模型。
下述渲染目标从左到右分别是:Heightmap、Normals、SSAO、Shaded:
构建熊天使头像的scheme脚本内容:
(define heart3d
(lambda-shape(x y z)
(+ (expt (+ (expt x 2) (/ (* 9 y y) 4) (expt z 2) -1) 3)
(* -1 (expt x 2) (expt z 3))
(/ (* -9 (expt y 2) (expt z 3)) 80))))
;heart3d
(define face (sphere 1.1))
(define eyel (move (sphere 0.3) [0.55 0.9 0.3]))
(define eyer (move (sphere 0.3) [-0.55 0.9 0.3]))
(define halo (torus 0.8 0.2 [0 0 1.6]))
(define nose (rotate-x (cone 0.1 0.2 [0 0 1.1]) 10.93))
(define earl (move (rotate-x (torus 0.14 0.13) 2.9) [0.9 0.4 0.9]))
(define earr (move (rotate-x (torus 0.15 0.14) 2.9) [-0.9 0.4 0.9]))
(define mouse1 (move (sphere 0.6) [0 0.6 -0.3]))
(define mouse2 (move (rotate-x (extrude (polygon 0.3 3) 0 0.5) 1.57) [0 1.45 -0.5]))
(define head (difference (union halo heart3d face eyel eyer nose mouse1) earl earr mouse2))
head
;(array-xyz head 4 3 4 [3 3 3])