1/4 >>

PythonからRenderManを使う その1

RenderManはC APIで記述されているが、cgkitと3Delightを使えば、次のように球体を表示、レンダリングできます。
本来ならば、C言語を使ってコンパイルしてやりますが、Python良いですね。便利です。

以下はcgkitを使って3Delightで直接レンダリングしました。3DelightのLibフォルダの3Delight.libが働いてくれます。


#min.py
import cgkit.cri

ri = cgkit.cri.loadRI("3Delight")
cgkit.cri.importRINames(ri, globals())

RiBegin(RI_NULL)
RiDisplay("min.tif", RI_FRAMEBUFFER, RI_RGB)
RiProjection(RI_PERSPECTIVE)
RiTranslate(0,0,1.5)
RiWorldBegin()
RiLightSource("ambientlight","intensity",0.4)
RiLightSource("distantlight")
RiSurface("plastic")
RiColor((1,0.2,0.2))
RiSphere(1,-1,1,360)
RiWorldEnd()
RiEnd()



ri = cgkit.cri.loadRI("3Delight")の部分を
オープンソースRenderMan互換レンダラのAqsis Renderer1.6を使用するならば、


ri = cgkit.cri.loadRI("aqsis_ri2rib")


コマンドプロンプトから、
>min.py
と打ち込むと、RIBが生成されて表示されるだけです。
なので、パイプを使います。こんな感じ・・
>min.py |aqsis

prmanの場合も、cgkitを使う場合は、
ri = cgkit.cri.loadRI("libprman")
>min.py |prman
となります。直接レンダリングではないので、
RenderManProServer-14からついているimport prmanを利用します。


# set PYTHONPATH=C:\Python25;C:\Python\Scripts;%RMANTREE%\bin
#min_pr.py
import prman
ri=prman.Ri()
rendertarget="min_pr.rib"
ri.Begin(ri.RENDER)
ri.Imager("background", {"color color":(.2,.4,.6)})
ri.Display("min_pr.tif", "framebuffer", "rgb")
ri.Format(640,480,1)
ri.Projection(ri.PERSPECTIVE, {ri.FOV: 90})
ri.Translate(0,0,1.5)
ri.WorldBegin()
ri.LightSource("distantlight", {ri.HANDLEID: "1"})
ri.LightSource("ambientlight", {ri.HANDLEID: "2", "intensity":[0.4]})
ri.Color((1,0.2,0.2))
ri.Surface("plastic")
ri.Sphere(1,-1,1,360)
ri.WorldEnd()
ri.End()


>min.pyと打ち込む前に
>set PYTHONPATH=C:\Python25;C:\Python\Scripts;%RMANTREE%\bin
でパスを通しておきます。
以下はレンダリング結果。
min_pr.jpg
  • -
  • -

「実践CGへの誘い」例題をPythonで行う その1

「実践CGへの誘い」p.18
Listing 2.1

cgkitと3Delightを使って
Python APIによるRenderManのシーン記述です。
4角形の表示です。



#list21.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 18 */
#/* Listing 2.1 A minimal program using RenderMan */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

square=[.5,.5,.5,.5,-.5,.5,-.5,-.5,.5,-.5,.5,.5]

RiBegin(RI_NULL)
RiFormat(640,480,1)
RiDisplay("list21.tif", RI_FRAMEBUFFER, RI_RGB)
#RiPixelSamples(3,3)
#RiProjection(RI_ORTHOGRAPHIC)
#RiScale(vec3(0.8))
#RiTranslate(0,0.55,5)
RiWorldBegin()
RiSurface("constant",RI_NULL)
RiPolygon(P=square)
RiWorldEnd()
RiEnd()


コマンドプロンプトから
>list21.py
と打ち込むと3delightでレンダリングして表示されます。
はじめの一歩ですね。
  • -
  • -

「実践CGへの誘い」例題をPythonで行う その2

「実践CGへの誘い」p.20
Listing 2.2




#list22.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 20 */
#/* Listing 2.2 Control over viewer and color */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

square=[.5,.5,.5,.5,-.5,.5,-.5,-.5,.5,-.5,.5,.5]

color=(.2,.4,.6)

