Drake's Weblog

5 minute read

第一屆的 SIGGRAPH Asia 2008 於這個冬天,在新加坡落幕了。雖然沒有親臨現場參與到,但從多方得來的消息(第一手 + 第二手 + 第 n 手),皆透露出“與預期的有些落差“。另一個說法是「比較接近正常的學術論文樣貌」,亦即在有聲光、有話題、有商業加持等的活動,數量上都減少了,因而使得原來的 paper session 的比重就來得比較高了。因為是第一屆,所以 course 的部分有不少“入門級“的,但我特別喜愛這種 course,裏頭常常會有令人意外的東西。

SCAD(Savannah College of Art and Design)的 Malcolm A. Kesson 教授所開講的 Pixar’s RenderMan,就是個很好的「入門兼中等級」課程。Kesson 教授從事 Graphics Programming 教學(特別是與 RenderMan 有關)已經十餘年,是一位非常敬業且時時在 Pixar 官方討論板上提問題,讓人尊敬的教授。他自行維護的 fundza 已經出現在我的網站不下數次了,非常推薦。

雖然沒有機會現場收聽,倒是拿到了 course note,花了幾個晚上看完。說實在的,參與 SIGGRAPH course 是一件非常「累人」的任務,多麼累人,你只要稍稍回想一下,你那大學時期,聽課聽到有點出神,不小心跑去和周公下棋的經驗。對了,大致的感覺就是那樣。更何況是單單看 course note(pdf 檔),不過終究是看完了。

據說,偉大的天才科學家:愛因斯坦,他的研究之路是經過計劃的。他先是下了苦功把需要的技能一一學會,才開始了他的研究。換句話說,他把需要的「工具」摸熟了,才開始上工。(這也有可能是盜聽塗說,畢竟是一點兒考據都沒有的話,聽聽就好)

在這邊,提出一套學習 RenderMan(我的經驗,幾乎都來自於 Pixar’s RenderMan,但在寫這篇文章時,會盡量保持中立,把 PRMan 特有的東西給獨立出去不提)的途徑,說不定半年後我就推翻掉這個說法了,但「推翻」這件事本身就很有趣,所以還是值得試試。

What is RenderMan all about?

RIB -> RSL -> front-ends (RMS/MtoR/3Delight For Maya/…)

從實作出一個 RenderMan renderer 的角度來看,它包含了三部分,分別是 RenderMan Interface Specfication (RISpec, RIB)、RenderMan Shading Language (RSL) 與 renderer 本身(ex, PRMan, 3Delight, Pixie, …)。RIB 決定了給 renderer 使用的 scene description;RSL 提供了一個幾乎無限制的語法供 shader 開發與使用;renderer 則是集前兩者然後產生結果(圖片)出來。

從使用者的角度來看待 RenderMan 的話,第一個接觸到的就是 shader,或說得更精確一些:RSL。舉凡你想要的質感:香汗淋漓的皮膚、骯髒的地板、半透明的瞳孔…乃至於 Transformer 裏的金屬車,皆是從 RSL 著手出發的。其次才是因應 RIB 所提供的功能,在 renderer 上頭經由 GUI 的界面來調整的參數(ex, shading rate)。

從負責解決問題的 RenderMan TD 來看,RIB 應該比 RSL 來得重要些。RSL 比較單純,不管你是使用什麼工具來撰寫 shader,最後的樣貌都一樣是個 .sl 檔,它幾乎不會單獨產生什麼問題(bug),挺多就是 rendering time 太久、顏色不對、AOV 數值怪怪的、procedural shader 的 scale 不對…等。RIB 的問題就複雜多了。舉凡你使用的 model 上 geometry、.rib 裏頭 options 的設定、shader attachment 錯誤、light linking (or light illumination’s status)、resources path…都是 RIB 它的範疇。

從 shader TD 或 lookdev TD 的觀點的話,那很簡單,他們就只關心 RSL 裏的 illumination model 與那些用來逼近 rendering equation 而來的任何 rendering techniques/terms 就行了。他們可以好好專注在 shading problem 上頭,甚至連 lighting 的環境或燈光的數量什麼的,都可以暫時先不與以考慮。換個說法,他們的工作內容比較偏向美術從業人員,可以花很多心力在藝術造詣上頭就行。

