multi camera prmandoc

15
Multi Multi Multi Multi Camera Camera Camera Camera Rendering Rendering Rendering Rendering (prman) (prman) (prman) (prman) 翻译:张邵杰 简述 Prman13.5 开始引入 multiple, arbitrary camera 的概念。主要是为了实现在单独 renderpass 中实现多个 viewpoints 的输出结果,这相比用多个 renderpass 输出 要节省大量的时间,现在对这项功能进行一个介绍。 Renderman Renderman Renderman Renderman Interface Interface Interface Interface 一个新的 RI Call 用来定义相机 RiCamera (RtToken name, ..parameterlist...) Rib Binding: Camera Camera Camera Camera name ...parameterlist... 例子: Camera Camera Camera Camera "rightcamera" 这个函数可以将摄像机进行标记,用 name 进行记录。可以在解析来的 RiAttribute RiDisplay 中调用 name 调用相应的 Camera 相机的一些其他的属性同样可以被调用: Screen window RiScreenWindow Image dimension RiFromat RiFrameAspectRation Depth of field setting RiDepthOfField Clipping planes RiClipping World to camera transformation Camera projection RiProjection RiCamera 必须要在 RiWorldBegin 前声明才有效,因为对“相机描述本身其实是一个 optionRiCamera 同时创建了一个以 name 为标记的坐标系(类似于 RiCoordinateSystem)。 Shader 或者 RiTrasformPoints 可以通过调用 name 来使用这个坐标系。 Prman 有两个默认就定义的摄像机,一个叫“frame是在 RiFrameBegin 时定义的,另 一个是"world"是在 RiWorldBegin 时定义的,所以用户自定义的摄像机不能是这两个名 字。

Upload: guestb02e87

Post on 23-Jun-2015

645 views

Category:

Technology


0 download

DESCRIPTION

stereo rendering in renderman guide

TRANSCRIPT

Page 1: Multi Camera Prmandoc

MultiMultiMultiMulti CameraCameraCameraCamera RenderingRenderingRenderingRendering (prman)(prman)(prman)(prman)

翻译:张邵杰

简述

Prman13.5开始引入 multiple, arbitrary camera的概念。主要是为了实现在单独

的 renderpass中实现多个 viewpoints的输出结果,这相比用多个 renderpass输出

要节省大量的时间,现在对这项功能进行一个介绍。

RendermanRendermanRendermanRenderman InterfaceInterfaceInterfaceInterface

一个新的 RI Call 用来定义相机

RiCamera (RtToken name, ..parameterlist...)

Rib Binding:

CameraCameraCameraCamera name ...parameterlist...

例子:

CameraCameraCameraCamera "rightcamera"

这个函数可以将摄像机进行标记,用 name进行记录。可以在解析来的 RiAttribute 或

者 RiDisplay中调用 name调用相应的 Camera

相机的一些其他的属性同样可以被调用:

Screen window RiScreenWindow

Image dimension RiFromat RiFrameAspectRation

Depth of field setting RiDepthOfField

Clipping planes RiClipping

World to camera transformation

Camera projection RiProjection

RiCamera 必须要在 RiWorldBegin前声明才有效,因为对“相机描述”本身其实是一个

option。

RiCamera 同时创建了一个以 name为标记的坐标系(类似于 RiCoordinateSystem)。

Shader或者 RiTrasformPoints可以通过调用 name来使用这个坐标系。

Prman有两个默认就定义的摄像机,一个叫“frame”是在 RiFrameBegin时定义的,另

一个是"world"是在 RiWorldBegin时定义的,所以用户自定义的摄像机不能是这两个名

字。

Page 2: Multi Camera Prmandoc

DicingDicingDicingDicing CamerasCamerasCamerasCameras

现在 dicing camera 可以支持 RiCamera声明的相机了。如果在 Attribute "dice"

中应用 RiCamera声明的相机,这个相机将在 dicing的过程中比其他 dicing camera

优先级高。

Muli-CameraMuli-CameraMuli-CameraMuli-Camera OutputOutputOutputOutput

