▉ 子在川上曰:逝者如斯夫 — 每天翻译一篇教程,这就是我写给houdini的情书。【首发于同名公众号:“致houdini的情书”】
█死亡不是失去生命,而是走出了时间——余华
我经常做一个重复的梦,一个灵魂在人类毁灭后的空旷的宇宙中,那种深入骨髓的孤独感胜过一切恐怖片,然后惊醒。
但我知道这绝非梦境,因为我知道人生在世,白驹过隙,我们在整个历史长河一个瞬间都不及,这一天迟早会到来,可能只是一眨眼的功夫。
我也知道人们都知道,但是为什么大家活的好像不会死一样,而死亡都是别人的事。是我清醒过头,还是周围的人都活在梦中,所以是我活在梦中,还是梦中的我真实的活着?
投胎来到这个世界,我们无权选择起点和重点,我们只能在这段旅程之中有一点选择。
所以请回答,怎样选择才能度过有意义的一生?
今天这一节:
讲一段序列帧的片段如何视觉化?
这一节要实现的效果
.....
▉今天是42岁第015天周五
这是写给houdini的
第041封“情书”
我是geo流程图
每帧图像映射到grid-vex表达式
//=========分解为4部分============
//分辨率x,y
int resx =chi("res_x");
int resy = chi("res_y");
//创建完整路径文件字符串
string filepath = chs("File_Path");
string path, file, suffix;
//=======分解路径和文件=========
splitpath(filepath,path,file);
//=======提取文件序列号=========
string counter = itoa(opdigits(file));
//=====提取“文件名”和“后缀”======
string temp[]=split(file,counter);
file = temp[0];
suffix = temp[1];
//======用ptnum求grid层的id======
int planenum = floor(@ptnum / (resx * resy)); //取最小的数的确是层数
string num = itoa(planenum); //字符串化
stringfilename = path +"/"+ file + num + suffix;
//printf(filename);
//===创建图像文件里的对应点的颜色变量===
vector col = colormap(filename,@uv);
//===把color向量写到point上====
v@Cd = col;
HSV驱动网格点位置-vex表达式
//引入color属性
vector col = v@Cd;
//将rgb转成hsv
vector HSV = rgbtohsv(col);
//将hsv矢量的分量提取为浮点
float H,S,V;
H = HSV[0]*6.28318; //使用hue值驱动旋转,就要转化成角速度H*2pi(单位时间内转动的角度)
S = HSV[1];
V = HSV[2];
float x,y,z,r;
//====设置半径======
r = S * V;
//====设置xyz====
x = r * sin(H);
y = @P.y;
z = r *cos(H);
//====设置粒子位置,粒子大小====
v@P = set(x,y,z);
f@pscale = 0.015;
本节需要注意的知识点:
1
节点
1) 自身复制节点:copy and Transform
2
如何分解一个引入的文件路径字符串
1)splitpath函数:分解路径path和文件file
2)opdigits函数:提取出文件file中的序号counter
3)split函数:用counter作为分隔符,提取一个:包含序号前的文件名file和后缀suffix的列表。
4)再用两个变量,提取出这两个部分;
5)引入路径分解成:a)路径path;b)文件名file;c)序号counter;d)后缀suffix;
3
如何创建grid的层id与图像序列号的关联
1)首先用primnum求得grid的id:
a)取得grid的id:int planenum = floor(@ptnum / (resx * resy));
b)整数字符串化:string num = itoa(planenum);
2)再次通过grid的id建立引入图像序列的字符串变量:
string filename = path + "/" + file + num + suffix;
4
贴图如何关联到grid平面上
1)通过colormap函数获得图像文件对应的点的颜色变量:vector col = colormap(filename,@uv);
2)再把这个颜色变量写到point上:v@Cd = col;
5
如何用ptnum求grid层的id
1)floor函数:返回小于四舍五入后值的最大整数int planenum = floor(@ptnum / (resx * resy));
2)itoa函数:字符串化;string num = itoa(planenum);
6
hsv如何驱动网格点
1)rgbtohsv函数:首先将rgb转成hsv模式
2)求grid的点位置的x,y,z;
a)提取hsv分量为浮点变量;
b)H分量控制在色圈上旋转,这需要转成角速度H*2pi(单位时间内转动的角度)
c)设置色圈的半径r=S*V
d)x=r * sin(H); z = r *cos(H);y = @P.y;
3)设置粒子位置v@P= set(x,y,z);
4 )设置粒子大小:f@pscale = 0.015;
2
函数
1)
splitpath(filepath,path,file);
splitpath函数:分割路径,将传入的字符串分割开来,路径+文件名。
2)
string counter = itoa(opdigits(file));
opdigits函数:返回字符串的最后一个数字序列的整数值。(例如:chinaArt_1.jpg返回1;)
itoa函数:转成字符串 ;
接下来
理论部分
问题1:HSV颜色模式原理
HSV颜色模式:
a)V:亮度=1;饱和度s提高=1时,
b)改变色相H数值,所有颜色映射到左边的圆上,
本例就是用这种颜色模型,来代表视频里的每一帧上的色彩,置换到空间里。
接下来
开始正式制作
使用软件houdini16.5
1)grid //
a)Rows=45;Columns=80;(比例是 9:16;电影尺寸)
b)size=1*1;(这个尺寸不必按长宽比,因为后面会改变每个像素的映射,每个像素的颜色。)
改变图片每个像素的贴图和颜色!
2):UV texture //
当前uv属性在vertices类里;转换到point类中:
1)Attribute Class:Point ;//这样uv属性进入point通道。
3)Copy and Translate
//Total Number:50;
// Translate y=0.02 //每一帧上移
// 复制电影的每一帧给这里每层grid
问题2:如何将视频的每一帧映射到对应的grid层上
4)Point Wrangle1
// 创建一个导入file的参数
2) 选择序列(注意)序列号不是01,02;还有不要选择序列;
3) 关联复制grid的长宽给Res X和Res Y;
// vex表达式:
1)分辨率x,y 和 字符串 文件路径
intresx =chi("res_X");
intresy =chi("res_Y");
stringfilepath = chs("File_Path");
a)
b) 改变参数filePath的参数类型:File-image
c) 非常重要的是,首先文件序列名不要有00的前缀;另外不要勾选show sequences as one entry;选择第一个文件;
d) 建立变量与grid的x,y轴关联;
// 需要将某个字符串,从文件路径中分离出来。这样能够针对不同的grid来调用不同的文件和路径。
2)创建几个字符串变量:
string path, file, suffix; //路径;文件;后缀
3)用分割路径splitpath函数,将传入的字符串分割开来,路径+文件名:
splitpath(filepath,path,file); //字符串;路径;文件名
//还需要一种分割方式:名字,后缀,找到序列数;例如:big_buck_bunny_0.jpg=名字(big_buck_bunny_)+序列号(0)+后缀(.jpg)
4)为找到序列号创建另一个变量名字就叫counter计数:
string counter = itoa(opdigits(file)); //chinaArt_1.jpg返回1;返回字符串的最后一个数字序列的整数值。 最后itoa函数转成字符串。这样就提取出了序列号“0”;
5)创建另一个为数组的临时字符串temp,.用它存储子字符串;split分割字符串;
string temp[]=split(file,counter); //split函数将字符串中分隔符,或空格移除,再把分隔符包围的子字符串创建数组条目。这里counter就是分隔符,所以分割后,把0移出,这个数组就是temp["buck_bunny_" , ".jpg"]
以big_buck_bunny_0.jpg为例
现在储存在temp里两个部分:
1)文件名字 “big_buck_bunny_”
2)后缀“ .jpg”;
6)从字符串temp中提取出两个变量;
file = temp[0]; //文件名“big_buck_bunny_”
suffix = temp[1]; //后缀 “.jpg”
本例filepath:$HIP/20170605 VEX in Houdini- Movie Color VisualisationMovie_Colors_To_HSV/Big_Buck/big_buck_bunny_0.jpg
至此 引入的完整路径文件字符串filepath完全被分解开成四部分:
1)路径
$HIP/20170605 VEX in Houdini- Movie Color VisualisationMovie_Colors_To_HSV
2)文件名
big_buck_bunny_
3)序列号
0
4)后缀
.jpg
6)接下来 ,观察一下这组grid的行为,找出解决方案;file文件的序号对应到哪个grid上
// 创建一个gridID变量,做这个除法还要四舍五入。取低于5的数值。
int planenum = floor(@ptnum / (resx * resy)); //取最小的数的确是层数
string num = itoa(planenum); //字符串化
如果是2*2网格grid,第一个grid的primnum=0~3;第二个grid的primnum就是4~7。第一个planenum=3/2*2(选最大primnum)第二个primnum=7/4;四舍五入之后,第一个planenum=0,第二个=1;
7) 使用grid对应的planenum的id创建引入图像文件名字符串。
string filename = path + "/" + file + num + suffix;
8)使用printf打印filename
a)输出,
printf(filename); Run Over返回point模式
b)设置运行一次。
c)弹出窗口显示运行一次调用了第一个grid对应的图片
// 使这个printf函数失效;切换回points
9)现在让我们使用文件名和网格上给定点的普遍性num来读取图像文件中的颜色,并将其写入该point color。colormap颜色映射函数
//创建颜色变量:文件里的对应点位置上的颜色值=。
a)首先文件名filename;
b)然后是uv坐标;
vector col =colormap(filename,@uv);
10)接着把这个向量写到point上;
v@Cd = col;
运行一次看看效果
问题3:如何用HSV控制点的移动
==首先rgb转成HSV模式==
现在我们有了一堆的图像,
5)Point Wrangle2
1)把color的rgb模式转成hsv模式;
vector col = @Cd;
vector HSV = rgbtohsv(col);
2)建立三个浮点;bahsv的单个矢量分量提取到浮点数中。
float H,S,V;
H = HSV[0];
S = HSV[1];
V = HSV[2];
/ 分析 / :接下来我们只使用hue值也就是“色调值”,来计算旋转,现在H从0~1,我们通过“乘积”把H转化成角速度(0~1)*2pi;(单位时间内转动的角度)
H = HSV[0]*6.28318;
===H值=转换成几何坐标===
3)这就需要一些浮点;
float x,y,z,r;
//接下来需要把颜色画到圆上。 把颜色排列在一个圆圈上,色调值H驱动“颜色圆圈”上的“角度”;饱和度值S和亮度值V驱动一个给定点离这个色圈的距离;
4)先计算半径!饱和度S乘值;
r = S * V; //饱和度乘亮度
5)接下来计算xyz坐标;x等于半径*正玄;
x = r * sin(H);
y = @P.y;
z = r *cos(H);
6)设置point点
v@P = set(x,y,z);
f@pscale = 0.015;
这些点根据颜色来移动!
06) add // 只保留grid的点,得到点云。
03)copy // 增加复制层数;500
07) transform1// xz轴向扩大2倍
08) transform2 // x轴旋转90
09) transform3 // z轴旋转-90
今天就到这儿了,收功
教程翻译自entagma的网络教程
下一节:20170611Quilling:paper spiral mosaic
本文图片全部原创,版权归原作者所有。