2009年4月23日 星期四

Hiroshige Fishscales Shader Tutorial

現在介紹surface shader
一樣是用網路上的另一個範例,目的在做出像魚麟的效果,連結如下
http://tutorials.vizyacky.com/vizy_tutorials_student/ChipCollier_fishscales_tutorial/ChipCollier_fishscales_tutorial.php

Step1:
先設置一個簡單的場景



















Step2:
一樣,File -> New Operator Type ...,
除了Network Type設為Surface Shader Operator,其餘設定都仿照上一個教學,如圖,按下 Accept


















Step3:
在Network Editor,選擇Material Palette,拉一個Basic Surface材質進去,如圖,再將此材質指定給場景中的Sphere




















Step4:
來小試牛刀一下。在Editor Operator Type Properties 視窗裡,Key入
surface
noise_surf(vector clr = {1,0,0}; float frequency = 1;
export vector nml = {0,0,0})
{
Cf = clr * (float(noise(frequency * P)) + 0.5) * diffuse(normalize(N));
nml = normalize(N)*0.5 + 0.5;
}
一樣,按下Test Compile

Step5:
在Network Editor選擇shop標籤





















然後進入basic_surface node





















Step6:
然後在suboutput1 node的 input上,shift+滑鼠右鍵→選擇剛剛輸入的Operator Label名稱,如圖。一樣,按下Edit Operator Type Properties的Apply



















Step7:
算張圖來看看吧。Render→Create Render Node→mentra,
然後Render→Start Render→mentra1,可得下圖


















Step8:
來試試教學範例上的code吧。將noise_surf內的code改成
int rep_s=10;
int rep_t=15;

float tt = (t * rep_t) % 1;

vector colorA = {0,0,0};
vector colorB = {0.5,0.7,0.8};
vector colorC = {0.9,1,0.9};

float radS = radians(s * (rep_s * 180));
float tSin = sin(radS);
float tCos = cos(radS);

float apt = abs((tt<=0.5)?tCos:tSin) * 0.5; float bpt = abs((tt<=0.5)?tSin:tCos) * 0.5; float cpt = apt - 0.05; float _tt=0; if(tt < _tt =" tt;" _tt =" (tt-0.5);">
Cf = colorB;
} else {
if( _tt > apt) {
if(_tt
Cf = colorA;
} else {
Cf = colorB;
}
} else {
Cf = colorC;
}
}
(註:要將範例檔中的_s改成s,_t改成t,surfcolor改成Cf)
然後一樣,Test Compile→Apply
再算圖即可得出以下結果:





















教學檔上的理論部份就不贅述了,至於上面提到的s,t,Cf等,為內建的變數,有興趣的話,
可以去查查相關資料。

A Generic Ripple - Creating a custom VEX Operator (by Georg Duemlein)

(這前4篇只是將以前寫在另一個blog的Houdini心得整理過來)

這是網路上抓到的一個教學範例
連結:http://www.preset.de/2007/0824/generic_ripple/rdg-genericRipple.pdf


Step1: File -> New Operator Type ...













Step2:
在Operator Name 輸入 rdg_ripple
Operator Label 輸入 RDG Ripple
(這裡可以自由輸入名稱,為尊重作者,所以用教學檔上的名稱)

Network Type 選擇 Geometry Operator
Install Library to 選擇 Current HIP File Only
Save To Library 則指定自己想儲存的路徑
按下 Accept

Step3:
然後會出現以下視窗






















選擇Vex Code標籤
Key入
sop
rdg_ripple( float freqency = 50;
float speed = 0;
float amplitude = 0.1;)
{
vector offset = {0, 0, 0};
float offset_y = 0;
float dist = length(P);
offset_y = sin(dist * freqency + speed) * amplitude;
setcomp(offset, offset_y, 1);
P += offset;
}

按下Test Compile,若是沒有bug,則會出現以下視窗(先不要將此視窗關掉)
























Step4:
在Network Editor按下 Tab鍵→Geometry,按下i進入Geometry node,
刪除file1 node,接著再按Tab→Grid,然後將Rows 及 Columns調到50,如圖
(將那兩個數值調高的原因在於可以展現較平順的效果)






















Step5:
在grid1的output上,shift+滑鼠右鍵→RDG Ripple,會出現如下圖:

















然後按下Operator Type Properties視窗的 Apply
即出現如下圖之結果:
















挺有意思的吧


這裡只單純的大概介紹如何使用sop shader,教學檔裡的理論部份也只是簡單的三角函數,就不贅述囉!

2009年4月14日 星期二

簡單介紹pymel以及安裝

