Большое спасибо за помощь. Вроде бы заработало)))
Получилось почти так как codingmonkey предложил:
<renderpath> <command type="clear" color="fog" depth="1.0" stencil="0" /> <command type="scenepass" pass="cull" /> <command type="clear" color="fog"/> <command type="scenepass" pass="base" vertexlights="true" metadata="base" /> <command type="forwardlights" pass="light" /> <command type="scenepass" pass="postopaque" /> <command type="scenepass" pass="refract"> <texture unit="environment" name="viewport" /> </command> <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" /> <command type="scenepass" pass="postalpha" sort="backtofront" /> </renderpath>
соответственно техника окклюдера:
<technique vs="Unlit" ps="Unlit" vsdefines="NOUV" > <pass name="cull"/> </technique>
техника зеленого объекта DiffAlpha, техника экрана:
<technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP"> <pass name="alpha" depthwrite="false" depthtest="always" blend="alpha" /> <pass name="litalpha" depthwrite="false" depthtest="always" blend="addalpha" /> </technique>
Кстати в связи с последней техникой возник вопрос - pass "litalpha" в рендерпасе не указан, но отрабатывается. С чем это связано?
И для чего нужны в моделе параметры "Is occluder" и "Can be occluded"? У меня так и не получилось смоделировать ситуацию, когда они на что-то влияют.
>Вроде бы заработало)))
круто)
>"litalpha" в рендерпасе не указан, но отрабатывается. С чем это связано?
Это типо сопутствующий alpha-пассу - суб-пасс (как и lit+base). Он не выносится в RP движек просто чекает технику.
// If no lit pass, check for lit alpha if (!destBatch.pass_) { destBatch.pass_ = tech->GetSupportedPass( litAlphaPassIndex_); isLitAlpha = true; }
далее альфа раскидывается по очередям на прорисовку (с лампочками или без)
Is occluder - это окклюдер, н/р здания,стены, горы, короче что-то большое, их не должно быть слишком много в кадре, bbox такого объекта рисует софтварно(CPU) в мелкий occlusionbuffer
и потом все объекты помеченные "Can be occluded" проверяются не перекрыты ли они чем либо.
>У меня так и не получилось смоделировать ситуацию, когда они на что-то влияют.
загрузи сцену с логотипом Ухи и с тремя кубиками в редакторе
в материале у логотипа чекни опцию "occlusion", у кубиков поставь "Can be occluded", затем покрути камеру вокруг логотипа (возможно лого придется несколько увеличить, что бы оно своим BBox перекрывало BB кубиков), должно все работать
> загрузи сцену с логотипом Ухи и с тремя кубиками в редакторе
> в материале у логотипа чекни опцию "occlusion", у кубиков поставь "Can be
> occluded", затем покрути камеру вокруг логотипа (возможно лого придется
> несколько увеличить, что бы оно своим BBox перекрывало BB кубиков), должно все
> работать
Обязательно проверю :) Но для меня сейчас более важен другой вопрос - почему при описанной выше системе при замене техники зеленого объекта с DiffAlpha на Diff он перестает отображаться.
Это находится в зависимости с depthtest="always" в технике экрана. Если depthtest оставить по умолчанию, то объект рисуется, но окклюдер вырезает экран. Если же поставить depthtest="greater" то экран рисуется только на окклюдере.
Все кажется разобрался. Как я понял из-за того, что техника Diff основана на пассе base, а DiffAlpha на пассе Alpha необходимо было вначале выполнить Alpha без записи в буфер глубины, а потом уже base выполнять.
Добрый день!
Появилось некоторое продолжение/усложнение задачи.
Теперь синий объект выполняет две функции:
1. Как и прежде окклюдера
2. Отображение некоторой текстуры с прозрачностью.
В итоге изображение на красном "экране" должно быть смешано с текстурой окклюдера.
Проблема - необходимо специфическое смешение с учетом разных факторов, другими словами результирующий цвет нужно вычислять в шейдере.
Вопрос в том, как и где этот щейдер прицепить.
Техника "экрана":
<technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP"> <pass name="alpha" depthwrite="false" depthtest="always" blend="alpha" /> <pass name="litalpha" depthwrite="false" depthtest="always" blend="addalpha" /> </technique>
Техника окклюдера:
<technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP"> <pass name="alpha" depthwrite="false" blend="alpha" depthtest="always" /> <pass name="litalpha" depthwrite="false" blend="addalpha" depthtest="always"/> <pass name="cull" vs="Unlit" ps="Unlit" vsdefines="NOUV" /> </technique>
Рендерпасс:
<renderpath> <command type="clear" color="fog" depth="1.0" stencil="0" /> <command type="scenepass" pass="cull" /> <command type="clear" color="fog"/> <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" /> <command type="scenepass" pass="base" vertexlights="true" metadata="base" /> <command type="forwardlights" pass="light" /> <command type="scenepass" pass="postopaque" /> <command type="scenepass" pass="refract"> <texture unit="environment" name="viewport" /> </command> <command type="scenepass" pass="postalpha" sort="backtofront" /> </renderpath>
AlexS32
Может собрать простой пример чтоб можно было проэкспериментировать с шейдерами и рендерпасом и при этом не выдавать деталей проекта?
Попробую - но не факт, что быстро получится.
Объекты можно просто кубиками поставить. Камеру добавить. Плоскость как задний фон. Просто чтоб точно понимать что ты делаешь. Потому что пока на словах очень тяжело.
я уже все забыл что там ты делал...(
но можешь попробовать проделать что-то типа такого финта:
0) рендерь окклюдер с альфа текстурой(материал на окклюдере) в маску - RT (A8), получится черно-белая текстура
1) рендерь фон в viewport-RT(rgba)
2) создай еще RT - temp RT(rgba), рендерь окклюдер и все чую нужно как раньше, но только в эту RT
3) постпроцессом смешиваешь две этих RT по маске, color = mix(viewportRT, TempRT, maskRTColor.r);
как-то так, но это все не точно
Разрешили мне пример для наглядности показать. Это то как работает у коллег под iOS на SceneKit:
Итак общая ситуация: изображение девушки с камеры воспроизводится на экране. Перед лицом размещается окклюдер, обрезающий лишние детали - например дужка очков, видимая через стекло не втыкается в голову.
На этой же поверхности располагается текстура для губ и бровей. И уже перед окклюдером располагаются очки. Соответственно для обеспечения правильного смешения изображения лица и косметики мне необходимо применить специфические преобразования.
codingmonkey, если Я правильно понимаю, ты предлагаешь рендерить разные части изображения в разные текстуры и где-нибудь в завершающим quad их смешивать?
Я хотел пойти по этому пути, но тут как раз и наткнулся на проблему, как разделить процесс рисования, если и экран, где отображается изображение с камеры и очки используют одни и те же проходы?
>разные части изображения в разные текстуры и где-нибудь в завершающим quad их смешивать?
да, всякие маски вспомогательные рендерить и по ним смешивать где тебе нужно
>наткнулся на проблему, как разделить процесс рисования, если и экран, где отображается изображение с камеры и очки используют одни и те же проходы?
если ты про урхо-пассы в RenderPath то ты можешь разделить и добавить их хоть тысячу штук под свои спец. задачи, но меньшее их кол-во естественно лучше.
стандартные RP на то они стандартные, чтобы в них вносили изменения под свои задачи.
объявляешь новый сцено-пасс(ы) в RenderPath, делаешь новую технику(и) с тем же именем(ми) и у тебя уже уникальный пасс(ы) в последовательности рендера, ты таким образом можешь можешь обойти свои ограничения, что-то разнести на этапы. все данные сохраняются в рендер-таргетах (RT). В общем все как в фотошопе со слоями только вместо кисти у тебя геометрия и шейдеры.
Ок. Попробую все разбить. Благо не так уж много объектов. По результатам отпишусь. Что слегка смущает- не до конца я понимаю суть замечания из документации про кастомные пассы:
"For the built-in passes listed above, the lighting shader permutations to load (unlit, per-vertex or per-pixel) are recognized automatically, but for custom passes they need to be explicitly specified. The default is unlit."
Я честно говоря уже не помню, но возможно это про то что тебе нужно писать PERPIXEL... в VS-PS-дефайнах пасса в своей кастомной технике т.к. для кастомных пассов двиг автоматом ничего не проталкивает в пермутации шейдеров
AlexS32
> если ты про урхо-пассы в RenderPath то ты можешь разделить и добавить их хоть
> тысячу штук под свои спец. задачи, но меньшее их кол-во естественно лучше.
>
Практически разобрался с этим вариантом, но не пойму никак эффект затемнения откуда берется если друг за другом идут два рендер-пасса, которые представляют собой кастомные alpha.
Т.е. в рендерпасе:
<command type="scenepass" pass="screen" vertexlights="true" sort="backtofront" metadata="alpha"/> <command type="scenepass" pass="object" vertexlights="true" sort="backtofront" metadata="alpha" />
в техниках:
<pass name="screen" lighting="pervertex" depthwrite="false" depthtest="always" blend="alpha" /> <pass name="litscreen" lighting="perpixel" depthwrite="false" depthtest="always" blend="addalpha" />
и
<pass name="object" lighting="pervertex" depthwrite="false" blend="alpha" depthtest="always" /> <pass name="litobject" lighting="perpixel" depthwrite="false" blend="addalpha" depthtest="always"/>
Object отображается нормально, а вот "экран" за ним очень темный получается. Шейдер для обоих техник стандартный LitSolid
Может unlit?
Так пока и не смог победить освещение - не понимаю я чего-то с освещением.
Расклад такой
Техника "экрана":
<technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP"> <pass name="screen" lighting="pervertex" depthwrite="false" depthtest="always" blend="alpha" /> <pass name="litscreen" lighting="perpixel" depthwrite="false" depthtest="always" blend="addalpha" /> </technique>
Техника маски:
<technique vs="LitSolid" ps="LitSolid" psdefines="DIFFMAP"> <pass name="glasses" lighting="pervertex" depthwrite="false" blend="alpha" depthtest="always" /> <pass name="litglasses" lighting="perpixel" depthwrite="false" blend="addalpha" depthtest="always"/> </technique>
Рендерпасс:
<renderpath> <rendertarget name="glasses" sizedivisor="1 1" format="rgba" /> <rendertarget name="screenRT" sizedivisor="1 1" format="rgba" /> <command type="clear" color="0.0 0.0 0.0 0.0" output="glasses" /> <command type="clear" color="0.0 0.0 0.0 0.0" output="screenRT" /> <command type="clear" color="fog" depth="1.0" stencil="0" /> <command type="scenepass" pass="glasses" metadata="alpha" output="glasses"/> <command type="scenepass" pass="screen" metadata="alpha" output="screenRT"/> <command type="quad" vs="MaskSh" ps="MaskSh" output="viewport"> <texture unit="diffuse" name="screenRT"/> <texture unit="specular" name="glasses"/> </command> </renderpath>
Шейдер для квада предельно прост:
#include "Uniforms.glsl" #include "Samplers.glsl" #include "Transform.glsl" #include "ScreenPos.glsl" #include "PostProcess.glsl" varying vec2 vTexCoord; void VS() { mat4 modelMatrix = iModelMatrix; vec3 worldPos = GetWorldPos(modelMatrix); gl_Position = GetClipPos(worldPos);https://gamedev.ru/files/?upload vTexCoord = GetQuadTexCoord(gl_Position); } void PS() { vec4 viewport = texture2D(sDiffMap, vTexCoord); vec4 glasses = texture2D(sSpecMap, vTexCoord); gl_FragColor = viewport; if (length(glasses) > 0.0){ gl_FragColor = glasses; } }
Если первым в рендерпасе стоит пасс "glasses" , то получаю такую картинку:
Если первым пасом указать"screen", то получим такую картинку:
Почему так происходит я не понимаю :(
Тема в архиве.