RiBegin(RI_NULL)
RiLightSource("distantlight",RI_NULL)
RiProjection(RI_PERSPECTIVE)
RiTranslate(0.0,0.0,1.0)
RiRotate(40,-1,1,0)
RiDisplay("list22.tif", RI_FRAMEBUFFER, RI_RGB)
RiWorldBegin()
RiColor(color)
RiSurface("constant",RI_NULL)
RiPolygon(P=square)
RiWorldEnd()
RiEnd()

  • -
  • -

「実践CGへの誘い」例題をPythonで行う その3

「実践CGへの誘い」p.25
Listing 2.3
list23.jpg


#list23.py
# Copyrighted Pixar 1989
# From the RenderMan Companion p. 25
# Listing 2.3 Control over viewer and color

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

L= -.5 #* For x: left side */
R= .5 # /* For x: right side */
D= -.5 # /* For y: down side */
U= .5 # /* For y: upper side */
F= .5 # /* For z: far side */
N= -.5 # /* For z: near side */

#/* UnitCube(): define a cube in the graphics environment */
def UnitCube():
Cube=[
[ [L,D,F], [L,D,N], [R,D,N], [R,D,F] ], #/* Bottom face */
[ [L,D,F], [L,U,F], [L,U,N], [L,D,N] ], #/* Left face */
[ [R,U,N], [L,U,N], [L,U,F], [R,U,F] ], #/* Top face */
[ [R,U,N], [R,U,F], [R,D,F], [R,D,N] ], #/* Right face */
[ [R,D,F], [R,U,F], [L,U,F], [L,D,F] ], #/* Far face */
[ [L,U,N], [R,U,N], [R,D,N], [L,D,N] ] #/* Near face */
];
for i in range(6):
RiPolygon(P=Cube[i])


#square=[.5,.5,.5,.5,-.5,.5,-.5,-.5,.5,-.5,.5,.5]

color=(.2,.4,.6)

RiBegin(RI_NULL)
RiDisplay("list23.tif", RI_FRAMEBUFFER, RI_RGB)
RiFormat(640,480, -1.0)
RiShadingRate(1.0)
RiLightSource("distantlight", RI_NULL)
RiProjection(RI_PERSPECTIVE)
RiWorldBegin()
RiTranslate(0.0, 0.0, 1.5)
RiRotate(40.0, -1.0, 1.0, 0.0)
RiSurface("matte",RI_NULL)
RiColor(color)
UnitCube()
#RiPolygon(P=square)
RiWorldEnd()
RiEnd()

  • -
  • -

PythonからRenderManを使う その2

Pixar RenderManのPython APIとcgkitでの記述を並べてみた。
import prmanでは、パラメータを辞書形式で記述。後はほとんど同じ感じてす。
以下は、ティーポットの表示
■import prman


#test2.py
# set PYTHONPATH=C:\Python25;C:\Python\Scripts;%RMANTREE%\bin
import prman
ri=prman.Ri()
rendertarget="test2.rib"
ri.Begin(ri.RENDER)
ri.Imager("background", {"color color":(.2,.4,.6)})
ri.Display("teapot2.png", "file", "rgb")
ri.Format(640,480,1)
ri.Projection(ri.PERSPECTIVE, {ri.FOV: 45})
ri.Translate(0,0,10)
ri.WorldBegin()
ri.LightSource("pointlight", {ri.HANDLEID: "1", "from": [-10,10,-10],"intensity":[300]})
ri.LightSource("pointlight", {ri.HANDLEID: "2", "from": [10,10,-10],"intensity":[300]})
ri.LightSource("pointlight", {ri.HANDLEID: "3", "from": [-10,-10,-10],"intensity":[300]})
ri.Color((0.9,0,0.1))
ri.Surface("plastic")
ri.Translate(0,-1,0)
ri.Rotate(-90,1,0,0)
ri.Geometry("teapot")
ri.WorldEnd()
ri.End()


teapot2.jpg

■cgkit
3Delightを利用した。


#min2.py
import cgkit.cri

ri = cgkit.cri.loadRI("3Delight")
cgkit.cri.importRINames(ri, globals())

