Rendering学習日記

日々3DCGの世界は進歩しているけど、勉強して理解したことをまとめていきたい。RenderMan互換レンダラーやグローバル・イルミネーション。いろんなことに好奇心を持ち面白くなってくる。目指せShader書き!!

はじめてのFujiyama Renderer その29

Fujiyama Renderer 0.2.1がリリースされました。既にmulti threadsでのレンダリングで速くなっている。
バンプ・マッピングができるようになりました。
bump_mapping.jpg
sphere_uv.plyを利用してます。TextureはFujiyama RendererのDownloadsからのリンクを利用しました。以下はPython APIを利用、例です。ありがとうございます。


#!/usr/bin/env python

# 4 textured spheres with 1 dome light with an HDRI
# Copyright (c) 2011-2013 Hiroshi Tsubokawa

import fujiyama

si = fujiyama.SceneInterface()

#Plugins
si.OpenPlugin('ConstantShader')
si.OpenPlugin('PlasticShader')

#Camera
si.NewCamera('cam1', 'PerspectiveCamera')
si.SetProperty3('cam1', 'translate', 0, 0, 10)

# Rotation of dome light and dome object used for background iamge.
rot = 110

#Texture
si.NewTexture('env_tex1', '../mip/pisa.mip')
si.NewTexture('rock_tex1', '../mip/rock.mip')
si.NewTexture('rust_tex1', '../mip/rust.mip')
si.NewTexture('concrete_tex1', '../mip/concrete.mip')
si.NewTexture('pattern_tex1', '../mip/pattern.mip')

#Light
si.NewLight('light1', 'DomeLight')
si.SetProperty3('light1', 'rotate', 0, rot, 0)
# You chang the number of samples on the env map. the default is 16.
#si.SetProperty1('light1', 'sample_count', 256)
si.SetProperty1('light1', 'sample_count', 32)
si.AssignTexture('light1', 'environment_map', 'env_tex1');

#Shader
si.NewShader('sphere_shader1', 'PlasticShader')
si.AssignTexture('sphere_shader1', 'diffuse_map', 'rock_tex1')
si.AssignTexture('sphere_shader1', 'bump_map', 'rock_tex1')
si.SetProperty1('sphere_shader1', 'bump_amplitude', 1)

si.NewShader('sphere_shader2', 'PlasticShader')
si.AssignTexture('sphere_shader2', 'diffuse_map', 'rust_tex1')
si.AssignTexture('sphere_shader2', 'bump_map', 'rust_tex1')
si.SetProperty1('sphere_shader2', 'bump_amplitude', 1)

si.NewShader('sphere_shader3', 'PlasticShader')
si.AssignTexture('sphere_shader3', 'diffuse_map', 'concrete_tex1')
si.AssignTexture('sphere_shader3', 'bump_map', 'concrete_tex1')
si.SetProperty1('sphere_shader3', 'bump_amplitude', 1)

si.NewShader('sphere_shader4', 'PlasticShader')
si.AssignTexture('sphere_shader4', 'diffuse_map', 'pattern_tex1')
si.AssignTexture('sphere_shader4', 'bump_map', 'pattern_tex1')
si.SetProperty1('sphere_shader4', 'bump_amplitude', -1)

si.SetProperty3('sphere_shader4', 'diffuse', .5, .5, .5)
si.SetProperty1('sphere_shader4', 'ior', 10)

si.NewShader('dome_shader', 'ConstantShader')
si.AssignTexture('dome_shader', 'texture', 'env_tex1')

#Mesh
si.NewMesh('sphere_mesh', '../mesh/sphere_uv.mesh')
si.NewMesh('dome_mesh', '../mesh/dome.mesh')

#ObjectInstance
si.NewObjectInstance('sphere1', 'sphere_mesh')
si.SetProperty3('sphere1', 'translate', -1.7, 1.2, 0)
si.AssignShader('sphere1', 'sphere_shader1')

si.NewObjectInstance('sphere2', 'sphere_mesh')
si.SetProperty3('sphere2', 'translate', 1.7, 1.2, 0)
si.SetProperty3('sphere2', 'rotate', 0, 20, 0)
si.AssignShader('sphere2', 'sphere_shader2')

