Войти
ПрограммированиеФорумОбщее

Рендер lightmap coords в текстуру на Unity

#0
23:57, 30 апр. 2021

Привет всем!

Делаю реалтайм лайтмапер, не спрашивайте зачем он мне нужон, нужОн для динамического лайтмапинга.

В чем проблема:
0) В сцене много моделей и сгенерированнная развертка лайтмапы выглядит так:

+ Показать

Как видим, все верно (насколько понимаю это все UV1 на "одном листе").

1) Свои карты / лайтмапы пеку так:

for(...)
commanBuf.DrawRenderer ( rend[i], worldBiNormalMaterial, k );

rtCamera.AddCommandBuffer ( CameraEvent.AfterEverything, cb);
rtCamera.Render ();

В материале worldBiNormalMaterial используется шейдер и при расcчетах берется texcoord1:

+ Показать

Как-то так, не вникайте в шейер. Фишка вот в чем: в результате работы "rtCamera.Render ();" имею такую текстуру:

+ Показать

И вот тут самое интересное. Часть UV обьектов отрендерено верно, а часть, неверно (будто использую UV1, но без учета упаковки на лайтмапе). В результате пес его знает что там наложилось на чего.

Вопрос на миллион: в чем проблема?


#1
(Правка: 0:17) 0:14, 1 мая 2021

Что это за магия и куда делся unity_LightmapST?
> float4( v.texcoord1.x * 2.0 - 1.0, v.texcoord1.y * 2.0 - 1.0, 0.5, 1.0 );// 0.5
Вот как производится трансформация из локальной ювихи в ювиху на атласе.
v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;

#2
0:44, 1 мая 2021

Dampire
> Что это за магия и куда делся unity_LightmapST?
Магия, но работает. Проецирует все куда надо.

Такой код:

float2 uv2 = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
        float4 uvWorldPos = float4( uv2, 0.5, 1.0 );
        // float4 uvWorldPos = float4( v.texcoord1.xy * 2.0 - 1.0, 0.5, 1.0 );
        o.pos = mul( UNITY_MATRIX_VP, uvWorldPos );
выдал такой результат:
+ Показать

Все посмещалось + развертки все так же наложились друг на друга.

#3
1:05, 1 мая 2021

Сместилось потому что не привел к -1..1 плюс  у тебя эта переменная пустая, так как развертки идентичные за исключением смещения.
Берется отсюда
https://docs.unity3d.com/ScriptReference/Renderer-lightmapScaleOffset.html

#4
8:53, 1 мая 2021

Dampire
А почему некоторые модели проецируются во весь лайтмап будто с uv1 что-то неверно?
Хотя на юнитевском лайтмап они вроде нормально расположены

#5
(Правка: 9:23) 9:22, 1 мая 2021

Dampire
> Сместилось потому что не привел к -1..1 плюс у тебя эта переменная пустая, так как развертки идентичные за исключением смещения.

Не, дело явно не в этом. Результат должен же быть всегда неверным для всех моделей. А у меня некоторые модели разворачиваются верно, некоторые - нет.
Вот что юнити показывает:

+ Показать

В моей версии обьекты должны спроектироваться в эти же области.
Вот вариант работы кода с fbx (все работает как надо):

+ Показать

А вот когда использую модель blender (настройки импорта почти такие же как у fbx, только 1cm (File) to 1m (unity))
А результат вот:

+ Показать

#6
(Правка: 10:17) 10:13, 1 мая 2021

Alerr
> А почему некоторые модели проецируются во весь лайтмап будто с uv1 что-то неверно?
Потому-что с uv1 что-то неверно.
Еще раз. Для правильного перевода uv1 в пространство лайтмапы есть

v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
Поскольку ты рисуешь в каком-то самопальном рендерлупе, то ты должен ручками задавать unity_LightmapST.
Значение берется из https://docs.unity3d.com/ScriptReference/Renderer-lightmapScaleOffset.html
Результат нужно потом переводить в -1..1 раз ты рисуешь в текстуру.
float4 uvWorldPos = float4((v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw) * 2 - 1, 0.5, 1.0 );

> Не, дело явно не в этом. Результат должен же быть всегда неверным для всех моделей.
Дело в этом. Одни модели юнити разворачивает сам, в других моделях uv1 развернут в каком-нибудь блендере. Очевидно юнити знает про упаковку в атлас, а блендер нет. Поэтому развернутое в юнити может юыть развернуто сразу в пространство лайтмапы, а развернутое в блендере развернуто на весь размер текстуры.

P.S. Еще дело может быть в том, что ты рисуешь все объекты в одну лайтмапу, хотя у тебя атласа два или больше, но судя по развертке в данный момент это не так.

#7
(Правка: 2 мая 2021, 9:03) 14:10, 1 мая 2021

Dampire
>Результат нужно потом переводить в -1..1 раз ты рисуешь в текстуру.
Спасибо, с этим понял.

