Настройка frameBuffer’ов для вывода пассов в целом и mia_material_x в частности

В этой статье хочу описать метод “ручной” распассовки при рендере в mentalray. Начиная с версии 2009 в майе появилась удобная система пассов прямо из renderSettings. Сейчас в ходу уже Maya 2010… Так зачем тогда нужна возня с настройкой вручную?

Ответ очень прост – до сих пор эта казалось бы удобная система адекватно работает лишь в презентациях и туторах, но даже в тестах средней сложности становятся видны проблемы. Лично я очень часто пользуюсь отличным шейдером mia_material_x, которым можно сделать подавляющее большинство необходимых материалов. И вот как раз его даже в виде специального _x_passes варианта (который, кстати, немного медленнее) новая система полноценно не распассовывает. У самого шейдера есть все необходимые аутпуты, которые можно подключить к кастомным буфферам и вывести как отдельные пассы, но вот тут и кроется самая большая проблема этой системы – простое добавление кастомного буффера, даже пустого, замедляет рендер… иногда очень значительно (сцена, которая используется для примера в этой статье, замедляется с 7 минут до 57 минут).

Собственно, в статье пойдет речь о более старом методе вывода пассов, который решает как проблему совместимости с mia_material_x, так и проблему скорости.

Сразу оговорюсь, что новую систему распассовки нельзя назвать прямо совсем уж никчемной – она довольно удобная и может быть полезна в каких-то ситуациях (при использовании обычных майских шейдеров, к примеру), просто она серьезно недоработана на данный момент… и этот момент длится уже года полтора, поэтому рассчитывать на скорое решение всех проблем лично я бы не стал 😉

Итак, самое важное преимущество, которое дает нам старый ручной метод – возможность выводить в пассы все что мы хотим без такого сильного ущерба для скорости рендера. Платой за это и самым большим недостатком является муторность сетапа, причем Муторность с большой буквы… или может быть даже так – МУТОРНОСТЬ 🙂

Процесс и результат на самом деле немало зависят от:

Описываемый метод состоит из трех блоков:

Опишу каждый из этих блоков подробнее.


– шейдинг нетворк –

Вот так может выглядеть шейдинг нетворк для пяти разных материалов с настроенной распассовкой:

Аутпуты mia_material_x и других шейдеров надо втыкать в каналы буффер-шейдеров в одинаковой последовательности для всех материалов, дабы разные данные не валились в один и тот же пасс. К примеру, indirect_raw данные тут подключены всегда к пятому каналу.

В первый канал (color[0] для simplePasses, primarybuffer для ctrl_buffers, color_pass[0] для ART_passes) подключаются beauty данные (result у mia_material_x, outColor у майских шейдеров и т.п.) – чтобы корректно определить качество сэмплинга (ниже расскажу подробнее о Contrast All Buffers), глубину трейса (к примеру, если рефракшен луч в точке не кастится в beauty, то и во всех пассах в этой точке рефракшен считаться не будет, даже при наличии соответствующего шейдера), а также видеть общую картинку во время просчета.

Важно отметить, что ctrl_buffers и simplePasses будут писать свои каналы поочередно в имеющиеся фреймбуфферы – если выключить/отконнектить какой-то канал – в подготовленный для него фреймбуффер попросту будет писаться следующий, что в итоге создаст рассинхронизацию имен и данных. ART_passes же позволяет писать каждый канал в фреймбуффер с определенным именем, что решает эту проблему и очень удобно.

Интерфейс подключенного simplePasses:

ctrl_buffers ограничен 15ю каналами (simplePasses/ART_passes таких ограничений не имеют):

ART_passes в плане интерфейса отличается от simplePasses только наличием еще одного массива, содержащего имена фреймбуфферов для каждого канала:

ВАЖНО! В первый пользовательский фреймбуффер всегда хочет залезть майский glow – он тоже может рассинхронить имена/данные, а в simplePasses еще и портит beauty (конечно только если вы не хотите чтобы beauty светился :)). Можно для него выделять всегда первый фреймбуффер, но лучше всего попросту отключить галку Export Post Effects в renderSettings.

