1

我正在将一系列光和表面着色器从 3Delight 转换为 PRMan,我发现了两者之间的差异,我无法解决。似乎当由于光照着色器中的跟踪而评估表面着色器的透射不透明度时I,PRMan 中的入射矢量被设置为表面的法线。

在我的示例场景中,有一个半球漂浮在圆盘上方。来自上方的远处光线将跟踪的透射值投射到它们后面的表面上(对于光线来说有点向后,但这是一个演示)。当被相机观察时,半球上的表面被渲染为由其法线着色的纯色,但在查询传输时具有入射方向的不透明度。

这是我期望它的样子,也是我从 3Delight 收到的:

3喜悦渲染

请注意,地板是实心的,几乎是纯绿色;如果入射角是垂直的,我们期望的颜色。但是,当我使用 PRMan 渲染完全相同的场景时,我会收到以下信息:

在此处输入图像描述

它似乎在投射法线。

我尝试通过获取值rayinfo并计算一个 new I,但这些值都与I实际设置的值匹配。我也注意到与 的差异E,但我无法确定 PRMan 中的设置。

问:我怎样才能得到我所期待的事件向量“I”?

内容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;
    }

}
4

1 回答 1

0

引用__computesOpacity表面着色器特殊参数的文档:

值 0 表示着色器不计算不透明度(即 Oi == Os)。这可用于覆盖着色器的传输命中模式。对于此类着色器,将跳过 opacity() 方法用于传输光线。

值 1 表示着色器确实计算了不透明度。将运行此类着色器以评估其对透射光线的不透明度。该结果可能由渲染器缓存,因此必须与视图无关。

值 2 表示着色器以与视图相关的方式计算不透明度。因此,渲染器将避免缓存传输光线的不透明度。不透明度仍被缓存以控制漫反射和镜面反射光线的延续,但可以使用 areashadow() 或透射() 生成与视图相关的阴影。对于模式 2,opacity() 方法必须仅依赖于检查 raytype == "transmission"..

并引用皮克斯的布赖恩:

将其设置2为做你想做的事。您所看到的是渲染运行 opacity一次与圆顶' I,并缓存它。

于 2012-05-15T17:43:05.557 回答