si.NewObjectInstance('sphere3', 'sphere_mesh')
si.SetProperty3('sphere3', 'translate', -1.7, -1.2, 0)
si.SetProperty3('sphere3', 'rotate', 0, 20, 0)
si.AssignShader('sphere3', 'sphere_shader3')

si.NewObjectInstance('sphere4', 'sphere_mesh')
si.SetProperty3('sphere4', 'translate', 1.7, -1.2, 0)
si.AssignShader('sphere4', 'sphere_shader4')

si.NewObjectInstance('dome1', 'dome_mesh')
si.SetProperty3('dome1', 'rotate', 0, rot, 0)
si.SetProperty3('dome1', 'scale', -.5, .5, .5)
si.AssignShader('dome1', 'dome_shader')

#ObjectGroup
# Create shadow_target for sphere1.
# Since 'DomeLight' has infinite distance, we need to exclude
# 'dome1' object which is for just background image.
si.NewObjectGroup('shadow_target1')
si.AddObjectToGroup('shadow_target1', 'sphere1')
si.AssignObjectGroup('sphere1', 'shadow_target', 'shadow_target1')
# and each sphere reacts to only 'dome1' and itself, not to the other spheres
si.NewObjectGroup('reflect_target1')
si.AddObjectToGroup('reflect_target1', 'dome1')
si.AddObjectToGroup('reflect_target1', 'sphere1')
si.AssignObjectGroup('sphere1', 'reflect_target', 'reflect_target1')

si.NewObjectGroup('shadow_target2')
si.AddObjectToGroup('shadow_target2', 'sphere2')
si.AssignObjectGroup('sphere2', 'shadow_target', 'shadow_target2')
si.NewObjectGroup('reflect_target2')
si.AddObjectToGroup('reflect_target2', 'dome1')
si.AddObjectToGroup('reflect_target2', 'sphere2')
si.AssignObjectGroup('sphere2', 'reflect_target', 'reflect_target2')

si.NewObjectGroup('shadow_target3')
si.AddObjectToGroup('shadow_target3', 'sphere3')
si.AssignObjectGroup('sphere3', 'shadow_target', 'shadow_target3')
si.NewObjectGroup('reflect_target3')
si.AddObjectToGroup('reflect_target3', 'dome1')
si.AddObjectToGroup('reflect_target3', 'sphere3')
si.AssignObjectGroup('sphere3', 'reflect_target', 'reflect_target3')

si.NewObjectGroup('shadow_target4')
si.AddObjectToGroup('shadow_target4', 'sphere4')
si.AssignObjectGroup('sphere4', 'shadow_target', 'shadow_target4')
si.NewObjectGroup('reflect_target4')
si.AddObjectToGroup('reflect_target4', 'dome1')
si.AddObjectToGroup('reflect_target4', 'sphere4')
si.AssignObjectGroup('sphere4', 'reflect_target', 'reflect_target4')

#FrameBuffer
si.NewFrameBuffer('fb1', 'rgba')

#Renderer
si.NewRenderer('ren1')
si.AssignCamera('ren1', 'cam1')
si.AssignFrameBuffer('ren1', 'fb1')
si.SetProperty2('ren1', 'resolution', 640, 480)
#si.SetProperty2('ren1', 'resolution', 160, 120)

#Rendering
si.RenderScene('ren1')

#Output
si.SaveFrameBuffer('fb1', '../bump_mapping.fb')

#Run commands
si.Run()
#si.Print()


他、Point Cloudsを試しました。こちらもサンプルPython APIを利用してます。
point_cloud.jpg
Fujiyama Renderer | - | -

Guile RMan #11 くりかえし処理その4

sin、cosを利用した。半径1の円周上に球体を12個、配置した。
色は乱数を発生させた。
sphere8.jpg
sphere8r.jpg


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "test8.rib")
(RiDisplay "sphere8.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 40.0))
(RiTranslate 0 0 4)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2
"uniform point from" (Point 3 3 -3)))