寥寥可數(相對來說,MS Office、Adobe 軟體系列、Java programming 則多如牛毛,到了讓人覺得他們的價值大多數像二手書攤裏發黃的疊書一樣),談的內容,也大都圍繞在 RIB 與 RSL 上頭,然後輔以幾個章節解釋 RenderMan rendering architecture。至今還沒有那種 step-by-step 或圖文並茂得嚇死人的工具操作入門書(ex, RMS),有一部分原因可能是,RenderMan 的使用者幾乎都是由各家 studio 的技術人員來主導的。從一開始的怎麼使用,GUI 上頭參數校正的意義,到整合進整個 pipeline 的方式等。換句話說,雖然有一大票非技術人員的 lighter 與 shader artists 也一樣在使用 RenderMan,而且,他們的人數遠比技術人員來得多很多,但怎麼使用 RenderMan,主要還是由技術人員決定的。(這暗示了一個問題與一個趨勢,稍後再談)

雖然 RenderMan 就只是 RIB + RSL 而已,但從不同的面向來看,需要面對的問題有點不同,需要的解決問題能力與經驗也不同,所以很難訓練出所謂的 RenderMan Generalist(RenderMan 通吃的傢伙),而且也不實際,倒不如先專精一件事來得好。

這件事我和 Kesson 聊過,他以老師的身份說了下頭的這麼一段話,指出 RenderMan 教學的難處:

The main problem I often find with students is that they do not understand the importance of what I try to show them or get them to do. We have a saying in England that “you can’t put an old head on young shoulders”. Somehow the students must come to appreciate what they really need to know.

我建議的學習方式是:就先一路由 RIB -> RSL -> front-ends (RMS/MtoR/3Delight For Maya/…) 學起。 最好的方法,就是有個明確的目標,所以你可以第一個月,使用 RenderMan 算出一張“水果盤“,第二個月算出“汽車“,第三個月來個“室內場景“…。這邊我建議直接去拿 Jeremy Birn 的 Lighting Challenges 來使用,然後以他網站上挑選出來的比較好的結果當作目標。

RIB(30%):

首要認識的是 RIB File Structure,亦即 Options, Frame[Begin|End], World[Begin|End], Transform[Begin|End], Resource[Begin|End}, Attribute[Begin|End} 之間的關係。這些 Begin/End 可以類比到 OpenGL 裏使用的堆疊的概念,亦即不管是 transformation 或是 graphics states 都是以 stack 的方式來存取。換另一個說法,就是以 stack 來實作出階層(hierarchy)的架構來,然後整個 rendering scene 可以利用階層來達到分類與資源再利用。比較複雜一點的是,得去了解哪些 block 可以被放在 Transform 裏頭,哪些是要放在 Attribute 裏頭。例如:同一個 Surface “surfaceShader1” 放在 Transform 與 Attribute 裏頭,可能會使得 surfaceShader1 的 shader coordinate 不一樣,在一些 procedural shader 部分會有不同的結果出來。

version 3.04
Option "searchpath" "resource" [".:@"]
FrameBegin 1
Identity 
Attribute "dice" "string strategy" ["planarprojection"]
PixelSamples 3 3
Exposure 1 1
Hider "hidden" "jitter" [1] "float[2] shutteropening" [0 1]
PixelFilter "separable-catmull-rom" 2 2
#Shutter 1 1.25
Shutter 0.0416667 0.0520833
Format 640 480 1
Display "untitled.0001" "it" "rgba" "int merge" [0] 
Projection "perspective" "fov" [54.4322]
ScreenWindow -1 1 -0.75 0.75
ConcatTransform [0.785857 -0.306445 -0.537141 0 4.85723e-17 0.868586 -0.495539 0 -0.618408 -0.389422 -0.682584 0 -9.83211 -11.3704 346.484 1]
WorldBegin 
    Surface "defaultsurface" 
    TransformBegin 
        Attribute "identifier" "string name" ["pointLightShape1"]
        Transform [1 0 0 0 0 1 0 0 0 0 1 0 0 96.8028 0 1]
        LightSource "PointLight" "pointLightShape1" "float intensity" [1] "color lightcolor" [1 1 1] "float decayRate" [0]
    TransformEnd 
    TransformBegin 
        Attribute "identifier" "string name" ["pointLightShape2"]
        Transform [1 0 0 0 0 1 0 0 0 0 1 0 110.316 96.8028 0 1]
        LightSource "PointLight" "pointLightShape2" "float intensity" [1] "color lightcolor" [1 1 1] "float decayRate" [0]
    TransformEnd 
    AttributeBegin 
        ResourceBegin 
        Attribute "identifier" "name" ["|nurbsSphere1|nurbsSphereShape1"]
        ConcatTransform [59.9248 0 0 0 0 59.9248 0 0 0 0 59.9248 0 0 0 0 1]
        Color [0.5 0.5 0.5]
        Opacity [1 1 1]
        Surface "Lambert"
        Sphere 0.15 -0.15 0.15 360
        ResourceEnd 
    AttributeEnd 