什麼是pymel咧?有在寫mel的應該都知道Maya在8.5版之後,有跟python做結合。但是....結合的不是很好,有很多python的優勢沒有發揮出來,像是對資料的動態處理。所以呢,就有幾位工程師,開始著手改良python與maya的結合~~~pymel就誕生了。話說某天用maya原本的python在寫一個工具,為了要動態的存取stringarray這個type的attribute,try了很久,但是卻一直跳error出來,而我現在的主管就在這時向我介紹了這好物,整個輕鬆解決了那時的問題。先介紹一下一下怎麼安裝,再敘述當時遇到的狀況囉~

可以先去這個連結:
http://www.highend3d.com/maya/downloads/tools/syntax_scripting/Pymel-4844.html
下載pymel的壓縮檔,解壓縮後,會得到一個名稱為pymel的資料夾。如果是Windows的使用者,直接將此資料夾複製到My Document\maya\prefs\script裡,即可使用。

來敘述一下當時遇到的問題吧,先看以下code:
###########################################################
import maya.cmds as mcmds
#宣告一個array, 值為a, b, c

TestStringArray=['a','b','c']
#新增一個transform的node,並將其命名為testnode
mcmds.createNode( 'transform', n='testnode' )
#給testnode新增一個資料型態為stringArray的屬性,其名稱為test_stringArray
mcmds.addAttr('testnode', longName='test_stringArray', dt='stringArray')
#將TestStringArray的值,assign給testnode.test_stringArray
mcmds.setAttr('testnode.test_stringArray', 3, TestStringArray, type='stringArray')
###########################################################
執行的話,會在最後一行發生error,因為它不能先宣告一個array (test_stringArray=['a','b','c']),然後再把這個array的值set給testnode.test_stringArray。所以得將最後一行改成

mcmds.setAttr('testnode.test_stringArray', 3, 'a', 'b', 'c', type='stringArray')

如果現在要在這個testnode.test_stringArray放100筆資料呢.....總不能這樣寫

mcmds.setAttr('testnode.test_stringArray', 100, 'a1', 'a2', 'a3',...bla bla...,'a100', type='stringArray')

很恐怖吶!!

但是換成用pymel的話,就可以直接用已經宣告好的array來用,如下:

#先import pymel的module
from pymel import *
#將TestStringArray assign給testnode.test_stringArray
setAttr('testnode.test_stringArray', TestStringArray)

酷吧~ 而pymel在寫UI時,也有其便利性在,以後有機會在寫上來囉~

(5)RenderMan Globals基本介紹

前面幾篇,除了比較偏programming的部份,也大概介紹了surface, displacement怎麼使用,也是該介紹像是解析度、gamma值、ray tracing....等怎麼設定。這一切~都在RenderMan Globals裡可以設定,簡單來說,RenderMan Globals裏面的設定,決定了render出來的結果。這裡僅介紹小轉個人比較常用的部份囉~

◎RenderMan -> RenderMan Globals 可以看到如下視窗。Display->Primary:
Display Name: render出來的檔案名稱。
Camera Name:用來render的camera的shape名稱。(注意~要是shape的名稱喔)
Display Resolution:解析度。
Display Server:用來選擇要render出來的檔案格式,如果是it的話,就是會直接顯示於catelog視窗。
Exposure:設定gamma值用的。

至於Secondary以及Channel是在出pass、layer時會用到,以後再介紹。






















◎Camera:
Motion Blur:就是Motion Blur,沒辦法更白話了。
Shutter Angle:Motion Blur的程度。





















◎Reyes:
Shading Rate:可以想成render出來的精細度,值越小,計算的範圍越小,也就越精細。
Pixel Samples:也是決定render出來的精細度,值越大,每次計算的pixel sample越多,也就越精細。





















◎Rays:
Ensemble Ray Tracing:打開的就,就會計算ray tracing。





















◎Accel:
Selected Object Only & With Selected Lights:照字面上看,就是只render選取到的object和light。





















◎Spool->Frames:
就是render出連續圖檔的相關設定,字面上還挺容易懂的,就懶的打了~

2009年4月13日 星期一

(4)displacement及貼圖的基本運用

上一篇拉哩拉咂的打了一堆偏programming的東西,也是該來介紹一下如何使用displacement和貼圖了。

什麼是displacement呢,簡單來想,就是會變形的bump。

先開始介紹怎麼使用貼圖吧~

◎這裡也是接續第1篇小小筆記的檔案。在graph layout上按滑鼠右鍵-> Colors-> Maps-> ImageFile 來新增一個ImageFile,顧名思義,這就是一個貼圖用的node。其實這裡也可以選Floats-> Maps-> ImageFile,會產生一個灰階的ImageFile,因為displacement用灰階的就可以了。為什麼這裡要用彩色(color)的呢,等一下會說明。

















◎在ImageFile的File選項,按下資料夾的圖示,選擇所要使用的貼圖檔案路徑(通常只能為 *.tif)。然後按下另一個圖示,選"Convert Textures",將剛剛指定的*.tif轉成Pixar RenderMan的貼圖檔案格式(*.tex)。