一旦创建了 multiple camera ,一个单独的 render pass就可以在渲染时同时输出多

个 viewpoints.而多相机渲染那需要配合 aov(arbitray output variable)输

出.RiDisplay 增加了一条新的参数"string camera". 这个参数可以用来接收由

RiCamera声明的自定义相机。

当多相机渲染时,所有的几何体只被 shade 一次。这也正是 single pass 渲染比

multiple pass渲染快的原因:即几何体 shade的结果可以被多个相机同时使用。但是

因为 shading只发生一次,与 view 相关的 shading就需要特别注意(比如高光,反射

等。)这将在下面的章节详细介绍。

下面的代码是一个定义了"right"camera的 rib文件,其中 right camera比 world

camera 不同的是 ScreenWindow 参数:

##RenderMan RIB

Projection "perspective" "fov" [45]

Formate 256 256 1.0

PixelSamples 5 5

ShadingRate 0.25

Translate 0 -1 10

TransformBegin

ScreenWindowScreenWindowScreenWindowScreenWindow -0.75-0.75-0.75-0.75 1.251.251.251.25 -1-1-1-1 1111

CameraCameraCameraCamera "right""right""right""right"

TransformEnd

ScreenWindowScreenWindowScreenWindowScreenWindow -1.25-1.25-1.25-1.25 0.750.750.750.75 -1-1-1-1 1111

Display "left.tif" "tiff" "rgba"

DisplayChannel "float a"

DisplayChannel "color Ci"

Display "+right.tif" "tiff" "Ci,a" "quantize" [0 255 0 255]

"stringstringstringstring camera"camera"camera"camera" ["right"]["right"]["right"]["right"]

Page 3: Multi Camera Prmandoc

FrameBegin 5

TransformBegin

LightSource "shadowspot" "mylight" "float intensity" [250]

"point from" [0 3 -15]"point to " [0 0 0 ] "shadowname"

"raytrace"

TransformEnd

WorldBegin

AttributeBegin

Attribute "visibility" "string transmission" ["opaque"]

Color [1 0.25 0.25]

Surface "plastic" "float roughness" [0.05] "color

specularcolor" [0 1 1]

Translate 0 -1 0

Rotate -90 1 0 0

Geometry "teapot"

AttributeEnd

AttributeBegin

Surface "texmap" "string texname" "ratGrid.tex"

Scale 6 6 1

Patch "bilinear" "P" [ -1 1 4 1 1 4 1-1 -1 4 1 -1 4]

AttributeEnd

WorldEnd

FrameEnd

在这个例子中,因为只有 screen window被修改,而两个渲染相机的位置并没有区别所

以实际观看时并不会出现立体效果。在下面的例子中我们用 Translate 来替换

screenwindow偏移,两个相机只在 x轴做偏移

left.tif: ScreenWindow -1.25

0.75 -1 1

right.tif: ScreenWindow -0.75

1.25 -1 1

Page 4: Multi Camera Prmandoc

##RenderMan RIB

Projection "perspective" "fov" [45]

Format 256 256 1.0

Translate 0 -1 10

TransfromBegin

TranslateTranslateTranslateTranslate -1-1-1-1 0000 0000

CaemraCaemraCaemraCaemra "right""right""right""right"

TransformEnd

TranslateTranslateTranslateTranslate 1111 0000 0000

Display "left.tif" "tiff" "rgba"

DisplayChannel "float a"

DisplayChannel "color Ci"

Display "+right.tif" "tiff" "Ci,a" "quantize" [0 255 0 255]

"string"string"string"string camera"camera"camera"camera" [[[[ "right"]"right"]"right"]"right"]

FrameBegin 5

TranformBegin

LightSource "shadowspot" "mylight" "float intensity" [250]

"point from" [0 3 -15] "point to " [0 0 0] "shadowname"

"raytrace"

TransformEnd

WorldBegin

Attribute "visitbility" "string transmission" ["opaque"]

Color [1 0.25 0.25]

Surface "plastic" "float roughness" [ 0.05] "color

sepcularcolor" [0 1 1 ]

Rotate -90 1 0 0

