Несоответствия векторов инцидентов в RenderMan

Я работаю над переводом серии легких и поверхностных шейдеров из 3Delight в PRMan, и я обнаружил разницу между этими двумя, которую я не могу отработать. Кажется, что когда поверхностный шейдер оценивается на непрозрачность передачи из-за следа в легком шейдере, вектор падения I в PRMan устанавливается на поверхность нормально.

В моем примере сцены над диском плавает полушарие. Дальний свет сверху проецирует отслеживаемые значения пропускания на поверхности позади них (немного назад для света, но это демо). Поверхность в полушарии отображается как сплошная, окрашенная своими нормалями при просмотре камерой, но с непрозрачностью направления падения при запросе на передачу.

Вот как я ожидаю, что это будет выглядеть, и что я получу от 3Delight:

3Delight Render

Обратите внимание, что пол сплошной, почти чистый зеленый; цвет, который мы ожидаем, если угол падения вертикальный. Тем не менее, это то, что я получаю, когда рендерирую ту же самую сцену с PRMan:

Похоже, что проецирует нормали.

Я пытался получить значения через rayinfo и вычисление нового I, но все эти значения совпадают с тем, что I на самом деле установлен в. Я также заметил расхождения с E, но я не смог записать то, что устанавливается в PRMan.

Q: Как я могу получить вектор инцидента, который я ожидаю?

Содержание 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;
    }

}

1 ответ

Решение

Цитирование документации для спец. __computesOpacity параметр поверхности шейдеров:

Значение 0 означает, что шейдер не вычисляет непрозрачность (т.е. Oi == Os). Это может быть использовано для отмены режима попадания передачи шейдера. Для таких шейдеров метод opacity() будет пропущен для лучей передачи.

Значение 1 означает, что шейдер действительно вычисляет непрозрачность. Такие шейдеры будут запускаться для оценки их непрозрачности для проходящих лучей. Этот результат может кэшироваться средством визуализации и, следовательно, должен быть независимым от представления.

Значение 2 означает, что шейдер вычисляет непрозрачность в зависимости от вида. Таким образом, рендер будет избегать непрозрачности кэширования для лучей передачи. Непрозрачность все еще кэшируется с целью управления продолжениями на рассеянном и зеркальном лучах, но тени, зависящие от вида, могут генерироваться с использованием areashadow() или transmission(). Для режима 2 метод opacity() должен зависеть только от зависимых от вида объектов в проверке для raytype == "translation".

И цитируя Брайана из Pixar:

Установите это 2 делать то, что вы хотите. То, что вы видите, это рендер работает opacity однажды с куполами Iи кеширует это.

Другие вопросы по тегам