> Одни модели юнити разворачивает сам, в других моделях uv1 развернут в каком-нибудь блендере.
Всё эти модели находятся в одном blender-file, следовательно импортируются с одинаковыми настройками. То есть либо юнити разворачивает все сам, либо я делаю развертки в блендере дл UV1.

Всем моделям сгенерировал UV1 в блендере, но можно поставить галку и юнити сгенерит свои UV1 для лайтмапы.

Что я сейчас сделал:
- запек освещение встроенным лайтмапером (кнопка Generate lighting)
- посмотрел как юнити расположился модели на лайтмапе, убедился что все расположено верно. То есть все UV1 сгенерировал верно, вот что сгенерировано:

+ Показать

- по идее юнити должен запечь всем моделям UV1 (то что видим на рис выше). Так же?
- для простоты у меня сейчас только 1 атлас.

Теперь прописал в функции Start вызов commandBuffer, который рендерит мои карты по запечённой лайтмапе со всеми UV1 (которые показаны на рис). И что, и снова с UV1 некоторых моделей что-то не так.

Подчеркиваю, у некоторых моделей. Все модели в одном blender-файле. Но UV1 одних верные, а у других такие, будто они из другого атласа или не запеклись верно. Хотя вон unity показывает, что на их лайтмапе все размещено верно.

#8
(Правка: 10:46) 10:44, 2 мая 2021

Alerr
> Всем моделям сгенерировал UV1 в блендере, но можно поставить галку и юнити
> сгенерит свои UV1 для лайтмапы.
Если в файле у тебя куча отдельных объектов, то юнити сделает авто развёртку лайтмапы для каждого меша ПО ОТДЕЛЬНОСТИ, а не упакует их в один атлас. Соответственно, если ты не используешь unity_LightmapST - получаешь корректное отображение лайтмап только на одном объекте, который имеет нулевые смещения в этом самом unity_LightmapST. А все остальные показывают не свои участки.

В любом случае - использование unity_LightmapST обязательно, если хочешь коректно получат UV координаты лайтмап.

#9
11:06, 2 мая 2021

marggob
Спасибо большое за ответ. Да, переписал код шейдера согласно тому как обьяснял товарищ Dampire :

+ Показать

Понял что координаты у каждого обьекта будут смещены. А как получить те самые UV1, которые генерирует Unity при запекании лайтмапа????

CommandBuffer теперь рендерит lightmap coords в текстуру так:

for (int m = 0; m < Paint3DManagerSystem.instance.m_Renderers[i].sharedMaterials.Length; ++m) {
            cb.SetGlobalVector ( "unity_LightmapST", Paint3DManagerSystem.instance.m_Renderers[i].lightmapScaleOffset );
            cb.DrawRenderer ( Paint3DManagerSystem.instance.m_Renderers[i], worldBiNormalMaterial, m );

В результате в текстуру все отрендерилось так:

+ Показать

А вот как Unity расположил UV1 на лайтмапе :

+ Показать

Почему в моем случае все отрендерилось не в те же области текстуры???

#10
(Правка: 13:34) 13:08, 2 мая 2021

Обновление.
Прямо какие-то чудеса. И эти чудеса длятся пол года, в течение этого времени я все пытаюсь иногда пофиксить эту часть проекта;

Что в итоге:
для некоторых моделей A,B,C

float2 uv2 = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
работает корректно!
Debug.Log(renderer.lightmapScaleOffset) выдает те же значения, что показаны в инспекторе.
Модель проецируется туда, куда ожидалось. Но большинство моделей C-Z искажается.


Исключаю операции с unity_LightmapST (как у меня было ранее), теперь обратная ситуация:
большинство моделей C-Z рендерится нормально, но модели A,B,C рендерятся так, будто unity_LightmapST = (1,1,0,0).

Ребят, что это может быть за магия и чертовщина? Почему код один и тот же, но модели рендерятся по-разному?
PS: все модели запечены, стоит галка Contribute GI. Так же все модели имеют UV1, развернуты блендером / встроенным генератором UV1, нормально проецируются встроенным лайтмапером.

#11
(Правка: 14:19) 13:43, 2 мая 2021

Попробовал тацы с бубном, пробовал задать для всех renderers:

_Renderers[i].lightmapScaleOffset = new Vector4 ( 1, 1, 0, 0 );

В итоге вот что получилось:
-- | Рендер lightmap coords в текстуру на Unity

Почему-то 99% разверток не во весь лайтмап. Только одна развертка стала ижидемов во весь лайтмап. Не чудеса ли это?

#12
(Правка: 15:01) 14:59, 2 мая 2021

Alerr
А если вырубить статик и динамик батчинг?

#13
15:23, 2 мая 2021

Dampire
> А если вырубить статик и динамик батчинг?
Если вырубить батчинг, то все модели растягиваются на весь лайтмап.

#14
16:50, 2 мая 2021

Ну вот тебе и ответ. В батчах хранится трансформированная UV1, без батчей нормальная.

ПрограммированиеФорумОбщее