Geometry "teapot"

WorldEnd

FrameEnd

Page 5: Multi Camera Prmandoc

和上个 ScreenWindow的版本相比,这次的立体效果更加明显:移动镜头产生的立体效果

可以从 teapot和背景的前后对比中分辨出来。注意两个图片中 teapot的 diffuse效果

也不一样。更明显的是 teapot的高光位置也不一样了

ShadingShadingShadingShading ConsiderationsConsiderationsConsiderationsConsiderations

需要再次强调的是,在进行 multiple-camera output时,shading过程只执行一次,

并且只与 wolrd camera进行计算。这就会使图片产生错误。例如在上面的例子中,你会

发现右面图片的高光位置相比左面的图片要离得更远。在大部分情况下,这种

artifacts(不真实)是难以察觉的,但是这也与实际使用的 shader与相机的相关计算的

程度有关。

为了便于我们介绍怎样修正 multiple-camera rendering使用的 shader,我们首先

将上面例子中出现的 artifacts效果放大,以方便我们查看,具体是将右相机与左相机成

90度夹角:

#RenderMan RIB

Projection "perspective" "fov" [45]

Formate 256 256 1.0

PixelSample 5 5

ShadingRate 0.25

Translate 0 0 10

TransformBegin

RotateRotateRotateRotate 45.045.045.045.0 0000 1111 0000

CameraCameraCameraCamera "right""right""right""right"

TransformEnd

RotateRotateRotateRotate -45-45-45-45 0000 1111 0000

left.tif: Translate 1.0 0 0 right.tif: Translate -1.0 0 0

Page 6: Multi Camera Prmandoc

Display "left.tif" "tiff" "rgba"

DisplayChannel "float a"

DisplayChannel "color Ci"

Display "+right.tif" "tiff" "Ci,a" "quantize" [ 0 255 0 255]

"stringstringstringstring camera"camera"camera"camera" ["right"]["right"]["right"]["right"]

FrameBegin 5

TransformBegin

LightSource "shadowspot" "mylight" "float intensity" [250]

"point from " [ 0 30 -15] "point to " [0 0 0 ] "shadowname"

"raytrace"

TransformEnd

WorldBegin

AttributeBegin

Attribut "visibility" "string transmission" ["opaque"]

Color [ 1 0.25 0.25]

Surface "plastic" "float roughness" [0.05] "color

specularcolor" [0 1 1 ]

Translate 0 -1 0

Rotate -90 1 0 0

Geometry "teapot"

AttributeEnd

AttributeBegin

Surface "texmap" "string texname" "ratGrid.tex"

Scale 6 6 1

Patch "bilinear" "P" [ -1 1 4 1 1 4 -1 1 4 1 -1 4]

AttributeEnd

WorldEnd

FrameEnd

Page 7: Multi Camera Prmandoc

在这个例子中,右相机输出的图片明显是错误的。Diffuse效果看起来就像是被切掉了,

高光也在错误的位置。下面我们看一下上面例子中使用的 shader plastic,经典的

plastic如下:

surface

plastic( float Ks = .5,

Kd = .5,

Ka = 1,

roughtnesss = .1;

color sepcularcolor = 1)

{

normalnormalnormalnormal NfNfNfNf ==== faceforward(normalize(N),I);faceforward(normalize(N),I);faceforward(normalize(N),I);faceforward(normalize(N),I);

vector V = -normalize(I);

Oi = Os;

Ci = Os * ( Cs * ( Ka* ambient()+ Kd * diffuse(Nf)) +

specularcolor * Ks * specular(Nf, V , roughness));

}

=================================================================

diffuse 之所以产生问题是因为 shader 的计算与 view 相关,即 faceforwardfaceforwardfaceforwardfaceforward

normal N. 内置的变量 I是应该随着 camera变化(主要是指位置方向)而变化的,但

是因为 shading只跟 world camera(left camera)计算一次,所以右相机输出的图片

就会有错误。下面的图示中,P点在左相机中是正确渲染的(被遮挡状态),而在右相机中

虽然被渲染出来但是确实黑的,因为实际计算中使用了左相机的信息。因为在函数

