Displacement Map
สร้างฉากใต้ทะเล โดยใช้ Displacement Map
Chamferbox
ขั้นตอนการสร้าง เตียง ผ้าคลุมเตียง หมอนใบนั้น
Compesite Map
ขั้นตอนการสร้างวัสดุ น้ำ Compesite Map

[Introduction to Shading Language Part 1]
หลังจากได้เสนอเรื่องการใช้งาน PRMan ผ่าน RAT ไปในครั้งก่อนๆ มีหลายคนถามเข้ามา เกี่ยวกับเรื่อง การใช้ งาน Shading Language ครับ จริงๆแล้วเรื่องนี้เป็นเรื่องทางเทคนิคจริงๆ เพราะฉะนั้นใครที่ไม่มีพื้นฐาน เรขาคณิตมาก่อนอาจจะงงๆไปบ้าง แต่ก็ลองอ่านไว้เป็นความรู้ครับ ก่อนจะไปถึง Shading Language มาพูดถึงของ Shade หรือการให้สีบนพื้นผิวตอน render กันก่อนดีว่าครับ

นี่คือสมการที่ใช้ในการคำนวณผิวแบบ Phong ใน renderer ทั่วๆไป โดยที่
Coutput : สีที่ได้ออกมา
Ka, Kd, Ks, n : คือตัวคูณ (n เป็นตัวยกกำลัง) ของค่า Ambient, Diffuse, Specular ตามลำดับ
Camp, Cdiff, Cspec : คือสีของ Ambient, Diffuse, Specular ตามลำดับ
N : normal vector ของพื้นผิวบนจุดที่มีการคำนวณ
R : vector สะท้อนของ แนวกล้อง
Li : Vector ของแสงแต่ละดวง
Cli : สีของแสงแต่ละดวง

จากภาพนี้เราก็จะสามารถทราบได้ว่าจะShadeจุดบนพื้นผิวได้อย่างไรหลักการคือคำนวณแสงทีละดวงแล้วนำมาบวกกันแสงแต่ละดวงคำนวณโดย นำ L มาหา Dot Product กับ N เพื่อดูว่าแสงทำมมุกับพื้นผิวมากแค่ไหน ถ้าขนานกันก็ได้ 1 ถ้าตั้งฉากก็ได้ 0 และ R Dot L เพื่อหาการทำมุมของกล้องและแสง ถ้าแนวสะท้อนของกล้อง ขนานกับแนวแสงได้ 1 ถ้าตั้งฉากได้ 0 นำค่าที่ได้มากบวกกันแล้วบวกเข้ากับค่า ambient อีกที ก็จะได้สีชอง พื้นผิวออกมา

อันนี้เป็นตัวอย่างง่ายๆครับของ Shader ที่เขียนบรรทัดเดียวจบอย่าง Phong ใน Maya ก็จะมี Shader ให้ใช้ หลายอย่างเช่น Blin, Anisotopic, Lambert เหล่านี้ก็มีสมการกำหนดการ Shade ที่แตกต่างกันออกไป

Rob Cook เห็นว่าการที่ software กำหนด Shader มาตายตัวแบบนี้ทำให้การสร้างพื้นผิวมีข้อจำกัด หลายอย่าง เช่นเมื่อต้องการ Shader ที่ตอบสนองกับแสงที่แตกต่างจากนี้ ก็ไม่สามรถทำได้ หรือถ้าทำได ้ก ็ต้อง เขียนโปรแกรมขึ้นมาใหม่ซึ่งยาวและเสียเวลามากเกินไป เขาจึงคิด Shading Language ขึ้นมาในปี 1984

เอาล่ะมาดูตัวอย่างกันครับ
surface
plastic( float Ks=.5, Kd=.5, Ka=1, roughness=.1; color specularcolor=1 )
{
normal Nf;
vector V;
Nf = faceforward( normalize(N), I );
V = -normalize(I);
Oi = Os;
Ci = Os * ( Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * specular(Nf,V,roughness) );
}
นี่คือ Shading Language ที่แปลงจากสมการของ Phong ด้านบน ใครที่เคยเขียนภาษา C มาก่อนคงจะคุ้นเคยละครับคล้ายกับการเขียน fuction ในภาษา C นั่นเอง ในที่นี้ output คือ Ci หรือสีของพื้นผิว และ Oi ค่า ความทึบแสงของพื้นผิว