WorldEnd 
FrameEnd

接著依如下的順序來一一了解 RIB:

  1. 鏡頭與產生的圖檔大小比例。ex, Camera, Screen, Display, …
  2. 用來指定 transformation 的語法。ex, Transform, ConcatTransform, Translate, …
  3. 用來描述幾合型狀(Geometric Primitives)的語法。ex, GeneralPolygon, SubdivisionMesh, …
  4. 使用 RSL 寫成的 shader。ex, Surface, Displacement, LightSource, …
  5. 影響 Geometric Primitives 的 Graphics State Attributes。
  6. 與最後的 Graphics State Options。ex, dicing strategy, shutter, …

閱讀與研究 RIB 是個非常不自然,很容易讓人放棄或想半途而廢的過程,因為感受不到它的意義與用途。這就好比你在高中時學到的傳統物理學,除了好成績好證明你夠聰明而可以進比較有名的學校外,似乎沒啥屁用。事實上,這一點也是 Kesson 教授傷腦筋的事,而且他也打算重新思考 RenderMan 教學這件事情。

了解 RIB 的規格,主要是在協助你 debug,de 與 shader 無關的 bug。舉凡「shader 一直找不到」、「RibArchive 的座標有問題」、「light linking 好像怪怪的」…等都屬這個範籌。另一方面,透過對 RIB 的了解,你有機會實驗與更加了解 RenderMan architecture 的東西,像是 dicing strategy, dicing camera, shading interpolation, double shaded (or sidedness), …。再更進一步,你可以透過自行撰寫的程式來影響 RIB 檔,做到一些很特別的效果來。像是使用 Procedure “RunProgram” 來把自行撰寫的 progressive LoD 加入。

了解 RIB 的另一個好處是,你有機會丟下那些耗時或煩雜的 RIB exporter(ex, MtoR, RMS, 3Delight for Maya, MayaMan, …),節省時間。舉個例子,你可以執行一次 ribgen 後,然後把 shader parameters 給 bound 到 RIB 裏頭(external in slim),接下來你就直接修改 RIB 檔裏頭的 shader parameters,然後直接對同一個 RIB 檔下 render 來看結果,省去不必要的 ribgen 的時間。

RSL(60%):

RenderMan 這個渲染器最讓人激賞的一點是,它讓你可以以各種方式,要多仔細要多仔細,要多古怪就有多古怪地“描述“一個物件的質感,就像你可以透過 RIB 表示任意一個物件的型狀與位置一樣地…自由。(這說法可能太誇張了,因為我相信現在不會有人手動寫一個 RIB 來描述一個場景裏頭物件的外形才是,應該都是用 Maya 之類的軟體了吧!)The RenderMan Shading Language,簡稱 RSL,是一個特別設計的語言,用來讓你描述一個物件的質感用的。不管你想要的質感訴求是“真實“或是“手繪風格化“~

學習 RSL 這件事並不等同於學習設置一個 shader,這其實可以是兩碼子事的。RSL 本身只是一些技術名詞加一些語法,它被用來設計 shader 用,亦即它是提供一種“可程式化的方式“來讓你設計 shader,但它不是唯一的答案。事實上,一個完整被拿來使用的 material(這裏不用 shader,表示我們在聊一個更 general 的名詞),需要大量的 texture(2D or 3D)介入的。

RSL 大略包含下列幾點:

  • shader evaluation pipeline
  • illumination loop
  • built-in functions
  • texture mapping
  • anti-aliasing
  • displacement/bump shader
  • surface shader
  • light shader
  • volume shader
  • procedural shader
  • coordinate system
  • message passing

其中比較基本(常常,“基本“除了表示簡單以外,同時也有“重要“這一層意思在)的是前三點。shader evaluation pipeline 決定了 surface shader, light shader, displacement shader 與 volume shader 之間的關係(或先後順序),所以你大略會知道一個物件的 displacement shader 會先執行,然後接著是 surface shader,而 light shader 則是 surface shader 的 co-routine。當開啟 ray tracing 後,事情變得稍稍複雜了。依據 ray 是 reflection 或 refraction(transmission) 而使得 volume shader 會有不同的身份(interior shader & exterior shader)。然後如果是 eye ray 的話,volume shader 又以 atmosphere shader 的身份出現。我猜你應該是頭暈了才對,而這也是為什麼我把 volume shader 放在幾乎最後的原因。