faceforward中使用了左相机的向量 I,在右相机的 diffuse计算中,P点的 diffuse

信息丢失。

left.tif: correctright.tif: incorrect diffuse and

specula

Page 8: Multi Camera Prmandoc

首先我们可以不使用 faceforward来避免这中情况。但是这就需要在建模的时候所有的

面的法线都是朝外的。下面是修改以后的 shader:

surface

stereoplastic ( float Ks = .5,

Kd = ,5,

Ka = 1,

roughtness = .1;

color specularcolor = 1)

normalnormalnormalnormal NfNfNfNf ==== normalize(N)normalize(N)normalize(N)normalize(N)

vector V = -nromalize(I)

Oi = Os;

Ci = Os * (Cs*(Ka * ambient() + Kd * diffuse(Nf)) +

specularcolor * Ks * specular(Nf, V, roughness));

}

我们可以看到,虽然经过了这样的修改,右相机中高光的位置仍然是错误的。原因很简

单因为 plastic shader中的 spelucar的计算方式仍然是和 view相关的。在计

算右相机的 specular函数中使用的参数 I 仍然是左相机的值,所以结果是错误的。

由此我们可以看到解决这个问题的核心是:所有与参数 I 和 E相关的计算都应该在

multicamera output的时候修正。

因为 shading只计算一次,为了得到"right" 相机的正确的结果,我们需要处理下

面的问题:

� 处理与右相机相关的 shading

� 与相机无关的计算可以在相机间共享,以避免重复计算和资源的浪费。

� 将右相机的结果使用新的 ouput color单独输出。

left.tif: correct right.tif: incorrect specular

Page 9: Multi Camera Prmandoc

第一个问题:

将右相机 "right" camera 的位置转换到 current space.我们可以使用

RiCamera声明 camera时储存的坐标系统.这个坐标系统的名字与 camera的名字是一样

的,在上面的例子中是"right",我们可以使用这个名字来转换 camera的坐标系(usethis to compute the "right" camera position in current space by

transforming the point (0) from the "right" coordinate system to

current space):

ErightErightErightEright ==== transform("right",transform("right",transform("right",transform("right", "current","current","current","current", point(0))point(0))point(0))point(0))

另外我们可以得 camera的入射法线:

IrightIrightIrightIright ==== PPPP ---- ErightErightErightEright

在与"right" camera相关的计算中我们用 Iright来替换 I,下面我们来进一步修

正 pliastic shader:

surface

stereoplastic( float Ks = .5,

Kd = .5,

Ka = 1,

roughtness = .1;

color specluarcolor = 1;

outputoutputoutputoutput varyingvaryingvaryingvarying colorcolorcolorcolor rightCirightCirightCirightCi ==== 0;)0;)0;)0;)

{

normal Nf = normalize(N);

vector V = -normalize(I);

Oi = Os;

//Compute//Compute//Compute//Compute thethethethe viewviewviewview independentindependentindependentindependent colorcolorcolorcolor

colorcolorcolorcolor CviCviCviCvi ==== CsCsCsCs **** (Ka(Ka(Ka(Ka **** ambient()+ambient()+ambient()+ambient()+ KdKdKdKd **** diffuse(Nf));diffuse(Nf));diffuse(Nf));diffuse(Nf));

//Left//Left//Left//Left cameracameracameracamera

CiCiCiCi ==== OsOsOsOs **** (Cvi(Cvi(Cvi(Cvi ++++ sepcularcolorsepcularcolorsepcularcolorsepcularcolor **** KsKsKsKs **** specular(specular(specular(specular( Nf,Nf,Nf,Nf, V,V,V,V,

roughness));roughness));roughness));roughness));

Page 10: Multi Camera Prmandoc

//Right//Right//Right//Right cameracameracameracamera

pointpointpointpoint ErightErightErightEright ==== transform("right",transform("right",transform("right",transform("right", "current",point(0));"current",point(0));"current",point(0));"current",point(0));

vectorvectorvectorvector IrightIrightIrightIright ==== PPPP ---- Eright;Eright;Eright;Eright;

vectorvectorvectorvector VrightVrightVrightVright ==== -nromalize(Iright);-nromalize(Iright);-nromalize(Iright);-nromalize(Iright);

rightCirightCirightCirightCi ==== OsOsOsOs **** (Cvi(Cvi(Cvi(Cvi ++++ specularcolorspecularcolorspecularcolorspecularcolor **** KsKsKsKs **** specular(Nf,specular(Nf,specular(Nf,specular(Nf,

Vright,roughtness));Vright,roughtness));Vright,roughtness));Vright,roughtness));

}