RiBegin(RI_NULL)
RiImager("background", "color background",(.2,.4,.6))
RiDisplay("min2.png", RI_FILE, RI_RGB)
RiProjection(RI_PERSPECTIVE,RI_FOV,45)
RiTranslate(0,0,10)
RiWorldBegin()
#RiLightSource("ambientlight","intensity",0.4)
#RiLightSource("distantlight")
RiLightSource("pointlight", RI_HANDLEID, "1", "from",[-10,10,-10],"intensity",[300])
RiLightSource("pointlight", RI_HANDLEID, "2", "from",[10,10,-10],"intensity",[300])
RiLightSource("pointlight", RI_HANDLEID, "3", "from",[-10,-10,-10],"intensity",[300])
RiSurface("plastic")
RiColor((1,0.2,0.2))
RiTranslate(0,-1,0)
RiRotate(-90,1,0,0)
RiReadArchive("teapot.rib")
RiWorldEnd()
RiEnd()


min2.jpg
  • -
  • -

「実践CGへの誘い」例題をPythonで行う その4

「実践CGへの誘い」p.28
Listing 2.5
TransformBegin()〜TransformEnd()を使ったサンプル
ありがたいです。



#list25.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 28 */
#/* Listing 2.5 Another cube definition */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

#/* UnitCube(): Enter a unit cube into the scene */

def UnitCube():
square = [ [.5,.5,.5], [-.5,.5,.5], [-.5,-.5,.5], [.5,-.5,.5] ]
RiTransformBegin()
#/* far square */
RiPolygon( RI_P, square, RI_NULL)
#/* right face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
#/* near face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
#/* left face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