Для удобства создания буффер-шейдера и подключения к нему существующего mia_material_x можно написать скрипт вроде этого (в списке passes определяем названия аутпутов, которые хотим выводить, затем выделяем нужные mia_material_x и запускаем скрипт):

# Python Script for creating simplePasses shaders and connecting them to selected
# mia_material shaders
from maya.cmds import *

passes = ['result', 'diffuse_raw', 'diffuse_level', 'ao_raw', 'indirect_raw',
'refl_raw', 'refl_level', 'spec_raw', 'spec_level', 'refr_raw', 'refr_level' ]

selShd = ls( selection = True )
for shd in selShd:
	buf = shadingNode( 'simplePasses', asShader = True,
							name = shd + '_passes' )
	for each in passes:
		connectAttr( shd + '.' + each,
			buf + '.color[' + str(passes.index( each )) + ']')

– фреймбуфферы –

Maya 2008 в renderSettings ментала в разделе Framebuffer>User Framebuffer имеет большую кнопку Open Editor, которая открывает атрибуты ноды miDefaultOptions, где можно легко создать необходимое кол-во фреймбуфферов. В 2009 этот интерфейс спрятан, поэтому единственный способ сетапа – создать ноду mentalrayUserBuffer и подключить ее message к массиву frameBufferList ноды miDefaultOptions.

Скриптом это сделать довольно просто (каждый запуск создает новый фреймбуффер и подключает его к следующему индексу frameBufferList):

# Python Script for creating and connecting mentalrayUserBuffers
# to miDefaultOptions
from maya.cmds import *

buff = createNode( 'mentalrayUserBuffer' )
connectAttr( buff + '.message', 'miDefaultOptions.frameBufferList',
							nextAvailable = True )

Интерфейс mentalrayUserBuffer незамысловат:

Можно выбрать битность пасса и производить ли его интерполяцию. Если писать в OpenEXR формат, имя фреймбуффера определит название канала exr (в 2008 это не работает, там по-любому каналы будут называться типа fb0, fb1, fb2…)

Есть ряд названий, которые пишутся в дефолтные каналы exr. К примеру, если назвать фреймбуффер rgba – данные запишутся в основной RGBA канал файла. Также можно использовать depth, uv (которые записываются как моушен вектора :)) и вероятно какие-то еще.


– аутпуты –

Последний этап – настроить рендерКамере аутпуты, дабы при рендере из нее данные фреймбуфферов записались в отдельные файлы (или в разные каналы одного exr). Для этого служит интерфейс на ее шейпе mental ray>Output Shaders, позволяющий создавать и подключать ноды mentalrayOutputPass:

Тут два варианта – брать данные из дефолтного фреймбуффера (различные варианты битности beauty, а также depth, label, coverage и т.п. – в этом случае имя канала exr будет браться из имени mentalrayOutputPass ноды) или пользовательского, который мы создали на прошлом этапе (надо активировать Use User Buffer и выбрать нужный из выпадающего меню). Для записи в файл активируем File Mode и задаем формат и постфикс (к имени файла, определенного в renderSettings, будет прибавлен знак _ и указанный постфикс, и сам файл создастся в директории, так же определенной в renderSettings). Если значение поля постфикса у разных аутпутов одно и то же, а тип файлов установлен OpenEXR – создастся один exr-файл с пассами в дополнительных каналах. Вместо постфикса можно написать абсолютный путь, например “C:/Temp/passes.0001.exr”, потому как, к сожалению, первый вариант плохо именует сиквенсы, приходится переименовывать файлы после рендера, но можно написать экспрешен, который при апдейте таймлайна будет вписывать путь и имя с текущим номером фрейма, например:

string $path = "C:/Temp";

string $outputs[] = `ls -type "mentalrayOutputPass"`;
for( $each in $outputs ) {
	setAttr -type "string" ($each + ".fileName")
				($path + "/" + $each + "." + frame + ".exr");
}

Его имеет смысл доработать под себя (в последнем проекте у меня экспрешен находил все нужные пути из настроек проекта, в них создавал подпапки с названием пассов (если их еще не было), делал пэддинг, красивые имена и все это вводил в аутпуты).

