![27e57f5aaf8219d3f6fd617a7fa099bb.png](https://i-blog.csdnimg.cn/blog_migrate/bcdec5fc655c6069e6810e5a05130564.jpeg)
每天翻译一篇教程,这就是我写给houdini的情书-<Entagma系列>Houdini 2016教程
【注】同名公众号“致houdini的情书”
![70973a37fb024758d22f1572cf56e36b.png](https://i-blog.csdnimg.cn/blog_migrate/faf4df2c43218d1fcdf7c20b68e29e6e.jpeg)
即使深陷污泥,即使被别人踩在脚底,也要努力活下去,因为泥路上有你啊,肉妮,你这个泥菩萨。
面对泥泞,可以低头看地,盯着脚下困难的泥沼,也可以抬头看天,那漫天的星辰,你有你的自由选择。但这世上若没有泥泞,种籽怎会发芽?树木又怎会生根?若没有污泥,莲花何以为生,又谈何出污泥而不染?
人生一世,草木一秋,瞑目皆归泥。我们早晚都会化成泥的。
这一节我们看一下:
殉泥派如何把比丘泥锁在一个自定义的mandel函数里。。
![2354f64ecb2db54324526d0af53973d0.gif](https://i-blog.csdnimg.cn/blog_migrate/0da831abf983fb051d7d62c32717dfea.gif)
![269f1bafeaf571e1fc5ab0e4bb2cb7a9.png](https://i-blog.csdnimg.cn/blog_migrate/d37dfff065370b0e6c1d7176b8e16862.jpeg)
▉今天是41岁第353天周日
这是写给houdini的 第015封“情书”
![1faf68cb5a1d9908604036a50bddc9f8.png](https://i-blog.csdnimg.cn/blog_migrate/b3e7f7c4a53b4fe67dd54439ecc3f6a7.jpeg)
本节需要注意的知识点:A)自定义二维mandel函数-部分:
A1)二维公式-函数定义部分:
1)mandel分型二维化公式
xnew = x*x –y*y+x0;
ynew = 2*x*y+y0;
2)如何定义mandel函数
function+数据类型+函数名(3个浮点+1个整数)
3)这个函数要实现的作用
通过给定的“坐标系” ,在一组公式趋于无穷大时,所需迭代的次数。
4)如何判断无穷大时条件
if(xnew*xnew+ynew*ynew> 8 ){
//如果成立,返回一个给定的值i,在本例应该返回整数;
return(i); //返回i
}
5)判断没超过最大值时的返回
x= xnew;
y= ynew;
}
return(imax); //这个循环返回imax
A2)二维公式-执行函数部分:
6)如何用条件语句执行自定义函数
1) 用if条件语句,(<最大迭代数值)满足条件的点,用set函数设置为:白色,不满足条件的点,设置黑色
//---- Main----
Mandel (@P.x,@P.y,@P.z,6) ;
// 条件判断,以此为依据上色
if( Mandel (@P.x, @P.y, @P.z, 6)<6) { //使用if语句如果<6,因为这是最大的“迭代数”这个函数不需要无限延伸
v@Cd = set(1,1,1);//白色;
}
else{
v@Cd = set(0,0,0)//黑色
7)另一种可调参数变量控制迭代值
//---- Main---
int maxiter =chi(“Maxiter”); //变量改成引用参数
if( Mandel (@P.x, @P.y, @P.z, maxiter)<maxiter) {
v@Cd = set(1,1,1);
}
else{
v@Cd = set(0,0,0);
}
B)自定义三维mandel函数-部分
01)定义函数
//增加了z轴;4变量(n,r,theta,phi)
//---- functions ----
function int Mandel (float x0, y0, z0; int imax)
float x, y, z, xnew, ynew, znew, n=ch("n"),r,theta,phi;
int i;
x=x0;
y=y0;
z=z0;
for(i=0; i < imax; i++ ){ .
//-------------三维公式部分---------------
//特别注意:公式的x,y,z要看清楚,稍微写错效果就不对
r=sqrt(x*x + y*y +z*z);
theta = atan2(sqrt(x*z+y*y),z); // 注意是x*z
phi = atan2(y,x);
xnew = pow(r,n)*sin(theta*n)*cos(phi*n)+x0;
ynew = pow(r,n)*sin(theta*n)*sin(phi*n)+y0;
znew = pow(r,n) *cos(phi*n)+z0;
02)执行函数
//-------------三维公式执行---------------
if(xnew*xnew+ynew*ynew+znew*znew> 8 ){
return(i);
}
x= xnew;
y= ynew;
z= znew;
}
return(imax);
}
C)渲染sdf体积-部分
03)如何不转成polygon而渲染sdf体积
// 给渲染的物体面板增加两个参数接口:volume Isosurface和Volume Density
04)如何提sdf体积解算速度
//就是实时框住volume,只计算范围内的volume,从而提高解算速度。
1) 用新的volume:减少单位内的体素数量=40.
2) 执行mandel函数。
3) 用vomumebound节点限制激活范围内的volume,节省计算量。
4) 用peak节点扩展一下volume体积。
5) 连接上之前的高单位体素=400的volume,把它的尺寸size降为0.
接下来理论部分
▉公式:曼德布罗特集合
![467481cc880fb8663cbef697db896530.png](https://i-blog.csdnimg.cn/blog_migrate/38cb9c2dc3dcdcfead071caf5ad60572.jpeg)
曼德布罗特集合
函数的两个功能
a)对grid上每个点进行循环。
b)如果计算值∞(无穷大)=黑色;反之=白色。
![f2616464f208fbf816f6105fd9fe0bbd.png](https://i-blog.csdnimg.cn/blog_migrate/7bb6d624eb46808f1ed0f139fbe98890.jpeg)
![9fb5965c90601eb03b7f8199de5d55f1.png](https://i-blog.csdnimg.cn/blog_migrate/0342312d3fd6c70da383fb919612aa31.jpeg)
这是作者推荐的专门讲解如何编程实现“曼德布罗特集合”和背后数学原理的一个youtube主:https://www.youtube.com/watch?v=pLtViSqkPvQ
接下来
开始正式制作
使用软件houdini16.5
1) grid
X y轴;3*3;200*200
A1)函数定义部分:自定义“曼德布罗特函数”返回一个整数
2) pointwrangle1
问题1:如何自定义函数
a)我们定义了函数:
//---- functions ----
function int Mandel (float x0, y0, z0; int imax) {
// "Function"意思是“定义一个函数”;
// “int Mandel”意思是“数据类型+函数名”返回整数
// "float x0, y0, z0,int imax"意思是“设置参数对象"
float x, y, z, xnew, ynew, znew;
int i; //定义一些变量类型,
x=x0; //坐标变量初始化,
y=y0;
z=z0;
问题2
mandel函数的二维公式
b )循环函数计算mandel公式:
//imax这是定义函数时,可以调用的一个值;
for(i=0; i < imax; i++ ){
//首先执行“曼德布洛特几何函数”
xnew = x*x –y*y+x0;
ynew = 2*x*y+y0;
c)条件判断:如果无穷大( 使用一种偷懒的方法,直接使用一个值比如8 ) 返回当前 i 数值
if(xnew*xnew+ynew*ynew > 8 ){
return(i); //返回i
}
c-1)否则 返回最大迭代数imax
x= xnew;
y= ynew;
}
return(imax); //这个循环返回imax
}
A2)主程序部分,执行自定义函数
//---- Main----
Mandel (@P.x,@P.y,@P.z,6) ;
a)任务:调用函数:
if( Mandel (@P.x, @P.y, @P.z, 6)<6) {
//使用if语句如果<6,因为这是最大的“迭代数” 这个函数不需要无限延伸
v@Cd = set(1,1,1); // <6的点给它白色;
}
else{
v@Cd = set(0,0,0); // >6的点给它黑色;
}
![759bee8d5d559927b8212f592e350edc.png](https://i-blog.csdnimg.cn/blog_migrate/63c2ef25e17624a68072aade9b4951ce.jpeg)
提高grid网格数
1)grid
Xy轴;5*5;400*400 ///增加grid分辨率
设置maxiter为可调参数
2)pointwrangle
int maxiter =chi(“Maxiter”); //变量改成引用参数
if( Mandel (@P.x, @P.y, @P.z, maxiter)<maxiter) {
v@Cd = set(1,1,1);
}
else{
v@Cd = set(0,0,0);
}
![4b2536f119361235f7063a11511f1cf0.png](https://i-blog.csdnimg.cn/blog_migrate/afb753c2cef03ac74ce727d228ba1255.jpeg)
设置引用参数:Maxiter=8
B)“洛德布罗特集合”函数的三维化
问题3:如何使用mandel函数的三维公式
3) pointwrangle2
//---- functions ----
function int Mandel (float x0, y0, z0; int imax)
float x, y, z, xnew, ynew, znew, n=ch("n"),r,theta,phi;
int i;
x=x0;
y=y0;
z=z0;
for(i=0; i < imax; i++ ){ .
//-------------三维公式部分---------------
r=sqrt(x*x + y*y +z*z);
theta = atan2(sqrt(x*z+y*y),z); // 注意是x*z
phi = atan2(y,x);
xnew = pow(r,n)*sin(theta*n)*cos(phi*n)+x0;
ynew = pow(r,n)*sin(theta*n)*sin(phi*n)+y0;
znew = pow(r,n) *cos(phi*n)+z0;
//-------------三维公式执行---------------
if(xnew*xnew+ynew*ynew+znew*znew> 8 ){
return(i);
}
x= xnew;
y= ynew;
z= znew;
}
return(imax);
}
问题4:如何使mandel函数三维化显示
4) volume1
1) Name=density
2) Size:3*3*3
3)Uniform Sampling Divs = 200
3) pointwrangle2
)勾选√Bind Each Volume to Density //每个体像素绑给density
int maxiter =chi(“Maxiter”);
if( Mandel (@P.x, @P.y, @P.z, maxiter)<maxiter) {
f@density= 0.0;
// 唯一改变的地方,改成density,另外外面区域密度=0
}
else{
f@density= 1.1;
}
![4a8951c88828c07ab35d8895d51f200d.png](https://i-blog.csdnimg.cn/blog_migrate/f68275bc133aeaa20e7686a50bed6022.jpeg)
![b9f9e8e66757fb5113106cb5f30f5788.gif](https://i-blog.csdnimg.cn/blog_migrate/e9ae71d1ff2347d38cc3ec920ce79579.gif)
![2354f64ecb2db54324526d0af53973d0.gif](https://i-blog.csdnimg.cn/blog_migrate/0da831abf983fb051d7d62c32717dfea.gif)
5) convertvdb1[1]
![cf3dacfff3699db66983b15457007f44.png](https://i-blog.csdnimg.cn/blog_migrate/56ad50cbdc30ac42ff84fe821bb9e647.jpeg)
提高volume精度
4) volume1
1) Uniform Sampling Divs = 400
![5798dc26fd6dcf5ee39e563f54f642aa.png](https://i-blog.csdnimg.cn/blog_migrate/813581bfd456315acb7e3865e612dbd0.jpeg)
因为直接渲染SDF速度会比转换成多边形快很多,所以我们要用sdf渲染,但是默认渲染器没有sdf渲染接口。
问题5:如何渲染sdf体积
给渲染geo物体增加两个参数接口
6)mantra1:
a) 点击
![6212d00be5f6d619998dbc444fc6805a.png](https://i-blog.csdnimg.cn/blog_migrate/04a199c0afb66fb68d86510222fa6b08.jpeg)
b) 弹出窗口:在左下角Filter里输入vol筛选出上方Render Properties面板下的与volume有关的选项
![aaa9870caee9ef113f30c2ed3b3964f0.png](https://i-blog.csdnimg.cn/blog_migrate/69ca43c94d5b4f779686ffa9af71092e.jpeg)
c) 选择volume Isosurface和Volume Density拖动到右边sampling下面。
d) 现在sampling面板下就增加了这两个参数
![0852faed05123a7cffb06d10b10f1a0d.png](https://i-blog.csdnimg.cn/blog_migrate/7d37e93c4a803bfde2d2e7bd6a405a99.jpeg)
e) 勾选volume Isosurface就可以渲染SDF。
问题6)如何提sdf体积解算速度
操作:复制volume1,volumewrangle1
7)volume2
1) Size:5*5*5 //增加体积尺寸
2) Uniform Sampling Divs=40 //减小体素单位数量
8)volumewrangle2
1) N=2.2
![943a7f6604e8534ecd313ea8e7efd19d.png](https://i-blog.csdnimg.cn/blog_migrate/fc9e1b6473dd7796779c0b147af04260.jpeg)
9)vomumebound1
1) Bounding Value=0.001 //这是仅仅激活box范围内的volume。
![c0a86468ff3d38d33a2e56dc9a2240ad.png](https://i-blog.csdnimg.cn/blog_migrate/a37b4182053b66616bf3bde5852b61bc.jpeg)
10)peak1
1) Distance=0.02 //扩展一点点。
操作:复制刚才的volume,volumewrangle,convervdb,连接volme3
11)volume3
1) Size全部为0//它继承peak传过来的volume
2)
![cf183a9a265daff761e443d3b3f27126.png](https://i-blog.csdnimg.cn/blog_migrate/3d152c904a53daf60318de493d97f874.jpeg)
![1b13c0d1e8175562b8c27b40bd01ba17.png](https://i-blog.csdnimg.cn/blog_migrate/6d665676357ddf854dd26321a2fb9108.jpeg)
12) volumewrangle3
1) N=5。
2) 关联复制到volumewrangle2的N上。
13) convertvdb2 //转SDF
14) convertvdb3 // 转Polygons
![71761d16952d08e422f47fafb2b48d4a.png](https://i-blog.csdnimg.cn/blog_migrate/c3480bda6af65e34532e6bea1d7011d1.jpeg)
![6dbabd42064cf96568e3f48ae259fbdd.png](https://i-blog.csdnimg.cn/blog_migrate/f41456cfd259b0f003a3218928e9ffcd.jpeg)
下一节:速建Quick Tip. Loops & Subdivision迭代循环细分
教程翻译自entagma的网络教程,本文图片全部原创,版权归原作者所有。
![d535bc62fce23931d0d7311964034279.png](https://i-blog.csdnimg.cn/blog_migrate/2624fc131345d521015c0c283120b5e0.png)
参考
- ^density转成SDF