(define (test x)
(define N1 12)
(define PI 3.141592)
(set! *random-state* (random-state-from-platform))
(let ((n 0))
(while (< n x)
(RiTransformBegin)
(RiTranslate (sin (* 2 (/ PI N1) n)) (cos (* 2 (/ PI N1) n)) 0 )
(RiColor (Color (random 1.0) (random 1.0) (random 1.0)))
(RiSurface "plastic")
(RiSphere 0.25 -0.25 0.25 360)
(set! n (+ n 1))
(RiTransformEnd)
)))

(test 12)

(RiWorldEnd)
(RiEnd)

RenderMan | - | -

Guile RMan #10 くりかえし処理その3

guileで乱数を発生させた。毎回変化させるには、
(set! *random-state* (random-state-from-platform))
を記述しておいた。
(RiColor (Color (random 1.0) (random 1.0) (random 1.0)))
たぶん、0から1までの乱数と思われる。
sphere7r.jpg
sphere7r2.jpg


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "test7.rib")
(RiDisplay "sphere7.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 40.0))
(RiTranslate 0 0 6)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2
"uniform point from" (Point 3 3 -3)))

(define (test x)
(define posx -3)
(set! *random-state* (random-state-from-platform))
(let ((n 0))
(while (< n x)
(RiTransformBegin)
(set! posx (+ posx 1 ))
(RiTranslate posx 0 0 )
(RiColor (Color (random 1.0) (random 1.0) (random 1.0)))
(RiSurface "plastic")
(RiSphere 0.5 -0.5 0.5 360)
(set! n (+ n 1))
(RiTransformEnd)
)))

(test 5)

(RiWorldEnd)
(RiEnd)

RenderMan | - | -

Guile RMan #9 くりかえし処理その2

球体の色を徐々に変化させてみた。
guile-rmanとAqsis1.6 (CentOS6.4 64bitで稼働。)
sphere70.jpg


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "test7.rib")
(RiDisplay "sphere7.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 40.0))
(RiTranslate 0 0 6)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2
"uniform point from" (Point 3 3 -3)))

(define (test x)
(define posx -3)
(define col 0.2)
(define col2 0.9)
(let ((n 0))
(while (< n x)
(RiTransformBegin)
(set! posx (+ posx 1 ))
(RiTranslate posx 0 0 )
(set! col (+ col .2))
(set! col2 (- col2 .2))
(RiColor (Color col .2 col2))
(RiSurface "plastic")
(RiSphere 0.5 -0.5 0.5 360)
(set! n (+ n 1))
(RiTransformEnd)
)))

(test 5)

(RiWorldEnd)
(RiEnd)

RenderMan | - | -

Guile RMan #8 くりかえし処理その1

関数を定義し、繰り返し処理を行いました。
sphere6.jpg
いろいろできそうです。


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "test6.rib")
(RiDisplay "sphere6.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 40.0))
(RiTranslate 0 0 6)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2
"uniform point from" (Point 3 3 -3)))

(define (test x)
(define posx -3)
(let ((n 0))
(while (< n x)
(RiTransformBegin)
(set! posx (+ posx 1 ))
(RiTranslate posx 0 0 )
(RiColor (Color .9 .1 .1))
(RiSurface "plastic")
(RiSphere 0.5 -0.5 0.5 360)
(set! n (+ n 1))
(RiTransformEnd)
)))

(test 5)

(RiWorldEnd)
(RiEnd)



(use-modules (rman ri2rib))
を使うと空のRIBが出るだけで、課題です。
以下、エラー。
guile: symbol lookup error: /usr/local/lib/libguile_rman_ri2rib.so: undefined symbol: RifGetDeclaration
RenderMan | - | -

Guile RMan #7 AutoShadow

Aqsis1.6では、
Attribute "autoshadows" "string shadowmapname" ["autoshadow.shad"] "integer res" [600]
を利用して、影の自動生成を行います。

これと、もう一つ
Option "Render" "integer multipass" [1]
がないと、シャドウマップは生成されません。

simple3.jpg
以下、Aqsis1.6.0のサンプルautoshadow.ribを参考にしました。


