Houdini 里面实现科幻圆环面板的效果 -Tron

把之前做的一个procedural modeling的方法做个小结,目的是做出tron风格的圆盘界面。:

 

      

左边是目标效果  右边是实现效果


shawn老师的思路做了一下参考,这里讲一讲我的思路。

界面里面最小的元素组成是每个圆环的中的一个小扇形,那么基本的结构就是:

扇形 -> 圆环 -> 整个面板

1,扇形

扇形的做法比较简单,主要考虑的是扇形跨度,扇形最小半径和最大半径这三个参数,值得注意的是在houdini里面要做成一个完整封闭的扇形面,那么扇形上面的点排列必须是按时针顺序排列的,不然则会产生面有奇怪的扭转问题。


2,圆环

圆环里面主要判定最大最小的扇形长度以及空隙宽度,并在这个范围类循环生成新的扇形,如果所有的扇形和空隙长多超过了2π则结束这个圆环的创建


3,整个面板

在这个级别,主要是随机确定每个圆环的最小和最大半径,并确定在一个多大的高度空间内行程面板。

 

下面是代码,直接写在一个attrib wrangle 里面的detail级别就好了:

 

#define dao 6.28318530718

int segment(
    float resolution;
    float level;
    float start_theta;
    float end_theta;
    float min_radius;
    float max_radius;
    ){

    int prim = addprim(geoself(),"poly");

    //min_radius
    float steps = start_theta;
    while(1){
        if(steps < end_theta){
            vector next_pt = set(cos(steps)*min_radius, level, sin(steps)*min_radius);
            int pt = addpoint(geoself(), next_pt);
            addvertex(geoself(), prim, pt);
            steps += resolution; 
        }else{
            vector next_pt = set(cos(end_theta)*min_radius, level, sin(end_theta)*min_radius);
            int pt = addpoint(geoself(), next_pt);
            addvertex(geoself(), prim, pt);
            steps = end_theta;
            break;
        }
    }

    //max_radius
    while(1){
        if(steps > start_theta){
            vector next_pt = set(cos(steps)*max_radius, level, sin(steps)*max_radius);
            int pt = addpoint(geoself(), next_pt);
            addvertex(geoself(), prim, pt);
            steps -= resolution; 
        }else{
            vector next_pt = set(cos(start_theta)*max_radius, level, sin(start_theta)*max_radius);
            int pt = addpoint(geoself(), next_pt);
            addvertex(geoself(), prim, pt);
            break;
        }
    }

    return 1;
}

int circle(
    int definition;
    int step;
    float level;
    float min_radius;
    float max_radius;
    ){

    float total_length = 0;
    float seg_length = 0;
    float gap_length = 0;
    int seg_num = 0;

    float resolustion = dao / 181 * definition;

    float seg_step = pow(rand(step*934),2)*2;
    float gap_step = pow(rand(step*547),2)*0.5;
    float min_seg = 0.01;
    float max_seg = min_seg + seg_step ;
    float min_gap = 0.002;
    float max_gap = min_gap + gap_step;

    float start_theta = 0;
    float end_theta = 0;

    int flag = 1;


    while(flag){
        seg_length = fit01(rand(seg_num*234), min_seg, max_seg);
        gap_length = fit01(rand((seg_num+52)*25), min_gap, max_gap);
        end_theta = start_theta + seg_length;
        segment(resolustion, level, start_theta, end_theta, min_radius, max_radius);
        total_length = total_length + seg_length + gap_length;
        if (total_length > dao){
            flag = 0;
        }
        seg_num++;
        start_theta = total_length;
    }
}

int tron(){
    float max_level = 1;
    float min_level = 0;
    float max_R = 1.5;
    float min_R = 0.8;
    float max_width = 0.05;
    float min_width = 0.001;

    int max_num = 50;
    for(int step = 0; step < max_num; step++){
        float level = fit01(rand(step*234), min_level, max_level);
        float min_radius = fit01(rand(step*344), min_R, max_R);
        float width = fit01(rand(step*114), min_width, max_width);
        float max_radius = min_radius + width;
        circle(1, step, level, min_radius, max_radius);
    }
}

tron();
posted @ 2014-12-31 06:24  嘉豪一点点  阅读(2480)  评论(0编辑  收藏  举报