ค่อยๆดูกันครับ คืออะไรบ้าง
surface
plastic( float Ks=.5, Kd=.5, Ka=1, roughness=.1; color specularcolor=1 )
ตรงนี้ คือ การกำหนด parameter หรือตัวแปลควบคุมต่างๆ และกำหนดค่าเริ่มต้นเอาไว้ด้วย
Nf = faceforward( normalize(N), I );
V = -normalize(I);

สองบรรทัดนี้เตรียมตัวแปลเพื่อส่งเข้า function ในบรรทัดถัดไป faceforward เป็น function ใช้หาทิศทาง เพื่อให้ชี้มาทางเดียวกัน กรณีนี้คือถ้า normal vector ชี้ออกจากกล้อง (I) ก็ชี้กลับเข้ามาซะ ส่วน normalize คือ function ใช้ในการเปลี่ยน vector ใดๆ ให้เป็น unit vector หรือ vector หนึ่งหน่วย เพื่อให้ Dot Product มีผลลัพท ์ระหว่าง 0 ถึง 1

Ci = Os * ( Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * specular(Nf,V,roughness) );

บรรทัดนี้ใช้ในการทำนวณผิว โดยเรีย fuction เช่น diffuse เพื่อคำนวณ diffuse เรียก specular เพื่อคำนวณ specular จากตรงนี้เราจะสังเกตได้ว่าแต่ละ fuction ก็ต้องการตัวแปลที่จะส่งเข้าไปต่างกัน

มาถึงตรงนี้บางคน อาจะเกิคำถามว่า ไม่เห็นมีการวน Loop เพื่อคำนวณแสงทีละดวงเลย แล้วก็ไม่เห็นมีการใช้ งาน Dot Product คำตอบคือการทำงานเหล่านี้ถูกซ่อนไว้ใน function ครับ เนื่องจากการทำงานแบบนี้ถ้าเขียน function เองเสียเวลาในการ render นาน renderman มี function การทำงานที่ optimized มาแล้ว แต่ก็ สามารถเขียนได้เองถ้าอยากลองเขียนดู

เรามี script ของ Shading Language ซึ่งเรียกว่า surface shader การเขียนจะเขียนในโปรแกรมเช่น notepad แล้ว save เป็นไฟล์ .sl ในที่นี้ผมจะให้ชื่อว่า plastic.sl

จากนั้นจำเป็นต้อง compile หรือแปลให้อยู่ในรูปที่ software เข้าใจก่อนการใช้งาน ไฟล์ .sl สามารถใช้งานได้ กับ renderer ที่ใช้มาตรฐานของ renderman ได้ทั้งหมด แต่ render แต่ละตัวก็จะมีการทำงานภายในที่แตก ต่างกัน จึงจำเป็นต้อง compile ให้เรียบร้อย ก่อนการใช้งาน

เพื่อความสะดวกในการ compile ผมจะกำหนด evironment variable ชี้ไปที่ folder bin ของ PRMan เพื่อ ให้เรียกใช้งานจากไหนก็ได้
คลิกขวาที่ My Computer แล้วเลือก Properties

ที่แถบ Advance คลิกปุ่ม Environment Variables

ดูบรรทัดที่มีคำว่า PATH แล้วกดปุ่ม Edit

เพิ่ม directory ของ PRMan เข้าไปครับ

โดยทั่วไปแล้วจะอยู่ที่ C:\Program Files\Pixar\prman-11.0.1\bin แล้วก็อย่าลืมใส ; ลงไปข้างหน้าด้วยครับ

เขียน script ลงไปใน notepad แล้ว save เป็น plastic.sl

ใน command prompt เข้าไปใน folder ที่เราเก็บ shader เอาไว้แล้วพิมพ์ shader plastic.sl กด Enter เป็นอันเสร็จ เราจะได้ plastic.slo ขึ้นมาที่ folder เดียวกันกับที่เก็บ plastic.sl เอาไว้ ถ้าเขียนผิด ตอนนี้ก็จะมี error เกิดขึ้น ลองเป็นเช็คดูครับว่าเขียนผิดตรงไหนบ้าง ถึงเวลา Maya แล้วครับ เปิด Maya และเปิด slim ขึ้นมา เรียก shader โดยไปที่ file>>import appearence เลือก plastic.slo

ได้ shader ออกมาหนึ่งอันแบบในภาพ

ถ้าลอง double click ดูจะเห็นรายละเอียด