#!/usr/bin/guile -s
!#
(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "illum2.rib")
(RiOption "Render" (list "integer multipass" 1))
(RiHider "hidden" (list "depthfilter" "midpoint"))
(RiDisplay "illum2.tif" "file" "rgb")
(RiFormat 512 384 1)
(RiProjection "perspective" '("fov" 30))
(RiTranslate 0 0 3)
(RiRotate -40 1 0 0)
(RiRotate -20 0 1 0)
(RiPixelFilter RiGaussianFilter 2 2)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.3))
(RiAttributeBegin)
(RiAttribute "autoshadows" (list "string shadowmapname" "autoshadow.shad" "integer res" 4096))
(RiTranslate 5 5 -5)
(RiRotate -45 0.0 1.0 0.0)
(RiRotate 35 1.0 0.0 0.0)
(define light1 (RiLightSource "shadowspot" (list "intensity" 300
"coneangle" 0.5
"string shadowname" "autoshadow.shad"
)))
(RiAttributeEnd)
(RiIlluminate light1 1 )
(RiAttributeBegin)

(RiTransformBegin)
(RiColor (Color 0.8 0.8 0.8))
(RiSurface "plastic")
(RiPolygon 4 (list "P" #f32(-1 0 -1 -1 0 1 1 0 1 1 0 -1)))
(RiTransformEnd)

(RiTransformBegin)
(RiColor (Color 0.8 0.4 0.2))
(RiSurface "plastic")
(RiRotate -90 1 0 0)

(RiScale 0.2 0.2 0.2)
(RiGeometry "teapot")
(RiTransformEnd)

(RiAttributeEnd)
(RiWorldEnd)
(RiEnd)



"integer res" 1024
"float blur" 0.008
と調整してみた。


(RiAttributeBegin)
(RiAttribute "autoshadows" (list "string shadowmapname" "autoshadow.shad" "integer res" 1024))
(RiTranslate 5 5 -5)
(RiRotate -45 0.0 1.0 0.0)
(RiRotate 35 1.0 0.0 0.0)
(define light1 (RiLightSource "shadowspot" (list "intensity" 300
"coneangle" 0.5
"float blur" 0.008
"string shadowname" "autoshadow.shad"
)))
(RiAttributeEnd)


illum3.jpg
RenderMan | - | -

Guile RMan #6 ShadowMap part 2

illum3.jpg

FramBegin〜Endを使ってAqsisサンプルのSoftshadowをguile-rmanで生成してみました。


#!/usr/bin/guile -s
!#
(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "illum3.rib")
;;(RiOption "limits" (list "bucketsize" #f32(32 32)))
(RiOption "limits" (list "eyesplits" 10))
(RiDeclare "bias" "float")
(RiHider "hidden" (list "depthfilter" "midpoint"))
(RiDisplay "softshadow.zfile" "zfile" "z")
(RiClipping 0.01 10)
(RiSides 2)
(RiFormat 512 512 1)
(RiPixelFilter RiBoxFilter 2 2)
(RiPixelSamples 1 1)
(RiShadingRate 2)

(RiFrameBegin 1)
(RiProjection "perspective" '("fov" 57.30))
(RiRotate -35.26 1.00 0.00 0.00)
(RiRotate 45.00 0.00 1.00 0.00)
(RiTranslate -5.00 -5.00 5.00)

(RiWorldBegin)
(RiSurface "null")
(RiSphere 1 -1 1 360)
(RiWorldEnd)
(RiFrameEnd)

(RiMakeShadow "softshadow.zfile" "softshadow.shad")


(RiDisplay "illum3.tif" "file" "rgba")
(RiFormat 512 384 1)

(RiPixelFilter RiGaussianFilter 2 2)
(RiPixelSamples 2 2)
(RiClipping 0.2 10)
(RiShadingRate 1)
(RiFrameBegin 2)

(RiProjection "perspective" '("fov" 45))
(RiTranslate 0 0 5)
(RiRotate -25 1 0 0)

(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "shadowspot" (list "intensity" 80
"from" (Point 5 5 -5)
"to" (Point 0 0 0)
"coneangle" 0.5
"float blur" 0.03
"string shadowname" "softshadow.shad"))

(RiColor (Color 0.4 0.4 0.1))
(RiSurface "matte")
(RiSphere 1 -1 1 360)

(RiOrientation "rh")
(RiColor (Color 0.5 0 0))
(RiSurface "matte")
(RiPatch "bilinear" (list "P" #f32(-10 -1 -10
10 -1 -10
-10 -1 10
10 -1 10)))
(RiWorldEnd)
(RiFrameEnd)
(RiEnd)


Max eyesplits for object "unnamed" exceeded
Object "unnamed" spans the epsilon plane
Object "unnamed" spans the epsilon plane
Max eyesplits for object "unnamed" exceeded
Object "unnamed" spans the epsilon plane
Max eyesplits for object "unnamed" exceeded
が出ますがレンダリングできました。
RenderMan | - | -

Guile RMan #5 RtLightHandle

やっと、わかりました。PixarのRenderMan C Bindingにヒントがありました。bulb.cを参考にしました。ありがとうございます。
guile-rmanでのRtLightHandleの記述例:

(define light2 (RiLightSource "distantlight" (list "intensity" 1.2 )))
(RiIlluminate light2 0 )

LightID、"light2"をRiIlluminateでオフ(0)にしています。
以下は、サンプルilluminate.scm
ambientlightのみの灯りになっています。


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "illum.rib")
(RiDisplay "illum.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 30))
(RiTranslate 0 0 5)
; (RiProgressHandler progress)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(display (RiLightSource "ambientlight" (list "intensity" 0.2)))
(newline)
(define light2 (RiLightSource "distantlight" (list "intensity" 1.2 )))
(newline)
(RiIlluminate light2 0 )
(RiAttributeBegin)
(RiColor (Color 1.0 0.6 0.0))
(RiSurface "plastic")
(RiTransformBegin)
(RiRotate 90 1 0 0)
(RiSphere 1 -1 1 360)
(RiTransformEnd)
(RiAttributeEnd)
(RiWorldEnd)
(RiEnd)

RenderMan | - | -

Guile RMan #4 RiPoints

guile-rmanでのRiPointsでは"constantwidth"を使う。ありがとうございます。
points4.jpg


#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "points4.rib")
(RiDisplay "points4.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 30))
(RiTranslate 0 0 3)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2 ))
(RiAttributeBegin)
(RiColor (Color 1 0 0))
(RiSurface "plastic")
(RiTransformBegin)
(RiTranslate -0.5 -0.5 0)
(RiPoints 4 (list "P" #f32(0 0 0 0 1 0 1 1 0 1 0 0) "constantwidth" 0.4))
(RiTransformEnd)
(RiAttributeEnd)
(RiWorldEnd)
(RiEnd)

RenderMan | - | -

Guile RMan #3 RiPolygon and RiPoints

guile-rmanでのRiPolygonの表記がわかりました。RiPointsもわかりましたが"width"設定がわからないところ。
rect.jpg
以下はサンプルです。points.scmで保存しました。

#!/usr/bin/guile -s
!#

(use-modules (rman rispec))
(use-modules (rman utilities))

(RiBegin "points.rib")
(RiDisplay "points.tif" "file" "rgb")
(RiFormat 640 480 1)
(RiProjection "perspective" '("fov" 30))
(RiTranslate 0 0 3)
; (RiProgressHandler progress)
(RiPixelFilter RiBoxFilter 1 1)
(RiWorldBegin)
(RiLightSource "ambientlight" (list "intensity" 0.2))
(RiLightSource "distantlight" (list "intensity" 1.2 ))
(RiAttributeBegin)
(RiColor (Color 1 0 0))
(RiSurface "plastic")
(RiTransformBegin)
(RiTranslate -0.5 -0.5 0)
;;(RiRotate -90 1 0 0)
;;(RiDisk 0 0.5 270)
;;(RiCone 1 0.5 150)
;;(RiCone 1.5 0.5 360)
(RiPolygon 4 (list "P" #f32(0 0 0 0 1 0 1 1 0 1 0 0)))
;;(RiPoints 4 (list "P" #f32(0 0 0 0 1 0 1 1 0 1 0 0) "width" 0.25)) ;;"Cs" #f32(1 0 0 0 1 0 0 0 1 1 1 0) "width" #f32(0.25 0.25 0.25 0.25)
(RiTransformEnd)
(RiAttributeEnd)
(RiWorldEnd)
(RiEnd)


(RiPoints 1 (list "P" #f32(0 0 0)))
で原点に点を表示します。
points.jpg
RenderMan | - | -
<< 2/52 >>