RenderManのお勉強(シェーダ言語とは)


シェーディング言語とは

RenderManの特徴的な点はシェーダ(shader)と呼ばれる機能をサポートしていることです。シェーダとは、物体の表面の質感などを計算によって求めるものです。シェーダはRIBファイルよりレンダリング時に呼び出されます。LightSourceによる光源の設定も、光の強さとその色を計算するためのシェーダを割り当てる(attach、アタッタチする)することを意味しています。シェーダには次の5つの種類のものがあります。

  1. 面シェーダ(surface shader):物体表面の質感と、光による影響を計算する。
  2. 光源シェーダ(light shader):光源の照らす方向や色、光量などを制御する。
  3. 変位シェーダ(displacement shader):物体表面の位置や法線ベクトルの向きを変え、物体表面の皺や凹凸などを計算する。
  4. ボリュームシェーダ(volume shader):霧や煙などによる光の変化などを計算する。
  5. イメージャシェーダ(imager shader):表示される直前に画面上の画素の色を変換する。

シェーダはシェーディング言語と呼ばれるプログラミング言語で記述されています。RenderManのシェーディング言語はRSL(Renderman Shading Language)と呼ばれ、C言語に似た文法のプログラミング言語となっています。そして、光や表面の清性質を記述するために、次のようなデータ型や関数などを持っています。

  1. 点、ベクトル、色などを操作するためのデータ型と関数
  2. シェーディングをほどこしている点の位置、法線ベクトル、色、入射光の情報などへのアクセス
  3. 実行時にシェーダに渡されるパラメータなど

はじめの一歩

自分のシェーダを利用するためには、以下のような手順をとります。

  1. シェーディング言語でソースファイルを作成する。
  2. シェーダコンパイラでソースファイルをコンパイルする。
  3. RIBファイル内で、属性としてシェーダを割り与える。
  4. RIBファイルを使ってレンダリングを行う。

RSLファイルの作成

通常、シェーディング言語はエディタを利用して作成します。保存する際にはファイルの拡張子はslとします。slはShading Languageの略だと思います。
エディタとしてemacsを利用する場合には、rslモード用のemacs lispのプログラムがhttp://accad.osu.edu/~smay/RManNotes/rsl_emacs_mod...にあるので、利用すると良いかも知れません。ただし、少し作りかえた方が良いような気もしますが。

RSLファイルのコンパイル

シェーディング言語のソースファイルの拡張子はslとなっていますが、シェーダコンパイラの名称や、コンパイルして出来るファイルの拡張子はシステム毎に異なっています。シェーダコンパイラは、なんらかのバイトコードを生成するシェーダコンパイラが多いようです。

レンダラーシェーダコンパイラ名称生成されるファイルの拡張子
PRManshaderslo
3Delightshaderdlsdl
Airshadedslb
Anglegilesslc
Aqsisaqslslx
jrManjrMan0.4ではシェーディング言語の機能を実装していないようです
Pixiesdrcsdr
RenderDotCshaderdcシステム依存

コンパイルするためには、
シェーダコンパイラ名 ソースファイル名
とします。例えば、Pixieでsample01.slというシェーディング言語のソースファイルをコンパイルするためには、
sdrc sample01.sl
とします。

RSLファイルを書いてみる

シェーダの機能を確認するためには、RSLファイルの他にもRIBファイルも必要となります。しばらくの間は、下のようなRIBファイルを利用することにします。

RSLファイルテスト用RIBファイル(その1)

# sl-sample01.rib:sample rib file for Surface Shader
Display "sl-sample01.tiff" "file" "rgba"  # 出力ファイル名は適当に変える
Projection "perspective" 
Translate 0 0 2	 
WorldBegin
	LightSource "ambientlight" 1
	"intensity" [0.2]
	LightSource "spotlight" 2
	"from" [2 2 -2]
	"to" [0 0 0]
	"intensity" [5]
	Color [1 0 0]
	Surface "plastic"  # 割り当てるシェーダ名は適時変更する、この場合はplasticシェーダを割り当てている。
	Sphere 1 -1 1 360
WorldEnd

RSLファイルテスト用RIBファイル(その1)のレンダリング結果



初めてのRSLファイル(ファイル名sample01.sl)

/* A sample shader */      # (1)
surface sample01(){          # (2)
	Oi = Os;                      # (3)
	Ci = Cs*Oi;                  # (4)
}

初めてのRSLファイルのレンダリング結果



このレンダリング結果を得るためには、
  1. RSLファイルsample01.slをエディタで作成する。
  2. シェーダコンパイラを利用して、sample01.slをコンパイルする。Aqsisの場合には”aqsl sample01.sl”、Pixieの場合には"sdrc sample01.sl"とする。
  3. RIBファイルsl-sample01.ribをエディタで作成する。ただし、割り当てるシェーダ名はsample01に変更する。
  4. レンダリングを実行。

