Як з'єднати 2 світлові карти для циклу день / ніч в Unity?


16

Перш ніж сказати щось інше: я використовую подвійні світлові карти, це означає, що мені потрібно поєднувати і близькі, і далекі.

Тому я над цим працюю вже деякий час, у мене цілий день / ніч створений цикл для візуалізації та освітлення, і все працює нормально і не є інтенсивним процесом.

Єдина проблема, яка у мене виникає, - це з'ясувати, як я міг би поєднати два світлові карти разом, я придумав, як перемикати світлові карти, але проблема полягає в тому, що це виглядає наче різко і перериває досвід.

Я провів кілька годин з цього питання, спробував усілякі шейдери, змішування пікселів за пікселями та все інше безрезультатно. Змішування пікселів за пікселями в C # виявилось трохи інтенсивним процесом, на мій смак, хоча я все ще працюю над його очищенням і змушує його працювати більш плавно. Шейдери виглядали багатообіцяючим, але я не зміг знайти шейдер, який міг би правильно поєднати два світлові карти.

Хтось має підказки щодо того, як я міг би це досягти? Мені просто потрібен якийсь плавний перехід між моєю денною та нічною світлою картою. Можливо, я міг би накласти дві текстури і використовувати альфа-канал? Або щось подібне?


Якщо у вас є Pro, можливо, ви можете перетворити дві текстури світлової карти на третину, а потім використовувати цю третю текстуру як світлу карту? Це має бути подібно до змішування пікселів, але масово швидше.
забудьте

У мене є Pro. Як би я міг передати два текстури світлової карти разом? Це було моє головне керівництво, але я намагався розібратися з кодом / процесом, щоб його виконати.
Тімоті Вільямс

Umm створити матеріал, який поєднує дві текстури, використовувати Graphics.Blit()для його візуалізації? Я ніколи цього не робив, але, дивлячись у посібнику, це має працювати.
забудьте

Отже, створіть новий матеріал, який може змішати дві текстури до виводу, застосувати Afar-1 і Bfar-1, а потім використовувати вихідну текстуру для змінної lightmap?
Тімоті Вільямс

Так, щось подібне. Я б протестував, але на даний момент у мене немає доступу до Pro версії.
забудьте

Відповіді:


3

Тому я нещодавно спробував себе в цьому і зіткнувся з багатьма тими ж проблемами, що і у вас. Текстурне рішення візуалізації - це трохи червона оселедець. Мені вдалося вирішити це за допомогою багатопотокової маніпуляції пікселями на окремій потоці.

https://www.youtube.com/watch?v=T_zpFk1mdCI

Тож зазвичай можна використовувати graphics.blit()та передавати текстуру візуалізації туди, куди їй потрібно перейти, але дані світшоти не підтримують текстури, для них потрібні тексту2ds. Наступним логічним кроком буде скопіювати дані в text2d, а потім подати їх у дані світлого карти. Ця методика руйнує частоту кадрів, тому що вона затримує GPU для надсилання даних в процесор, а не просто посилання на дані.

Тоді рішення - не використовувати GPU.

Переходи світлих карт відбуваються протягом тривалого періоду часу, тому не обов’язково важливо оновлювати світлу карту кожного кадру. Насправді гравці, ймовірно, не помітили, якби світлі карти оновлювалися лише кожні 20-40 хвилин у ігровий час.

Отже, ви робите це завдання, яке ви подаєте на ЦП на окремі потоки для кожної легкої карти.

Зазвичай Unity не підтримує багатопотоковість. Але це нормально, C # робить. Цей хлопець виконує феноменальну роботу, пояснюючи багатопотоковість в Єдності, тому якщо ви ніколи про це не чули або ніколи не знали, як багатопоточні в Unity, це відео:

https://www.youtube.com/watch?v=ja63QO1Imck

Все, що вам потрібно зробити, - це зробити клас робочої нитки, який варіює копії даних пікселів світлого карти в кольорових масивах, а потім створити функцію змішування.

Простий лерп від одного кольору до іншого зробить.

Потім створіть потік, запустіть його, і коли всі світлові карти будуть закінчені в окремі потоки, ви зможете скопіювати дані пікселів назад у text2d дані даних про світлу карту.

Нижче я розмістив приклад коду. Це, звичайно, не повністю реалізована версія, але вона показує вам основні концепції складання класу, створення потоку та встановлення світлих даних.