Пользовательские фреймбуфферы активируются по запросу аутпута из камеры, т.е. если на рендерКамере есть включенный (галка renderable установлена) аутпут, который берет данные из пользовательского фреймбуффера – этот фреймбуффер будет создан, если нет – несмотря на его наличие и подключение к miDefaultOptions, он будет пропущен. Т.е. если используется ctrl_buffers или simplePasses, и какие-то из уже настроенных аутпутов отключаем – снова есть опасность рассинхрона имен/данных. (В 2008 же, если фреймбуффер подключен к miDefaultOptions, он будет создан по-любому, даже если записывать его никуда не надо – что исключает данную проблему).


– прочее –

При verbose минимум 4 (info messages) в логе можно посмотреть какие фреймбуфферы созданы для текущего рендера:

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

set TEMP=D:\tmp
start /belownormal D:\Maya\2009_x64\bin\maya.exe

Галку Contrast All Buffers в renderSettings часто имеет смысл отключить, иначе для каждого фреймбуффера будут вычисляться свои значения контраста для повышения сэмплинга, в результате чего скорость рендера может сильно упасть. При отключении галки сэмплинг для всех пассов будет определяться основным фреймбуффером (color[0] для simplePasses, primarybuffer для ctrl_buffers, color_pass[0] для ART_passes). Конечно, пассы будут менее качественные, но обычно в тех местах, где это не очень нужно. Если beauty содержит достаточно деталей во всех необходимых областях – в них и у пассов проблем не будет (если в beauty какие-то зоны тонут во тьме, к примеру, в пассах будет виден минимальный сэмплинг).

Шейдеры с просчетом освещения (типа lambert для пасса dust в тестовой сцене) или трейсом обычно получается быстрее отсчитать отдельным проходом, так как может замедлить рендер распассовки сильнее, чем дополнительный просчет – это лучше потестить по факту. Прилагаю тестовую сцену с сетапом на основе simplePasses – без пассов просто beauty рендерится 6m50s, а с 19ю пассами – 7m00s, т.е. замедление довольно незначительное. В ней есть этот lambert (в сцене вместо него подключен incidence от samplerInfo) – если его подключить обратно, время возрастает примерно до 13m30s, хотя сам он отдельно может быть просчитан всего за 16 секунд 🙂

Download Example Scene

Ну и в качестве заключения – какой же шейдер все-таки использовать…

38 Responses