RiTransformBegin()
#/* bottom face */
RiRotate(90.0, 1.0, 0.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

RiTransformBegin()
#/* top face */
RiRotate(-90.0, 1.0, 0.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

color=(.9,.1,.2)

RiBegin(RI_NULL)
RiDisplay("list25.tif", RI_FRAMEBUFFER, RI_RGB)
RiFormat(640,480, -1.0)
RiShadingRate(1.0)
RiLightSource("distantlight", RI_NULL)
RiProjection(RI_PERSPECTIVE)
RiWorldBegin()
RiTranslate(0.0, 0.0, 1.5)
RiRotate(40.0, -1.0, 1.0, 0.0)
RiSurface("matte",RI_NULL)
RiColor(color)
UnitCube()
RiWorldEnd()
RiEnd()


  • -
  • -

「実践CGへの誘い」例題をPythonで行う その5

「実践CGへの誘い」p.30
Listing 2.6
cgkitを使ってPython APIによるRenderManeインタフェースの勉強です。今回は、色つき立方体の生成です。面白いですね。
レンダリングは、3Delightを使っています。さらに、勉強していきます。ありがとうございます。

colormain.jpg



#list26.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 30 */
#/* Listing 2.6 Defining a larger cube from smaller minicubes */
#/*
# * ColorCube(): create a unit color cube from smaller cubes
# * Parameters:
# * n: the number of minicubes on a side
# * s: a scale factor for each minicube
# */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

#/* UnitCube(): Enter a unit cube into the scene */

def ColorCube(n, s):
if n<=0:
return

RiAttributeBegin()
RiTranslate(-.5, -.5, -.5 )
RiScale(1.0/n, 1.0/n, 1.0/n)
color=[0,0,0]
for x in range(n):
for y in range(n):
for z in range(n):
color[0] = (x+1)/float(n)
color[1] = (y+1)/float(n)
color[2] = (z+1)/float(n)
RiColor(color)
RiTransformBegin()
RiTranslate (x+.5, y+.5, z+.5)
RiScale(s, s, s)
UnitCube()
RiTransformEnd ()


RiAttributeEnd();


def UnitCube():
square = [ [.5,.5,.5], [-.5,.5,.5], [-.5,-.5,.5], [.5,-.5,.5] ]
RiTransformBegin()
#/* far square */
RiPolygon( RI_P, square, RI_NULL)
#/* right face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
#/* near face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
#/* left face */
RiRotate(90.0, 0.0, 1.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

RiTransformBegin()
#/* bottom face */
RiRotate(90.0, 1.0, 0.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

RiTransformBegin()
#/* top face */
RiRotate(-90.0, 1.0, 0.0, 0.0)
RiPolygon( RI_P, square, RI_NULL)
RiTransformEnd()

color = ( .2, .4, .6 )

RiBegin(RI_NULL); #/* Start the renderer */
RiDisplay("colormain.tiff", RI_FILE, "rgb", RI_NULL)
RiFormat(512, 384, -1.0)
RiShadingRate(1.0)
RiLightSource("distantlight", RI_NULL)
RiProjection(RI_PERSPECTIVE,RI_FOV,65)
RiWorldBegin()
RiSides(1) # /* N E W */
RiTranslate(0.0, 0.0, 1.5)
RiRotate(30.0, -1.0, 0.0, 0.0)
RiRotate(30.0, 0.0, -1.0, 0.0)
RiColor(color) # /* Declare the color */
ColorCube(4, .8) #/* Define the cube */
RiWorldEnd()
RiEnd() #/* Clean up after the renderer */



  • -
  • -

「実践CGへの誘い」例題をPythonで行う その6

「実践CGへの誘い」p.31
Listing 2.7


>list27.py
オブジェクトインスタンスを利用しようと組んだら、以下のエラー
3DL ERROR P1051: [C:0]: invalid context for 'RiTransformBegin'
3DL ERROR P1051: [C:0]: invalid context for 'RiRotate'
3DL ERROR P1051: [C:0]: invalid context for 'RiTransformEnd'

いろいろと調べたら、cgkitでは、
obj = RiObjectBegin()
RiSphere(0.5,-0.5,0.5,360)
RiObjectEnd()
RiObjectInstance(obj)

と記述しているが、これは問題ない。

cube = RiObjectBegin()
UnitCube()
RiObjectEnd()
問題は、UnitCube()
「実践CGへの誘い」によれば、物体の記述に、ジオメトリ変換を記入していると無視される。よってUnitCube()は、一番最初にやった面のみを記述する定義を用いる。
  • -
  • -

「実践CGへの誘い」例題をPythonで行う その7

できました。よく読まないといけません。
UnitCube()を最初に使った定義のものに戻しています。

「実践CGへの誘い」p.32
Listing 2.7

オブジェクトインスタンスを利用したサンプルです。
ありがとうございます。


#list27.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 32 */
#/* Listing 27c A more efficient color cube */
#/*
# * ColorCube(): create a unit color cube from smaller cubes
# * Parameters:
# * n: the number of minicubes on a side
# * s: a scale factor for each minicube
# */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

L= -.5 #* For x: left side */
R= .5 # /* For x: right side */
D= -.5 # /* For y: down side */
U= .5 # /* For y: upper side */
F= .5 # /* For z: far side */
N= -.5 # /* For z: near side */

#/* UnitCube(): define a cube in the graphics environment */
def UnitCube():
Cube=[
[ [L,D,F], [L,D,N], [R,D,N], [R,D,F] ], #/* Bottom face */
[ [L,D,F], [L,U,F], [L,U,N], [L,D,N] ], #/* Left face */
[ [R,U,N], [L,U,N], [L,U,F], [R,U,F] ], #/* Top face */
[ [R,U,N], [R,U,F], [R,D,F], [R,D,N] ], #/* Right face */
[ [R,D,F], [R,U,F], [L,U,F], [L,D,F] ], #/* Far face */
[ [L,U,N], [R,U,N], [R,D,N], [L,D,N] ] #/* Near face */
];
for i in range(6):
RiPolygon(P=Cube[i])

def ColorCube(n, s):
if n<=0:
return

cube = RiObjectBegin()
UnitCube()
RiObjectEnd()

RiAttributeBegin()
RiTranslate(-.5, -.5, -.5 )
RiScale(1.0/n, 1.0/n, 1.0/n)
color=[0,0,0]
for x in range(n):
for y in range(n):
for z in range(n):
color[0] = (x+1)/float(n)
color[1] = (y+1)/float(n)
color[2] = (z+1)/float(n)
RiColor(color)
RiTransformBegin()
RiTranslate (x+.5, y+.5, z+.5)
RiScale(s, s, s)
RiObjectInstance(cube)
RiTransformEnd()

RiAttributeEnd()


color = ( .2, .4, .6 )

RiBegin(RI_NULL); #/* Start the renderer */
RiDisplay("colormain2.tiff", RI_FILE, "rgb", RI_NULL)
RiFormat(512, 384, -1.0)
RiShadingRate(1.0)
RiLightSource("distantlight", RI_NULL)
RiProjection(RI_PERSPECTIVE,RI_FOV,65)
RiWorldBegin()
RiSides(1) # /* N E W */
RiTranslate(0.0, 0.0, 1.5)
RiRotate(30.0, -1.0, 0.0, 0.0)
RiRotate(30.0, 0.0, -1.0, 0.0)
RiColor(color) # /* Declare the color */
ColorCube(4, .8) #/* Define the cube */
RiWorldEnd()
RiEnd() #/* Clean up after the renderer */


  • -
  • -

「実践CGへの誘い」例題をPythonで行う その8

■簡単なアニメーション
60フレーム出力してみました。
「実践CGへの誘い」p.34
Listing 2.8を改良しました。
Python便利ですね。
ありがとうございます。



#list28change.py
#/* Copyrighted Pixar 1989 */
#/* From the RenderMan Companion p. 34 */
#/* Listing 2.8 A simple animation */
#/*
# * ColorCube(): create a unit color cube from smaller cubes
# * Parameters:
# * n: the number of minicubes on a side
# * s: a scale factor for each minicube
# */

import cgkit.cri
from cgkit.cgtypes import *

# Load the RenderMan API.
# Replace the library name with whatever renderer you want to use.
ri = cgkit.cri.loadRI("3delight")
cgkit.cri.importRINames(ri, globals())

L= -.5 #* For x: left side */
R= .5 # /* For x: right side */
D= -.5 # /* For y: down side */
U= .5 # /* For y: upper side */
F= .5 # /* For z: far side */
N= -.5 # /* For z: near side */

#/* UnitCube(): define a cube in the graphics environment */
def UnitCube():
Cube=[
[ [L,D,F], [L,D,N], [R,D,N], [R,D,F] ], #/* Bottom face */
[ [L,D,F], [L,U,F], [L,U,N], [L,D,N] ], #/* Left face */
[ [R,U,N], [L,U,N], [L,U,F], [R,U,F] ], #/* Top face */
[ [R,U,N], [R,U,F], [R,D,F], [R,D,N] ], #/* Right face */
[ [R,D,F], [R,U,F], [L,U,F], [L,D,F] ], #/* Far face */
[ [L,U,N], [R,U,N], [R,D,N], [L,D,N] ] #/* Near face */
];
for i in range(6):
RiPolygon(P=Cube[i])

def ColorCube(n, s):
if n<=0:
return

cube = RiObjectBegin()
UnitCube()
RiObjectEnd()

RiAttributeBegin()
RiTranslate(-.5, -.5, -.5 )
RiScale(1.0/n, 1.0/n, 1.0/n)
color=[0,0,0]
for x in range(n):
for y in range(n):
for z in range(n):
color[0] = (x+1)/float(n)
color[1] = (y+1)/float(n)
color[2] = (z+1)/float(n)
RiColor(color)
RiTransformBegin()
RiTranslate (x+.5, y+.5, z+.5)
RiScale(s, s, s)
RiObjectInstance(cube)
RiTransformEnd()

RiAttributeEnd()


color = ( .2, .4, .6 )

NFRAMES = 60 #/* number of frames in the animation */
NCUBES = 5 #/* # of minicubes on a side of the color cube */
FRAMEROT = 3.0 #/* # of degrees to rotate cube between frames */


RiBegin(RI_NULL) #/* Start the renderer */
frame = 1
for frame in range(frame,NFRAMES+1):
if len(str(frame))==1:
print "anim00"+"%d.tif" % frame
filename="anim00"+"%d.tif" % frame
elif len(str(frame))==2:
print "anim0"+"%d.tif" % frame
filename="anim0"+"%d.tif" % frame
else:
print "anim%d.tif" % frame
filename="anim%d.tif" % frame

RiFrameBegin(frame)
RiLightSource("distantlight", RI_NULL)
#/* Viewing transformation */
RiProjection("perspective", RI_NULL)
RiTranslate(0.0, 0.0, 1.5)
RiRotate(40.0, -1.0, 1.0, 0.0)

RiDisplay(filename, RI_FILE, RI_RGBA, RI_NULL)
RiFormat(512, 384, -1.0)
RiShadingRate(1.0)
RiWorldBegin()
RiSides(1); #/* N E W */
scale = (NFRAMES-(frame-1)) / float(NFRAMES)
RiRotate(FRAMEROT*frame, 0.0, 0.0, 1.0)
RiSurface("matte", RI_NULL)
ColorCube(NCUBES, scale) #/* Define the cube */
RiWorldEnd()
RiFrameEnd()

RiEnd()



出力画像はこちらを参考にしてください。
  • -
  • -

1/4 >>