當你開始把寫 shader 當成是寫程式時(恭喜你通過 Technical Artists 一職的門檻),那你就進入了 procedural shader 這個領域了。這時你會大量接處到的東西,除了數學上的線性代數(Linear Algebra)、三角學(Trigonometry)加上 RSL 內建的 function(ex, solar(), filterstep()) 以外,你有很高的機會要去接觸 coordinate system 與 message passing,關於這兩點,有不少人寫出(兼提出)很不一樣的 shader,像是 Magic Lights, Tag Lights, Faked SubSurface, …。

既然談到 procedural shader,那我們再多聊聊一下。事實上你很少需要去撰寫 procedural shader,換個說法,一部「沒有玩得太過火」的 animation,80% ~ 90% 的 materials 都是靠常見的 illumination models + textures 完成的,亦即在 surfacing (or even lookdev?) 部門裏頭,最最重要的人員是畫材質的美術人員,他們決定了大部分 shader 的品質與產出的速度(與畫得多快多準成直接的正比)。但當你真的必須使用到 procedural shader 時,工作內容(或 procedural shader 的組成)不出如下三點:

  • pattern generation
  • illumination model
  • layering compositinng

What else?(10%)

  • RMS/MtoR/3Delight for Maya:
    • RibGen
    • Shading network editing/authoring
  • Rendering Time Issues:
    • global illumination
    • statistics file
  • Render farm:
    • job description
    • job delivering
    • job handling

Conclusion

Computer graphics is all about cheating :-) It’s all about the Ancient Chinese Art of ChiTing.

Source:Jim Blinn.

最後來回顧一下文章主題「學習 RenderMan 的一套方法」。我把整個學習的過程大略分成三階段: 1)RIB 2)RSL 3)renderer & others,每一階段旁有個百分比,是估計需要投入的心力(30%, 60%, 10%)。RIB 是用來協助你了解 RenderMan 運算的精髓與 debug 用;RSL 是 RenderMan 最強力的地方(事實上,我非常懷疑有其它的 renderer 可以跟它匹敵的,尤其是拿 PRMan 的 filtering 與 stochastic sampling 來說);其它則是依工作需要而去了解就行。

這裏有一個很有趣的想法。如果把 RIB 想成是「描述模型的語言」,把 RSL 想成是「描述質感的語言」的話,那麼有一件事實你一定要知道:花費在調整質感上的時間,至少要和建模型的時間差不多,而且常常是更多!!這一點在 SIGGRAPH 1992 年 RenderMan 的 course 就已經提出來了,至今仍然如此,而我們在太極影音製作的經驗也相差無幾

Postscript

學習怎麼使用 RenderMan,與其說是學一套軟體(ex, Photomatix),更正確一點來說,是學習它背後的運算邏輯,各式各樣的調校,甚至是它的語法撰寫,與最後的整合應用。RenderMan 實在太複雜了,以至於永遠沒有結束的一天。就好比你在學 Java 時,當你搞懂 Java 的基本語法後,你可以學進階的語法(closure?)、官方函式庫的用法、第三方的 frameworks、與 web server 整合的 JBoss、在 mobile 上跑的特製化 JVM、以它為其礎的圖像語言 Processing、GUI programming: JFC/Swig…因為實在太多了,所以 Java 的書永遠寫不完,即使是寫一些很入門的書都可以每年有新書!!!(再次強調,我一點兒都沒有在扁抑 Java,我只是和它比較不熟而已)

學習 RenderMan,除了工作所需,另一個原因在於它的「集大成」。

透過它,你可以有機會多了解一些 Computer Graphics 界的研究成果;每個演算法被實作出來的樣子;怎麼透過它來渲染出一張張你想要的畫面出來;Subdivision 與 Texture coordinates 有什麼關係;怎麼利用 RenderMan 來讓你的畢業論文有更優的結果;或甚至面對每天遇到的 RenderMan + Maya 問題時,你該如何快速找出原因並解決掉…雖然 RenderMan 裏頭有不少技術都是老技術(相信我,有不少是十幾二十年的東西了),但存活下來有一定的原因與目的(普遍性與穩定性),所以也許對於新技術的探討來說,RenderMan 是個老學究,一點兒也幫不上忙,但對於 CG 的歷史,它鐵定是站在一個非常重要的位置上頭。

comments powered by Disqus

Recent posts

Categories

About

You're looking at Drake's words or statements. All opinions are my own.