Subscribe to comments via RSS

  1. Written by DQvsRA
    on 17 January 2010 at 13:25
    Permalink

    Thnx, a lot. Right at time when i need it.

  2. Written by Jason
    on 18 January 2010 at 9:27
    Permalink

    Thanks a lot. A great read. Not sure if you have dropped by these two CGTalk threads below. They are working on multipass shader based on the megaTK shader.

    http://forums.cgsociety.org/showthread.php?f=87&t=828928
    http://forums.cgsociety.org/showthread.php?f=87&t=843425

    Also, a matte-pass generator shader is under construction here:
    http://forums.cgsociety.org/showthread.php?f=89&t=843279

    – Jason

  3. Written by Mike
    on 21 January 2010 at 9:39
    Permalink

    А можно ли получить вдобавок ко всем пассам еще и Shadow pass? За один рендер проход, при условии, что используется mia_material_x_passes.

    Есть ли хоть какое-нибудь решение по данной проблеме?

  4. Written by Sagroth
    on 22 January 2010 at 0:52
    Permalink

    У шейдера к сожалению нет такого аутпута, поэтому его средствами похоже это сделать не получится. Можно в состав распассовки впихнуть mip_matteshadow (если shadow выставить в белое – можно получать в rgb результат), но это разумеется дополнительные вычисления – насколько существенные – надо пробовать.

  5. Written by Mike
    on 22 January 2010 at 9:55
    Permalink

    А difuse_raw как shadow_pass использовать можно? У p_megaTK shadow_pass очень похож на difuse_raw.

  6. Written by Sagroth
    on 22 January 2010 at 10:04
    Permalink

    diffuse_raw это комбинация прямого освещения, теней, самозатенения и неосвещенных участков. Т.е. тени в состав конечно входят, но отделить их от всего остальное вряд ли получится… если стоит цель именно получить исключительно брошенные объектом на объект тени.

  7. Written by Mike
    on 22 January 2010 at 11:12
    Permalink

    Конечная цель в том чтобы на композе иметь возможность поменять цвет теней(добавить или сменить им цветовой оттенок), а также сделать тени более прозрачными либо наоборот более заметными.

  8. Written by Mike
    on 24 January 2010 at 19:13
    Permalink

    Проделал туториал, все вроде получилось, но не совсем все 🙂
    Единственное, что не понятно из туториала, что после создания simplePasses и связи его с шейдером его надо назначить объекту вместо это шедера. Ели бы не пример сцены так бы и рыскал в инете в поиске ответа :))))

    А вот, что не получилось:
    1. Почему-то на одной поверхности изменилась интенсивность источника света дифуз_резалт+все пасы выдает бьюти один в один, а diffuse_row+diffuse_level уже сразу слегка отличается от diffuse_result и бьюти тоже выдает другое. Отличие идет в распределении света его интенсивность слегка меньше становится. Почему так могло получится?
    2. Один из объектов имел mia_material_x с выбраным пресетом — Glass solid. Он давал голубую прозрачную тень, после связи его с simplePasses и переназначении simplePasses на этот объект, в рендере сразу выдает другую тень — просто черная тень как от непрозрачного объекта. Как это можно обойти?

  9. Written by Sagroth
    on 26 January 2010 at 0:37
    Permalink

    1. Не могу сказать наверняка.

    2. Попробовал Glass Solid – получил голубую тень как в бьюти, так и в diffuse_raw. Возможно надо взять более свежый патч майи (у меня 2009 x64 SP1a)

  10. Written by Mike
    on 26 January 2010 at 12:44
    Permalink

    По поводу тени, я тоже получил. Там моя проблема оказалась в том что, при наложении simplePasses на объект вместо mia_material_x, нужно в шейдергруппе в shadow shader вместо simplePasses оставлять mia_material_x. Тогда тени правильные получаются. В любом случае спасибо за помощь 🙂

  11. Written by zeth
    on 2 February 2010 at 0:46
    Permalink

    Great post. Great blog, lots of good stuff here . . .
    Had a quick question. I’m on a Mac using 2008. When I render images using simplepasses, all works fine except that I’m getting blown out images (except reflections). All the passes are correct, just WAY overbright. Any ideas on what this could be?
    Z

  12. Written by Sagroth
    on 2 February 2010 at 0:52
    Permalink

    Yeap, I guess I’ve mentioned that – you need to turn off Export Post Effects checkbox in Render Globals>Options – that’s shader glow messes everything up for some reasons.

  13. Written by zeth
    on 2 February 2010 at 18:59
    Permalink

    Hmm. Yeah, I’m actually doing that. Looking more closely at it, it seems to have something to do with the physical sun & sky only. Scenes with no sun/sky work fine, IBL/HDR stuff included (including exposure shaders and all that). But the sun/sky system seems to blow out the renders in the passes. The “result” pass is completely different from the actual beauty render and all the passes seem to want to add up to this messed up/blown out version. Can you think of why this would be happening?
    Thanks again.

    Z

  14. Written by Sagroth
    on 4 February 2010 at 2:05
    Permalink

    Yeah, I see now what you mean. The thing is – framebuffers don’t give a damn about lens shaders. s&s adds pretty heavy one – if you remove it from camera, you’d get in beauty the same blown out result as in passes – that’s just what s&s does to your picture without gamma correction applied, so everything seems to be correct.

    s&s default gamma CC has gain set to 0.2, it has also other settings, but multiplying your light passes by 0.2 in comp makes a pretty similar picture.

  15. Written by zeth
    on 4 February 2010 at 7:44
    Permalink

    sweet. Thanks a ton. Thought I was crazy:)
    Keep up the good work, man.

    Z

  16. Written by dragonlaw
    on 15 February 2010 at 14:16
    Permalink

    Fantastic stuff, although I am having trouble figuring out how you rendered you normal pass, as I have looked at your shader and there seems to be no connection allowing that pass?

    Which number is it? Its not color16 due to the fact that is the position pass.

  17. Written by Sagroth
    on 15 February 2010 at 15:15
    Permalink

    It’s a native mr pass (as well as depth and a couple more) – it can be output directly from camera through mentalrayOutputPass node without user buffers.

    P.S. I ran it on vista (crazy OS) and found out that you need to make all your native outputs AFTER userBuffer outputs or render would fail (no such problems in XP).

  18. Written by Royalty
    on 19 March 2010 at 3:17
    Permalink

    А кто нибудь может подсказать где найти информацию о создании многослойных текстур с использованием масок и рендеринге всего результата в Ментал рей?

  19. Written by Royalty
    on 19 March 2010 at 3:18
    Permalink

    * по пассам.
    Забыл добавить)

  20. Written by Sagroth
    on 20 March 2010 at 2:34
    Permalink

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

    Либо собрать все вручную и подключить к обычному буффер шейдеру. По сути надо умножить текстуру на маску (colorGain как самое простое решение) и отправить маску как альфу – можно через mib_color_mix

  21. Written by mBort
    on 10 June 2010 at 7:12
    Permalink

    Hello, Sagroth
    Nice Blog, thx for sharing so much info.
    Today i found a good news at http://mayastation.typepad.com/maya-station/2010/02/writetocolorbuffer.html
    that:
    “Note: in Maya 2011, the writeToColorBuffer node has been rewritten and does not increase the render times as in previous versions of Maya.”

  22. Written by Sagroth
    on 10 June 2010 at 9:34
    Permalink

    Yeap, I know, thanks. I’ve even tested this in 2011 myself already and it seems to be working properly now, though rendering a lot of different passes at once was pretty slow still (I need to do more tests on that). We’re still in 2009 anyway 😉

  23. Written by Kamal
    on 17 June 2010 at 1:23
    Permalink

    Hi, first of all thanks for your ART passes. I am trying to make them work in 2011 but getting stuck.Is it possible for you to post a scene example file where the scene is setup using ART passes.in the scene above available for download you have used Simple passes. Also, We need to use KSL frame buffer manager as in maya 2011 they Autodesk has hidden the feature of User framebuffer. thanks in advance. also, a video tutorial to set up Framebuffer output using ART passes would be very very appreciated.
    best regards,
    Kamal

  24. Written by Sagroth
    on 19 June 2010 at 2:55
    Permalink

    Hi.

    ART_passes shader is not mine.

    Here’s the scene for Maya 2011 with complete setup and the exr file I get from it for comparison:

    http://www.sigillarium.com/blog/wp-content/uploads/FILES/art_test01.rar

    2011 has framebuffer section hidden the same way it is in 2009.

    Nice videotutorial about setting up buffers can be found here:

    http://williework.blogspot.com/2010/03/technical-creating-custom-render-passes.html

  25. Written by Kitten
    on 1 July 2010 at 6:42
    Permalink

    thanks a lot. my boyfriend has been ferveriously testing me to see if I understand this stuff to be a part of his world, and I can now report back with what I’ve learned ^-^

  26. Written by Sagroth
    on 2 July 2010 at 15:56
    Permalink

    Sounds like a pretty cruel man 😀

  27. Written by Korinkite
    on 2 July 2010 at 19:37
    Permalink

    Great work, I’ve tried looking at the scene files but I can’t for the life of me figure out how you made the maskA, maskB, and p passes. I figured the reason was because of some lack of knowledge of ramps and/or projections.

    I know to create the same effect by using render layers but your method doesn’t require any which makes me especially intrigued.

    May I get some kind of reference (link/forum/tutorial) where I can learn how you mapped your ramp colors to your objects via projection?

  28. Written by Sagroth
    on 2 July 2010 at 22:15
    Permalink

    masksA & masksB are just solid RGB-colored ramps plugged into the same buffer channel. I’ve got 5 shaders and 3 colors, so I make 3 shaders RGB and 2 just black in masksA. Then I make these last two shaders RG in masksB and the rest three of them black.

    Projected ramps are for ‘grads’ pass – I just create ramp as projection and translate/rotate/scale it’s planar placement to cover the scene with green gradient from left to right, blue gradient from us in depth and red – from the center of the scene outwards (circular ramp) – then just plus them all together (since they are pure RGB – they’ll be separated without any problem in compositing). There’re three placements in the scene – take a look at them. Projecting 2D textures are explained in maya help.

    p is a position of a surface point in the world space – it’s taken from samplerInfo node and just plugged into buffer channel.

    Hope that answers your questions.

  29. Written by Korinkite
    on 3 July 2010 at 1:39
    Permalink

    Oh, looks like I over thought the process a bit, that explanation is really helpful thank you. Hope to see more of your work later.

    – Korinkite

  30. Written by Kit
    on 6 July 2010 at 0:50
    Permalink

    okay~ just so we are clear, yes Korinkite, this is me, your girlfriend, I just wanted to say. No. Kitty is not me like you have accused me of being. BUT this was very helpful. I would love to learn how to do all of this stuff. This was well laid out and helpful.
    ~Kit

  31. Written by Chris Russell
    on 13 November 2010 at 11:07
    Permalink

    Hi Sagroth

    Thanks for this tutorial it’s really helpful. I’m still struggling to understand how to render a cast shadows pass. Is this possible or do we still have to set up a shadow layer to get just the shadow information.

    Thanks for all your help

    Cheers

  32. Written by Sagroth
    on 13 November 2010 at 23:36
    Permalink

    Hi. If you want to get shadow layer unmatted by casting objects (like a shadow on the ground) it seems you have to use renderLayer. I did some tests plugging mib_continue or other fully transparent shaders into a pass for the casting objects, but it produces weird results and render time increases greatly.

  33. Written by Chris Russell
    on 14 November 2010 at 0:04
    Permalink

    That’s a shame. Is there any combination of diff_level, diff_result and diff_raw that can be composited to control the
    cast shadows? Thanks again for your help 😀

  34. Written by Sagroth
    on 14 November 2010 at 2:01
    Permalink

    These passes won’t give you control over shadows. You need a pass that has diffuse without shadows or shadows without diffuse. Then you can divide one by another in comp to separate them. You can make additional pass with mip_matteshadow for that, but that’s additional calculations. So that really depends whether your scene export is fast enough – pretty often it’s much more efficient to render stuff like that as a separate render (furthermore ground shadows with casting objects invisible are much better in comp because shouldn’t leave fringes).

  35. Written by Lover boy
    on 19 November 2010 at 4:17
    Permalink

    Thanks for posting, my girlfriend Kitty showed me this, I haven’t seen this one yet and it was a big help, I’m currently working on trying to fix my shadows to be a slightly different shape than the object that they are coming from so learning about shadows is helpful.

  36. Written by Aperon
    on 27 December 2010 at 3:18
    Permalink

    А что можете сказать об этих НЕМУТОРНЫХ ))) шейдерах, которые были сделаны на основе шейдеров Puppetа?
    http://deex.info/wordpress2/tools/deex-shaders-pack/

    Я в майке их не юзал, пытаюсь под макс приспособить.

    За статью СПАСИБО!!!

  37. Written by Sagroth
    on 27 December 2010 at 5:20
    Permalink

    Слышал, но никогда не пробовал. Помню были какие-то странности с бампом у ctrl_buffers и вроде то же самое в тестах с p_megaTk наблюдалось. У simplePasses этого не было, зато был ряд других 🙂 Надо будет попробовать – спасибо.

  38. Written by korinkite
    on 1 June 2011 at 14:55
    Permalink

    Hey Sagroth. Just wanted to say that, as a person who has been revisiting your blog in intervals, that I find myself learning new things every time I reread your posts and it has been incredibly helpful. I was just looking to optimize passes and found your tip on “contrast all buffers”. Thanks a ton!

    – Korinkite

Subscribe to comments via RSS

Leave a Reply