用集合return多个值_第015封“情书”泥什么意思?houdini Mandelbrot曼德布罗特集合...

27e57f5aaf8219d3f6fd617a7fa099bb.png
每天翻译一篇教程,这就是我写给houdini的情书-<Entagma系列>Houdini 2016教程

【注】同名公众号“致houdini的情书”

70973a37fb024758d22f1572cf56e36b.png
泥可积德慢:尔等只是一滩泥,只有在我的手里,你们才能有人的模样。

即使深陷污泥,即使被别人踩在脚底,也要努力活下去,因为泥路上有你啊,肉妮,你这个泥菩萨。

面对泥泞,可以低头看地,盯着脚下困难的泥沼,也可以抬头看天,那漫天的星辰,你有你的自由选择。但这世上若没有泥泞,种籽怎会发芽?树木又怎会生根?若没有污泥,莲花何以为生,又谈何出污泥而不染?

人生一世,草木一秋,瞑目皆归泥。我们早晚都会化成泥的。

这一节我们看一下:

殉泥派如何把比丘泥锁在一个自定义的mandel函数里。。

2354f64ecb2db54324526d0af53973d0.gif
自定义的mandle三维函数

269f1bafeaf571e1fc5ab0e4bb2cb7a9.png
这一节要实现的效果.....

▉今天是41岁第353天周日

这是写给houdini的 第015封“情书”

1faf68cb5a1d9908604036a50bddc9f8.png
先上obj流程图

本节需要注意的知识点: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 IsosurfaceVolume Density

04)如何提sdf体积解算速度

//就是实时框住volume,只计算范围内的volume,从而提高解算速度。

1) 用新的volume:减少单位内的体素数量=40.

2) 执行mandel函数。

3) 用vomumebound节点限制激活范围内的volume,节省计算量。

4) 用peak节点扩展一下volume体积。

5) 连接上之前的高单位体素=400的volume,把它的尺寸size降为0.

接下来理论部分

公式:曼德布罗特集合

467481cc880fb8663cbef697db896530.png

曼德布罗特集合

函数的两个功能

a)对grid上每个点进行循环。

b)如果计算值∞(无穷大)=黑色;反之=白色。

f2616464f208fbf816f6105fd9fe0bbd.png

9fb5965c90601eb03b7f8199de5d55f1.png

这是作者推荐的专门讲解如何编程实现“曼德布罗特集合”和背后数学原理的一个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

提高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

设置引用参数: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
N=4;Maxiter=8

b9f9e8e66757fb5113106cb5f30f5788.gif
N=4;Maxiter=1~8

2354f64ecb2db54324526d0af53973d0.gif
N=1~8;Maxiter=8

5) convertvdb1[1]

cf3dacfff3699db66983b15457007f44.png

提高volume精度

4) volume1

1) Uniform Sampling Divs = 400

5798dc26fd6dcf5ee39e563f54f642aa.png

因为直接渲染SDF速度会比转换成多边形快很多,所以我们要用sdf渲染,但是默认渲染器没有sdf渲染接口。

问题5:如何渲染sdf体积

给渲染geo物体增加两个参数接口

6)mantra1

a) 点击

6212d00be5f6d619998dbc444fc6805a.png

b) 弹出窗口:在左下角Filter里输入vol筛选出上方Render Properties面板下的与volume有关的选项

aaa9870caee9ef113f30c2ed3b3964f0.png

c) 选择volume IsosurfaceVolume Density拖动到右边sampling下面。

d) 现在sampling面板下就增加了这两个参数

0852faed05123a7cffb06d10b10f1a0d.png

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

9)vomumebound1

1) Bounding Value=0.001 //这是仅仅激活box范围内的volume。

c0a86468ff3d38d33a2e56dc9a2240ad.png

10)peak1

1) Distance=0.02 //扩展一点点。

操作:复制刚才的volume,volumewrangle,convervdb,连接volme3

11)volume3

1) Size全部为0//它继承peak传过来的volume

2)

cf183a9a265daff761e443d3b3f27126.png
Size = 400

1b13c0d1e8175562b8c27b40bd01ba17.png
volume3框住bound后的大小比自定义的范围小多了,这就节省了计算量

12) volumewrangle3

1) N=5。

2) 关联复制到volumewrangle2的N上。

13) convertvdb2 //转SDF

14) convertvdb3 // 转Polygons

71761d16952d08e422f47fafb2b48d4a.png
制作完毕

6dbabd42064cf96568e3f48ae259fbdd.png

下一节:速建Quick Tip. Loops & Subdivision迭代循环细分

教程翻译自entagma的网络教程,本文图片全部原创,版权归原作者所有。

d535bc62fce23931d0d7311964034279.png
扫一扫关注该公众号

参考

  1. ^density转成SDF
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值