◎將此ImageFile接到Simple的Displacement,當作要產生displacement的紋路。這裡來解釋一下為什麼要選用color的ImageFile,因為如果把這node接到diffuse的color的話,就可以把這當作彩色的底色囉。



















◎這裡是用一張青蛙的圖(kero~kero)。按下"Toggle preview render setting",然後將"Object Shape"選為Plane,就可以將preview的模式改成plane。






















◎S Filtering & T Filtering:是延texture的座標軸(s,t)做blur。例如把兩個值都調成8的話,就可以看見一隻糊的青蛙。






















◎在manifold的地方,接一個ST的node,就可以對這個ImageFile,延(s,t)做一些手腳。

















◎例如...把ST node的repeat的參數都調成2的話,就可以看到2x2=4隻青蛙。其餘的參數....就自己paly吧~






















◎把上述的動作回歸到預設值。在Simple裡preview一下,可以看到如下圖。這裡是將Kb設為0.2,Displacement bound設為1。注意:Displacement bound的值要大於Kb的值。






















◎在場景中新增一個plane,隨便打點燈。建議新增的物件最好要是polygon,比起nurbs,較不會有接縫不連續的問題。




















◎將Diffuse以及Specular的color都調成50度的灰,render即可看到如下結果。


















◎看一下如果Displacement bound的值小於於Kb的值會怎麼樣。











◎就會看到出來的結果會有破洞

2009年4月10日 星期五

Houdini強者:Jacys的blog

http://tw.myblog.yahoo.com/chiao-pi 他是我的一個好朋友~特效神人Jacys~Maya跟Houdini都很厲害喔!!

2009年4月8日 星期三

(3)結合C和RenderMan API來輸出*.rib

這裡要先介紹一個很不錯的免費RenderMan:Pixie,可以去他的官方網站:http://www.renderpixie.com/ 下載。

很多人以為RenderMan=Pixar,事實上~RenderMan只是一套規格,符合這套規格的都可以稱做RenderMan。

這裡用的程式編輯器是Visual Studio.Net 2005。安裝好Pixie後,除了把lib, include, dll...等,copy到Visual Studio.Net 2005對應的目錄下,還要在工具列上的專案→屬性→連結器→輸入→其他相依性,輸入ri.lib sdr.lib。然後,開啟Visual Studio 2005→檔案→新增→專案,選擇"Win32主控台應用程式"按下確定,在彈出視窗左邊的選擇應用程式設定→其他選項→空專案。這裡小轉是將project名稱命名為"RenderMan_Cube"。

然後在原始檔案新增一個C++檔案,key入下面的code(參考資料為"The RenderMan Companion [Steve Upstill]"):

#include <ri.h>
#include <stdio.h>
#define NFRAMES 10 /* number of frame in the animation */
#define NCUBES 5 /* # of minicubes on a side of the color cube */
#define FRAMEROT 5.0 /* # of degrees to rotate cube between frames */

#define L -0.5
#define R 0.5
#define D -0.5
#define U 0.5
#define F 0.5
#define N -0.5

void UnitCube()
{
static RtPoint Cube[6][4]={
{{L,D,F}, {R,D,F}, {R,D,N}, {L,D,N}},
{{L,D,F}, {L,U,F}, {L,U,N}, {L,D,N}},
{{R,U,N}, {L,U,N}, {L,U,F}, {R,U,F}},
{{R,U,N}, {R,U,F}, {R,D,F}, {R,D,N}},
{{R,D,F}, {R,U,F}, {L,U,F}, {L,D,F}},
{{L,U,N}, {R,U,N}, {R,D,N}, {L,D,N}}
};
int i;

for(i=0;i<6;i++)
RiPolygon(4, RI_P, (RtPointer)Cube[i],RI_NULL);
}

void ColorCube(int n, float s)
{
int x, y, z;
RtColor color;//宣告顏色變數
RtObjectHandle cube;//選告物件變數

if(n<=0)
return;

cube = RiObjectBegin();
UnitCube();

RiObjectEnd();

RiAttributeBegin();
RiTranslate(-0.5, -0.5, -0.5);
RiScale(1.0/n, 1.0/n, 1.0/n);//縮放

for(x=0; x<n; x++)
for(y=0; y<n; y++)
for(z=0; z<n; z++)
{
color[0]=((float)x+1)/((float)n);
color[1]=((float)y+1)/((float)n);
color[2]=((float)z+1)/((float)n);

RiColor(color);//指定個別cube的顏色
RiTransformBegin();//將transform的code"包"起來
RiTranslate(x+0.5, y+0.5, z+0.5);
RiScale(s, s, s);
RiObjectInstance(cube);
RiTransformEnd();
}
RiAttributeEnd();
}