การ import เข้ามาแบบนี้ Slim จะสร้าง shader ให้เราหนึ่งตัวโดยผูกติดเข้ากับ slim templateที่ชื่อensembleก็เลยมีตัวแปลที่เราไม่ได้สร้างขึ้นมาด้านบนเยอะแยะ และตัวแปลที่เราทำขึ้นมา ก็อยู่ในกรอบสีแดง ปรับค่าใช้งานได้ตามปกติ

ปัญหาก็คือเราไม่สสามารถเปลี่ยนตัวแปลเป็นแบบ connection ได้ ก็ใส่ texture ไม่ได้ ถ้าอยากใส่ texture ด้วยวิธีในต้องเขียน script เพื่อใส่ texture ใน .sl เอาเอง ซึ่งเสียเวลาครับ มานั่งเขียนกันทุกๆตัวแปล ทางออก คือ แทนที่เราจะ compile เป็น .slo เราจะเปลี่ยนในเห็น .slim ซะ เรียกว่า slim template เขียน code ลงไป ใน notpad ออกจะยาวซักหน่อย

slim 1 extensions pixardb {
extensions pixar pxsl {
template shadingmodel splastic {
parameter color sfcolor {
label "Surface Color"
description {Surface Color}
detail varying
default "1 1 1"
}
parameter color speccolor {
label "Specular Color"
description {Specular Color}
detail varying
default "1 1 1"
}
parameter color sfopacity {
label "Surface Opacity"
description {Surface Opacity}
detail varying
default "1 1 1"
}
parameter float Ka {

label {Ka}
description {Ka}
detail varying
default 1
}
parameter float Kd {
label {Kd}
description {Kd}
detail varying
default 1
}
parameter float Ks {
label {Ks}
description {Ks}
detail varying
default 1
}
parameter float roughness {
label {roughness}
description {roughness}
detail varying
default 1
}
collection shadingmodel shadingmodel {
access output
display hidden
parameter color CI {
detail varying
default {0 1 0}
access output
}
parameter color OI {
detail varying
default {1 1 1}
access output
}
}
RSLFunction {
void pxslsplastic(
color sfcolor;
color speccolor;
color sfopacity;
float Ka;
float Kd;
float Ks;
float roughness;
output color CI;
output color OI;){
extern normal N;
extern vector I;
normal Nf = faceforward(normalize(N), I);
normal V = -normalize(I);
OI = Os*sfopacity;
CI = Os * Cs * (Ka * ambient() + sfcolor * Kd * diffuse(Nf) + speccolor * Ks * specular(Nf,V,roughness));
}
}

}
}
}
รูปแบบในการเขียนคือ กำหนดตัวแปลให้ครบ และกำหนด function ซึ่งเขียนตามรูปแบบ Shading Language แล้ว save เป็น .slim ข้างบนนี้ผมให้ชื่อว่า splastic.silm วิธีการโหลดเข้ามาใช้งาน เปิด slim console ขึ้นมา ครับ

จากนั้นพิมพ์ slime ReadSlimFile ตามด้วยที่อยู่ของ file .slim และกด enter

เป็นการโหลด slim เข้าไปใช้งาน และเราจะเห็น shader ที่เราสร้างขึ้น เกิดขึ้นใน menu

ลองสร้างขึ้นมาซักอันครับ...

จะเห็นความแตกต่างระหว่างอันแรกที่ import เข้ามาโดยใช้ shader compile เป็น .slo กับ .slim เครื่องหมาย สีจากหมายถึงไม่สามารถ connect กับตัวอื่นๆได้ ส่วนสีเข้มคือสามารถ connect ได้ตามปกติครับ

ลองใส่ texture และเปลี่ยนค่าตัวแปล ก็จะได้ shader ของเราเองออกมาหนึ่งอัน slim template เป็นการเขียน script ที่นิยมกันในหมู่คนใช้ RATเนื่องจากมีความยืดหยุ่นมาก และสะดวกใน การใช้งาน แต่ทั้งนี้ก็ต้องแลกกับการที่จะต้องเรียนรู้เรื่องการเขียนโปรแกรม ซึ่งก็ไม่ใช่เรื่องง่าย เท่าไหร่นักกับคน ที่ไม่เคยเขียนมาก่อนเลย แต่ถ้าสามารถทำได้ก็คุ้มครับ กับผลที่ได้คราวหน้าผมจะพูดถึงเรื่องนี้เป็นตอนที่สองด้วยการยกตัวอย่าง slim template และมาดูกันครับว่าเราสามารถใช้ ประโยชน์อะไรได้อีก

<<Back