一种裂纹效果的实现
裂纹效果的实现
——一种真正递归分岔的裂纹
关键字:houdini程序化,地形,arnold,裂纹,裂缝,裂痕,递归,二叉树,地震裂纹
一般Vnoise(或叫cell noise) 实现的裂纹更像是土地干旱裂的,如下图是用vnoise实现:
而我想要的是一种大地震造成的大范围的裂纹的模拟,可以递归分岔的树状裂缝结构,vnoise不能满足需求,根据二叉树原理自己做一个吧!
效果展示:
下图是没有扭曲坐标的效果:
这里有一个houdini vex展示的简单原理代码实现:
1 vector fastperlin(vector p) 2 { 3 vector f = 0.0; 4 vector pp = p ; 5 vector nn = noise(pp)-set(0.5); 6 f += 1.0000 * nn; pp = 2.0 * pp;nn = noise(pp)-set(0.5); 7 f += 0.5000 * nn; pp = 2.0 * pp;nn = noise(pp)-set(0.5); 8 f += 0.2500 * nn; pp = 2.0 * pp;nn = noise(pp)-set(0.5); 9 f += 0.1250 * nn; pp = 2.0 * pp;nn = noise(pp)-set(0.5); 10 f += 0.0625 * nn; pp = 2.0 * pp; 11 return f; 12 } 13 float line(vector intpoint1;vector intpoint2;vector p;float width1;float width2) 14 { 15 float k = (intpoint2.z - intpoint1.z)/(intpoint2.x-intpoint1.x); 16 float b = intpoint1.z - k * intpoint1.x; 17 float distance = abs(k * p.x - p.z+b) / sqrt(k * k + 1); 18 float clp = dot(intpoint1 - p,intpoint2 - p)>0?0:1; 19 float width = lerp(width1,width2,distance(p,intpoint2) / distance(intpoint1,intpoint2) ); 20 return (1.0 - clamp(distance,0,width*0.5)/(width*0.5))*clp; 21 } 22 23 void nearcellpoints(vector pp;vector nearpos1;vector nearpos2;) 24 { 25 float dist1=0; 26 float dist2=0; 27 int seed=0; 28 vnoise(pp,set(0.8,0.8,0.8),seed,dist1,dist2,nearpos1,nearpos2); 29 } 30 31 float multiline(vector intpoint;vector dir;vector pp ;float width;float widthscale;float lengthscale;float angle;float anglebias;int seed;vector nearpos1;vector nearpos2) 32 { 33 vector pos = pp; 34 vector np1,np2; 35 vector direct1 = normalize(dir)*maketransform(0,0,set(0),set(0,-angle+anglebias*(rand(seed+41)*2-1),0),set(1),set(0)); 36 vector direct2 = normalize(dir)*maketransform(0,0,set(0),set(0,angle+anglebias*(rand(seed+415)*2-1),0),set(1),set(0)); 37 np1 = intpoint + lengthscale*direct1*fit(rand(seed+138),0,1,0.5,1); 38 np2 = intpoint + lengthscale*direct2*fit(rand(seed+618),0,1,0.5,1); 39 float tmpline1 = line(intpoint,np1,pos,width*widthscale,width); 40 float tmpline2 = line(intpoint,np2,pos,width*widthscale,width); 41 float out = max(tmpline1,tmpline2); 42 float tempwidth = width; 43 nearpos1 = np1; 44 nearpos2 = np2; 45 return clamp(out,0,1); 46 } 47 48 vector p1 = set(0,0,0); 49 vector p2 = set(17,50,0); 50 vector pp = @P*1+fastperlin(@P*4)*set(0.3,0,0.3); 51 vector nextpos[] = {}; 52 vector fatherpos[] = {}; 53 vector np1,np2; 54 float width =0.06; 55 float widthscale = 0.8; 56 float o1 = multiline(p1,set(1,0,0),pp,width,widthscale,1,90,10,1,np1,np2); 57 insert(nextpos,0,np1); 58 insert(nextpos,0,np2); 59 insert(fatherpos,0,p1); 60 insert(fatherpos,0,p1); 61 float lengthscale = 1; 62 for(int i=0;i<chi("iter");i++) 63 { 64 vector tmpnextpos[] = {}; 65 tmpnextpos = nextpos; 66 vector tmpfp[] = fatherpos; 67 width *= widthscale; 68 if(o1>0.01) 69 break; 70 for(int j=-1;j>-len(tmpnextpos)-1;j--) 71 { 72 vector pos = tmpnextpos[j]; 73 vector fp = tmpfp[j]; 74 vector dir = pos -fp; 75 if(length(dir)>1) 76 continue; 77 vector tmpnp1,tmpnp2; 78 lengthscale *= 0.99; 79 o1 = max(o1,multiline(pos,dir,pp,width,widthscale,lengthscale,50,30,i*10+j,tmpnp1,tmpnp2)); 80 if(find(nextpos,tmpnp1)<0) 81 { 82 insert(nextpos,0,tmpnp1); 83 insert(fatherpos,0,pos); 84 } 85 if(find(nextpos,tmpnp2)<0) 86 { 87 insert(nextpos,0,tmpnp2); 88 insert(fatherpos,0,pos); 89 } 90 pop(nextpos); 91 pop(fatherpos); 92 } 93 } 94 95 @Cd = o1;
也可以去群里下载相关的hip文件!
补充说明::
安装最新版arnold6_foolshader arnold5_foolshader 就可使用该节点,节点名cracknoise
分岔的数量与iterate的exp 成反比
iterate越大计算越慢,但并非指数关系,收敛较快
节点安装方法:
在htoa中dll文件放到arnold/plugin下,在软件里该节点在shading环境右键fool texture下。
在mtoa中dll文件放到arnold/shaders下,在软件里,该节点在材质编辑器的texture/fool texture下。
相关的案例文件和dll文件请到群里下载。