因为我们要区分左右 camera的输出,我们需要一个 arbitrary output variable.

我们需要对 rib文件左相应的调整:

#RenderMan RIB

Projection "perspectiv" "fov" [ 45 ]

Formate 256 256 1.0

PiexlSemples 5 5

ShadingRate 0.25

Translate 0 0 10

TransformBegin

Roate 45 0 1 0

Camera "right"

TransformEnd

Rotate -45 0 1 0

Display "left.tif" "tiff" "rgba"

DisplayChannel "float a"

DisplayChannel "colorcolorcolorcolor rightCirightCirightCirightCi"

Display "+right.tif" "tiff" "rightCi,rightCi,rightCi,rightCi,a" "quantize" [0 255 0 255]

"string camera" ["right"]

FrameBegin 5

TransformBegin

LightSource "shadowspot" "mylight" "float intensity" [250]

"point from" [0 3 -15] "point to"[0 0 0] "shadowname"

"raytrace"

TransformEnd

WorldBegin

AttributeBegin

Attribute "visibility" "string transmission" ["opaque"]

Color [1 0.25 0.25]

Surface "stereoplastic" "float roughness" [0.05] "color

specularcolor" [ 0 1 1]

Translate 0 -1 -

Rotate -90 1 0 0

Geometry "teapot"

AttributeEnd

AttributeBegin

Surface "texmap" "string texname" "ratGrid.tex"

Page 11: Multi Camera Prmandoc

Scale 6 6 1

Patch "bilinear" "P" [ -1 1 4 1 1 4 -1 -1 4 1 -1 4]

AttributeEnd

WorldEnd

FrmaeEnd

我们可以看到 teapot的 diffuse 和 specular被修正,但是背景的颜色信息丢失

了,因为背景板所使用的 shader "texmap"并没有对"rightCi"做输出

与相机相关的 shading可以扩展到其他相关的效果中例如 raytracing.下面是一个

简单的镜面反射材质:

#================================================================

surface

mirror(float Kr = 1)

{

color Crefl = 0, hitc = 0;

vectorvectorvectorvector reflDirreflDirreflDirreflDir ==== reflect(I,N);reflect(I,N);reflect(I,N);reflect(I,N);

gather ("illuminance", P, reflDir,reflDir,reflDir,reflDir, 0 , 1, "surface:Ci",hitc){

Crefl +=hitc;

}

Ci = 0.2 * Cs * diffuse(normalize(N)) + Kr * Crefl;

Oi = 1;

}

#===============================================================

如果我们将这个材质赋予一个球体用来反射一个 teapot,我们会得到错误的右相机的输

left.tif: correct right.tif: correct

Page 12: Multi Camera Prmandoc

出:

#===============================================================

##Renderman rib

Projection "perspective" "fov" [45]

Format 256 256 1.0

PixelSamples 5 5

ShadingRate 0.25

Translate 0 0 5

TransfomBegin

Rotate 45 0 1 0

Camera "right"

TransformEnd

Rotate -45 0 1 0

Display "left.tif" "tiff" "rgba"

DisplayChannel "float a"

DisplayChannel "color Ci"

Display "+right.tif" "tiff" "Ci,a" "quantize" [0 255 0 255]

"string camera" ["rightcamera"]

FrameBegin 5

TransformBegin

LightSource "shadowspot" "mylight" "float intensity" [250]

"point form" [0 30 -15] "point to" [ 0 0 0]

"shadowname" "ryatrace"

TransformEnd

WorldBegin