void main()
{
int frame;
float scale;
char filename[20];

RiBegin(RI_NULL); /*Start the renderer*/
RiLightSource("distantlight", RI_NULL);//指定light shader明成還有其參數

/*Viewing transformation*/
RiProjection("perspective", RI_NULL);//就是perspective,沒辦法更白話了 XD
RiTranslate(0.0, 0.0, 1.5);//位移
RiRotate(40.0, -1.0, 1.0, 0.0);//旋轉

for(frame=1; frame<=NFRAMES; frame++)
{
sprintf(filename, "anim%d.jpg", frame);
RiFrameBegin(frame);
RiDisplay(filename, "framebuffer", "rgb", RI_NULL);
RiWorldBegin();
scale=(float)(NFRAMES-(frame-1))/(float)NFRAMES;
RiRotate(FRAMEROT*frame, 0.0, 0.0, 1.0);//以z軸為中心旋轉
RiSurface("matte",RI_NULL);//指定surface shader名稱還有其參數
ColorCube(NCUBES, scale);
RiWorldEnd();
RiFrameEnd();
}
RiEnd();
}


有用過OpenGL的話,應該整個覺得很熟悉(話說小轉第一次用RenderMan API時,覺得根本就是OpenGL吧)。RenderMan的function名稱都是"Ri"開頭,變數名稱為"Rt"開頭。用紅色mark起來的那兩行程式碼,會在下面介紹其功用。

執行後可以看到10個buffer(因為code中的frame數=10),有5x5x5個cube在旋轉,且邊旋轉邊縮小(下兩張圖為示意):




◎如果將RiDisplay(filename, "framebuffer", "rgb", RI_NULL);中的"framebuffer"改成"file"來執行,則會在project底下產生10張*.jpg,且檔案名稱為filename。




























◎如果將RiBegin(RI_NULL);RI_NULL改成一個*.rib的名稱(這裡小轉是用"rotate_cubes.rib"),則會在project底下輸出一個名稱為rotate_cubes的*.rib(如上上圖)。

◎將rotate_cubes.rib複製到Pixie\bin,並在命令提示字元裡,將路徑切換到Pixie\bin底下,輸入 rndr rotate_cubes.rib,則會在這個目錄底下產生如剛才的10張圖檔。

注意:Pixar的RenderMan的render程式為prman,而Pixie的則為rndr。





































來看看這個rotate_cubes.rib,用文字編輯器開啟,可以看到如下的code(因為這code落落長,所以只截取部份):


## Pixie 2.2.5

## Generated Tue Apr 07 23:41:15 2009

LightSource "distantlight" 1
#就是light shader以及其參數囉


Projection "perspective"
Translate 0 0 1.5
Rotate 40 -1 1 0
FrameBegin 1
#第一個frame開始!到下一個FrameEnd前,都是這個frame會render出來的東西

Display "anim1.jpg" "file" "rgb"
#輸出*.jpg,若是將file改成frmaebuffer,則會直接在一個視窗呈現(如第1張圖)

WorldBegin
Rotate 5 0 0 1
Surface "matte"
ObjectBegin 1
Polygon "P" [-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 ]
Polygon "P" [-0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 ]
Polygon "P" [0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 0.5 0.5 ]
Polygon "P" [0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 ]
Polygon "P" [0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 ]
Polygon "P" [-0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 ]
ObjectEnd
AttributeBegin
Translate -0.5 -0.5 -0.5
Scale 0.2 0.2 0.2
Color [0.2 0.2 0.2]
TransformBegin
Translate 0.5 0.5 0.5
Scale 1 1 1
ObjectInstance 1
TransformEnd
Color [0.2 0.2 0.4]
TransformBegin
Translate 0.5 0.5 1.5
Scale 1 1 1
ObjectInstance 1
TransformEnd
Color [0.2 0.2 0.6]
TransformBegin
Translate 0.5 0.5 2.5
Scale 1 1 1
ObjectInstance 1
TransformEnd

~~~我是code分隔線~~~

AttributeEnd
WorldEnd
FrameEnd
#這是對應上面的FrameBegin

FrameBegin 2
#第二個frame開始!
Display "anim2.jpg" "file" "rgb"
WorldBegin
Rotate 10 0 0 1
Surface "matte"
ObjectBegin 2
Polygon "P" [-0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 ]
Polygon "P" [-0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 ]
Polygon "P" [0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 0.5 0.5 ]
Polygon "P" [0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 ]
Polygon "P" [0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 ]
Polygon "P" [-0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 ]
ObjectEnd
AttributeBegin
Translate -0.5 -0.5 -0.5
Scale 0.2 0.2 0.2
Color [0.2 0.2 0.2]
TransformBegin
Translate 0.5 0.5 0.5

~~~我是code分隔線~~~

其實....看的出來都是很白話的code,就懶的各個做解釋了XD。也很明顯的可以觀察出*.rib和*.cpp的對應關係。