7. right.tif: incorrect diffuse and
left.tif: correct
specula
在这个例子中,右相机输出的图片明显是错误的。Diffuse 效果看起来就像是被切掉了,
高光也在错误的位置。下面我们看一下上面例子中使用的 shader plastic,经典的
plastic 如下:
surface
plastic( float Ks = .5,
Kd = .5,
Ka = 1,
roughtnesss = .1;
color sepcularcolor = 1)
{
normal Nf = 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 相 关 , 即 faceforward
normal N. 内置的变量 I 是应该随着 camera 变化(主要是指位置方向)而变化的,但
是因为 shading 只跟 world camera(left camera)计算一次, 所以右相机输出的图片
就会有错误。下面的图示中,P 点在左相机中是正确渲染的(被遮挡状态) ,而在右相机中
虽然被渲染出来但是确实黑的,因为实际计算中使用了左相机的信息。因为在函数
faceforward 中使用了左相机的向量 I,在右相机的 diffuse 计算中,P 点的 diffuse
信息丢失。
8. 首先我们可以不使用 faceforward 来避免这中情况。但是这就需要在建模的时候所有的
面的法线都是朝外的。下面是修改以后的 shader:
surface
stereoplastic ( float Ks = .5,
Kd = ,5,
Ka = 1,
roughtness = .1;
color specularcolor = 1)
normal Nf = normalize(N)
vector V = -nromalize(I)
Oi = Os;
Ci = Os * (Cs*(Ka * ambient() + Kd * diffuse(Nf)) +
specularcolor * Ks * specular(Nf, V, roughness));
}
left.tif: correct right.tif: incorrect specular
我们可以看到,虽然经过了这样的修改,右相机中高光的位置仍然是错误的。原因很简
单因为 plastic shader 中的 spelucar 的计算方式仍然是和 view 相关的。在计
算右相机的 specular 函数中使用的参数 I 仍然是左相机的值,所以结果是错误的。
由此我们可以看到解决这个问题的核心是: 所有与参数 I 和 E 相关的计算都应该在
multicamera output 的时候修正。
因为 shading 只计算一次,为了得到"right" 相机的正确的结果,我们需要处理下
面的问题:
� 处理与右相机相关的 shading
� 与相机无关的计算可以在相机间共享,以避免重复计算和资源的浪费。
� 将右相机的结果使用新的 ouput color 单独输出。
9. 第一个问题:
将 右 相 机 "right" camera 的 位 置 转 换 到 current space. 我 们 可 以 使 用
RiCamera 声明 camera 时储存的坐标系统.这个坐标系统的名字与 camera 的名字是一样
的,在上面的例子中是"right",我们可以使用这个名字来转换 camera 的坐标系(use
this to compute the "right" camera position in current space by
transforming the point (0) from the "right" coordinate system to
current space):
Eright = transform("right", "current", point(0))
另外我们可以得 camera 的入射法线:
Iright = P - Eright
在与"right" camera 相关的计算中我们用 Iright 来替换 I,下面我们来进一步修
正 pliastic shader:
surface
stereoplastic( float Ks = .5,
Kd = .5,
Ka = 1,
roughtness = .1;
color specluarcolor = 1;
output varying color rightCi = 0;)
{
normal Nf = normalize(N);
vector V = -normalize(I);
Oi = Os;
//Compute the view independent color
color Cvi = Cs * (Ka * ambient()+ Kd * diffuse(Nf));
//Left camera
Ci = Os * (Cvi + sepcularcolor * Ks * specular( Nf, V,
roughness));
13. AttributeEnd
WorldEnd
FrameEnd
left.tif: correct reflection right.tif: incorrect reflection
我们可以修正 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));
14. 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 的立体渲染以后再研究)
efficiency of multi-camera rendering
综上所述,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 的速度差不多,甚至前者比后者效率会更
低一些(当然这种情况也比较少) 。