初めてのRSLファイルの説明

  1. RenderManのシェーディング言語の文法はC言語の文法に似ていますので、C言語を知っている人はおおよそ何をやろうとしているのかわかると思います。
  2. (1)はコメント文です。/*と*/で囲まれた間がコメントとなっています。
  3. (2)最初のsurfaceは、この関数が面シェーダであること示しており、その次に単語がシェーダ名を示しています。この場合は、sample01というシェーダ名という面シェーダであることを示しています。sample01の直後の"()"は、この引数(パラメータ)をとらないシェーダとなっていることを示しています。
  4. RSLでは、様々な大域変数が定義されています。これらの大域変数は、レンダラーがシェーダを呼び出す際に適切な値に設定します。(3)に現れているOiやOsがそれらの一部です。OsとOiは不透明度を表す情報で、Osは物体表面にOpacity命令によって設定された情報が渡されています。また、Oiはこのシェーダによって新たに計算された不透明度となります。このシェーダでは、"Oi=Os"としているので、Osの値がそのままこのシェーダによって新たに計算された不透明度となっています。
  5. (4)に現れているCsとCiは物体表面の色を表す情報で、Csは物体表面にColor命令によって設定された情報が渡されています。また、Ciはこのシェーダによった新たに計算された物体表面の色の情報となります。"Ci = Cs*Oi"となっているので、物体表面の色Ciに物体表面の不透明度Oiを掛け合わせたものを、新たな物体表面の色としています。
  6. このsample01シェーダを利用する場合には、RSLファイルテスト用RIBファイル(その1)の「Surface "plastic"」を「Surface "sample01"」に変更します。これによって割り当てられている面シェーダがplasticからsample01に変更されます。
  7. ここで定義した面シェーダsample01は、普通constantと呼ばれている面シェーダです。

強制色設定色シェーダ(?)

面シェーダによって、物体表面の色の見え方を変更することができます。そこで、Color命令によって設定された色を無視して、常にある色によって表示されるような面シェーダを書いてみることにします。

RSLファイル

/* 物体表面の色の見え方を常に青にする */
surface sample01a(){
	Oi = Os;
	Ci = (color "rgb" (0,0,1))*Oi;
}

レンダリング結果



説明

  1. このsample01aシェーダを利用する場合には、RSLファイルテスト用RIBファイル(その1)の「Surface "plastic"」を「Surface "sample01a"」に変更します。
  2. シェーディング言語の中では、「color "rgb" (赤,緑,青)」によってRGB値よって色を表すことができます。ここでは、「color "rgb" (0,0,1)」が青を表していることを使って、「Ci = (color "rgb" (0,0,1))*Oi」によって、青色に不透明度をかけたものが物体表面の色として見えるようにしています。このため、Color命令のよる設定は無視されます。

シェーディング言語で利用できる大域変数

シェーダ毎に利用できる大域変数は変わってきます。例えば、面シェーダでは面の色に関わるCsやCiなどは利用できますが、変位シェーダでは利用できません。また、面上の法線ベクトルを示している大域変数Nは、面シェーダと変位シェーダの両方で利用することが出来ます。この大域変数Nは変位シェーダでは変更することが出来ますが、面シェーダでは変更することはできません。こららの状況をまとめたものが下の表です。Rは読み出し可能、Wは変更可能、RWは読み出しと変更の両方が可能となっていることを示しています。

大域変数名DisplacementSurfaceLightVolume役割
P RW RW R R ワールド座標でのシェーディングされる面上の点の座標
N RW R - - シェーディングされる面上の点Pでの法線ベクトル
u,v R R - - 面のパラメータ座標
du,dv R R - - パラメター位置u,vでの座標変化
s,t R R - - 面のテクスチャ座標
E R R R R 視点位置
I R R - R 視線ベクトル(視点位置からシェーディングされる面上の点への方向を表すベクトル)
L - R R r 光線ベクトル(シェーディングされる面上から光源方向のベクトル)
Cs - R - - 面の色(入力)
Ci - W - RW 面の色(出力)
Os - R - - 面の不透明度(入力)
Oi - W - RW 面の不透明度(出力)
Cl - R RW r 光源の色
2008年03月09日(日) 14:54:57 Modified by m_riho

添付ファイル一覧(全3件)
da286e13.jpg (5.83KB)
Uploaded by m_riho 2008年02月03日(日) 00:59:55
dae162ef.jpg (10.34KB)
Uploaded by m_riho 2008年02月03日(日) 00:16:00
98a2127f.jpg (10.41KB)
Uploaded by m_riho 2008年02月03日(日) 00:10:00



スマートフォン版で見る

×

この広告は60日間更新がないwikiに表示されております。