Інші речі, які вам доведеться зробити, - це викликати функцію щоразу, щоб викликати оновлення світлових карт. Крім того, ви повинні або скопіювати всі дані пікселів у робочий клас під час запуску або під час компіляції. Удачі всім, хто це знайде. Я вважаю, що ОП продовжило своє життя, але я знаю, що інші люди з подібними проблемами можуть натрапити на це.

public class work
{
    Color[] fromPixels;
    Color[] toPixels;

    public float LerpValue = 0;
    public bool Finished = false;
    public Color[] mixedPixels;

    public work(Color[] FromPix, Color[] ToPix)
    {
        fromPixels= FromPix;
        toPixels= ToPix;
        Finished = false;
        mixedPixels = new Color[FromPix.Length];
    }
    public void DoWork()
    {
        for (int x = 0; x < fromPixels.Length; x++)
        {
            mixedPixels[x] = Color.Lerp(fromPixels[x], toPixels[x], LerpValue);
        }
        Finished = true;
    }
}

IEnumerator LightMapSet()
{
    Thread workerThread = new Thread(someworker.DoWork);
    someworker.LerpValue = lerpValue;
    workerThread.Start();
    yield return new WaitUntil(() => someworker.Finished);
    mixedMap.SetPixels(someworker.mixedPixels);
    mixedMap.Apply(true);
    LightmapData someLightmapData;
    someLightmapData.lightmapColor = mixedMap;
    lightDatas = { someLightmapData};
    LightmapSettings.lightmaps = lightDatas;
}

1

Є шейдер skybox, який поєднується між двома наборами текстур skybox. Подумайте про денний і нічний цикл!

Якщо ви хочете створити або анімувати skybox із скрипту, використовуйте skyboxmaterial.SetFloat("_Blend", yourBlend)для зміни змішування; також можна використовувати SetTextureматеріальні функції для налаштування або зміни фактур.

Відеоурок про цикл день / ніч: http://www.youtube.com/watch?v=FTfv9JhkmIA

Приклад коду йде наступним чином:

Shader "RenderFX/Skybox Blended" {
Properties {
    _Tint ("Tint Color", Color) = (.5, .5, .5, .5)
    _Blend ("Blend", Range(0.0,1.0)) = 0.5
    _FrontTex ("Front (+Z)", 2D) = "white" {}
    _BackTex ("Back (-Z)", 2D) = "white" {}
    _LeftTex ("Left (+X)", 2D) = "white" {}
    _RightTex ("Right (-X)", 2D) = "white" {}
    _UpTex ("Up (+Y)", 2D) = "white" {}
    _DownTex ("Down (-Y)", 2D) = "white" {}
    _FrontTex2("2 Front (+Z)", 2D) = "white" {}
    _BackTex2("2 Back (-Z)", 2D) = "white" {}
    _LeftTex2("2 Left (+X)", 2D) = "white" {}
    _RightTex2("2 Right (-X)", 2D) = "white" {}
    _UpTex2("2 Up (+Y)", 2D) = "white" {}
    _DownTex2("2 Down (-Y)", 2D) = "white" {}
}

SubShader {
    Tags { "Queue" = "Background" }
    Cull Off
    Fog { Mode Off }
    Lighting Off        
    Color [_Tint]
    Pass {
        SetTexture [_FrontTex] { combine texture }
        SetTexture [_FrontTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_FrontTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_BackTex] { combine texture }
        SetTexture [_BackTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_BackTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_LeftTex] { combine texture }
        SetTexture [_LeftTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_LeftTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_RightTex] { combine texture }
        SetTexture [_RightTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_RightTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_UpTex] { combine texture }
        SetTexture [_UpTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_UpTex2] { combine previous +- primary, previous * primary }
    }
    Pass {
        SetTexture [_DownTex] { combine texture }
        SetTexture [_DownTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
        SetTexture [_DownTex2] { combine previous +- primary, previous * primary }
    }
}

Fallback "RenderFX/Skybox", 1
}

2
Питання про світлові карти, а не про небо. Дякуємо за посилання, але, схоже, це буде мені корисно.
поштовх

0

Якщо ви знаєте, як переключитися, чому б не продовжувати створення декількох перехідних світлових карт на фоновому потоці, а потім увімкнути переходи, коли світлові карти готові?

Ви також можете подивитися цікавий актив на AssetStore: https://www.assetstore.unity3d.com/en/#!/content/5674

Я здогадуюсь, що вона включає змішування світлових карт, хоча я не знаю, як саме.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.