我正在努力将一系列光线和表面着色器从3Delight转换为PRMan,我发现了两者之间的差异,我无法解决。似乎当由于光着色器中的迹线而对表面着色器进行透射不透明度评估时,PRMan中的入射向量I
将被设置为曲面的法线。
在我的示例场景中,有一个漂浮在光盘上方的半球。来自上方的远处光线将跟踪的透射值投射到它们后面的表面上(对于光线稍微向后,但这是一个演示)。当被摄像机观察时,半球表面呈现为法线的纯色,但在查询传输时会出现入射方向的不透明度。
这是我期望的样子,以及从3Delight收到的内容:
注意地板几乎是纯绿色的;如果入射角是垂直的,我们期望的颜色。但是,当我用PRMan渲染完全相同的场景时,这就是我收到的内容:
似乎正在预测法线。
我尝试通过rayinfo
提取值并计算新的I
,但这些值都与实际设置的I
匹配。我也注意到与E
的差异,但我无法确定它在PRMan中的定位。
问:我怎样才能得到“我想要的事件?”
scene.rib
的内容:
Display "falloff.tiff" "framebuffer" "rgba"
Projection "perspective" "fov" [17]
Format 400 400 1
ShadingRate 0.25
PixelSamples 3 3
# Move the camera
Translate 0 -0.65 10
Rotate 30 -1 0 0
Option "searchpath" "string shader" ".:&"
WorldBegin
LightSource "projector" "projector_light"
"point to" [0 -1 0]
Surface "matte"
TransformBegin
Rotate 90 1 0 0
Disk 0 1.25 360
TransformEnd
Surface "inspect_incident"
Attribute "visibility" "integer transmission" [1]
Attribute "shade" "string transmissionhitmode" "shader"
TransformBegin
Translate 0 1 0
Rotate -90 1 0 0
Sphere 1 0 1 360
TransformEnd
WorldEnd
projector.sl
的内容:
light projector(
float intensity = 1;
color lightcolor = 1;
point from = point "shader" (0,0,0);
point to = point "shader" (0,0,1);
float maxdist = 1e12;
) {
uniform vector dir = normalize(to - from);
solar(dir, 0.0) {
Cl = intensity * lightcolor * (1 - transmission(Ps, Ps - dir * maxdist));
}
}
inspect_incident.sl
的内容:
class inspect_incident() {
public void opacity(output color Oi) {
vector In = normalize(I);
Oi = color((In + 1) / 2);
}
public void surface(output color Ci, Oi) {
vector Nn = normalize(N);
Ci = color((Nn + 1) / 2);
Oi = 1;
}
}
答案 0 :(得分:0)
引用表面着色器的特殊__computesOpacity
参数的文档:
值为0表示着色器不计算不透明度(即Oi == Os)。这可以用来覆盖 着色器的传输命中模式。对于这样的着色器,不透明度() 方法将被跳过传输光线。
值为1表示着色器确实计算了不透明度。这样 将运行着色器来评估它们对透射光线的不透明度。 该结果可能由渲染器缓存,因此必须是 视图无关的。
值为2表示着色器根据视图计算不透明度 方式。因此,渲染器将避免缓存不透明度 透射光线。不透明度仍然是为了缓存而缓存的 控制漫反射和镜面反射光线的延续,但是 视图相关阴影可以使用areashadow()或生成 传输()。对于模式2,opacity()方法必须仅依赖于 检查raytype ==“传输”的视图相关实体..
引用皮克斯的布莱恩:
将其设置为
2
以执行您想要的操作。你看到的是渲染运行opacity
一次使用圆顶'I
,然后缓存。