AttributeBegin

Attribute "visibility" "int camera" [0] "int diffuse"

[1] "int specular" [1]

Color [1 0.25 0.25]

Surface "defaultsurface"

Translate 0 -1 -4

Roatate -90 1 0 0

Geometry "teapot"

AttributeEnd

AttributeBegin

Surface "texmap" "string texname" "ratGrid.tex"

Scale 6 6 1

Patch "bilinear" "P" [ -1 1 4 -1 -1 4 1 1 4 1 -1 4]

AttributeEnd

AttributeBegin

Attribute "visibility" "string transmission" ["opaque"]

Surface "mirror"

Color [0.25 0.25 1]

Sphere 1 -1 1 360

Page 13: Multi Camera Prmandoc

AttributeEnd

WorldEnd

FrameEnd

我们可以修正 mirror shader以适应左右相机输出,这里需要两个 gather语句:

#================================================================

surface

stereomirror ( float Kr = 1 ;

output varying color rightCi = 0;)

{

//View independent color calculations

color Cvi = .2 * Cs * diffuse(normalize(N));

//View dependent calculation for left camera

color Crefl = 0, hitc = 0;

vector reflDir = reflect ( I, N);

gather ("illuminance", P, reflDir , 0, 1, "surface:Ci", hitc){

Crefl += hitc;

}

Ci = Cvi + Kr * Crefl;

unifrom float raydepth;

rayinfo("depth", raydepth);

if (raydepth ==0)

//View dependent calculation for right camera - these only

need // to be performed for primary rays. If we dont

//perform the reydepth check, we ll be throwing lots of

//wasted secondary rays.

point Eright = transform ("right", "current", point(0));

left.tif: correct reflection right.tif: incorrect reflection

Page 14: Multi Camera Prmandoc

vector Iright = P - Eright;

Crefl = 0;

reflDir = reflect(Iright,N);

gather("illuminance", P, reflDir, 0 ,1, "surface:Ci",hitc){

Crefl+= hitc;

}

rightCi = Cvi + Kr * Crefl;

}

Oi = 1;

}

#================================================================

总结:

在multi-camera output rendeing时,因为 shading只计算一次并且只和main

camera进行计算,我们可以遵从下面的规则得到正确的输出图片:

1.首先运行所有和 view不相关的计算,并把结果保存到一个临时的 color变量

中(例如:"color Cvi")

2.运行与 view相关的计算例(所有依赖于 I, E的计算);把计算结果加上 Cvi

一并储存到 Ci中,这就是主相机(left camera)的正确结果。

3.对于所有其他的 camera,将其他 camera 相应的 I,E 转换到 current

space,Iright, Eright;计算与相机相关的 shading;然后将计算结果加上 Cvi

一并储存到 color arbitrary output variable中(这个变量在流程中应该尽

量的统一)。并且确保 RiDisplay的输出与color arbitrary output variable

一直

#================================================================

注意:

atmosphere shader需要特别的注意,因为一般情况下,atmosphere的所有计算都是与相

机相关的。(关于 atmosphere shader的立体渲染以后再研究)

efficiencyefficiencyefficiencyefficiency ofofofof multi-cameramulti-cameramulti-cameramulti-camera renderingrenderingrenderingrendering

综上所述,multi-camera rendering 要比 multiple pass rendering 快很多,

因为对于所有相机,所有物体的 shading只计算一次。但是,内存的使用量会随着相机分

离的程度(不同的程度)而又所不同 - 因为 shading的结果会在 camera间公用,所以

相应的会在内存中保存时间增加。在 multi camera rending 时,除非指定特定的

dicing camera,不然的话渲染器会每个 camera渲染时采用物体的最集合机型计算,距

离说如果一个物体只在 left camera中出现,在计算 right camera时,他也会被计算

进去,虽然他完全不在 right camera 的输出中出现。在这种情况下 multi-camera

rendering和 multiple pass rendering的速度差不多,甚至前者比后者效率会更

低一些(当然这种情况也比较少)。

Page 15: Multi Camera Prmandoc

email:

[email protected]

欢迎大家交流