У Minecraft, коли дивишся на воду, тим глибше ти бачиш, чим вона стає темнішою. Хтось знає, як кодувати щось подібне?
Minecraft з ефектом
подібна гра без ефекту
У Minecraft, коли дивишся на воду, тим глибше ти бачиш, чим вона стає темнішою. Хтось знає, як кодувати щось подібне?
Minecraft з ефектом
подібна гра без ефекту
Відповіді:
По суті, існує два різних підходи до освітлення води на основі глибини:
Minecraft використовує освітлення на основі вокселів, яке працює, поширюючи світло на сусідні кубики, знижуючи яскравість залежно від типу блоку. Темні океани є побічною дією цієї системи.
Вода блокує сонячне світло і зменшує світло на 3 рівні на блок (замість 1 рівня за замовчуванням), що означає яскравість в океані на кожну відстань від поверхні:
0 (surface): 15 (direct sunlight)
1: 12
2: 9
3: 6
4: 3
5 and below: 0 (darkness)
Джерело: Minecraft Wiki - Light
В іграх із традиційною моделлю освітлення цей ефект можна створити, вимірюючи кількість води, яка знаходиться між джерелом світла та океанським дном. Потім світло згасає, виходячи з цієї відстані. Для цього є кілька методів:
Якщо у вас рівна поверхня, ви можете легко обчислити відстань, яку проходить світло у воді, якщо перенести поверхню нормально подалі від водоймища та крапкового добутку цього нормального та положення поверхні в шейдер геометрії.
Ефективна водна відстань - це
де розташування вершини і кут між напрямком світла під поверхнею та нормальною поверхнею води до водойми.
На заході сонця досягає лише трохи менше 50 °, оскільки світло переломлюється при надходженні у воду.
Ось запис у блозі з хорошим поясненням: Цифрова камера: Повна внутрішня рефлексія
Ще одна публікація з більш детальною інформацією: Цифрова камера: Закон переломлення Снелла
Якщо ви використовуєте мапу висоти на поверхні, паралельній воді, стає . Правильний коефіцієнт дорівнює 1, якщо сонце знаходиться безпосередньо над поверхнею води.
За допомогою точкового світла ви повинні розраховувати для кожної вершини виходячи з відносного положення до джерела світла.
При фіксованому рівні води або фіксованому напрямку світла частини рівняння є постійними і їх не слід обчислювати в шейдері з міркувань продуктивності.
Якщо ви виведете поверхню води на окрему карту глибини (як видно з джерела світла), ви можете використовувати цю текстуру глибини для обчислення відстані, яку світло проходить у воді, перш ніж потрапляти на поверхню.
Для цього ви проектуєте кожну вершину у проекцію подання джерела світла у вершинній шейдері та здійснюєте пошук текстури у піксельній шейдері.
Якщо поверхня відносно рівна, для кращих результатів слід використовувати заломлене походження світла.
* Ви можете визначити кількість води перед найближчою твердою поверхнею, порахувавши глибину від ПОВ світла таким чином:
Тепер текстура результату містить кількість води перед світлом у просторі зору світла, тому значення потрібно перетворити назад, перш ніж використовувати його. Цей метод працює для обчислення спрямованого світла (мінус заломлення), але призведе до неправильного навколишнього світла, якщо поверхні дуже нерегулярні і між водоймами, що впливають на ті самі фрагменти, є велика кількість повітря.
Плюси і мінуси такі ж, як і для звичайного тіньового відображення, за винятком того, що вам потрібен ще один буфер під час обчислення глибини, а продуктивність гірша, тому що ви повинні намалювати більше геометрії.
Рейкове трасування є на сьогодні найбільш точним, але також найдорожчим рішенням для надання прозорих томів. Це можна зробити двома способами: 1. Простеження від дна океану до поверхні та 2. Відстеження від джерела світла до води. Для розрахунку яскравості для кожної точки на підлозі потрібно кілька променів.
Є кілька речей, які слід враховувати при подачі води:
Світло у воді знову розсіюється під час подорожі до спостерігача, тому вам слід змішати його із суцільним кольором.
Якщо спостерігач занурений , ви можете просто вивести туман на основі кінцевого результату глибини буфера. Колір туману, але не його густина, повинен змінюватися в залежності від відстані спостерігача від поверхні! (Minecraft використовує лише цю частину ефекту.)
Якщо спостерігач дивиться на воду зверху , потрібно обчислити туман, виходячи з різниці глибини між поверхнею та геометрією під водою. Колір туману повинен стати трохи темнішим при більших перепадах глибини, але він повинен змінюватися лише до тієї точки, де туман повністю непрозорий.
Колір туману також повинен залежати від напрямку перегляду для кожного пікселя, тому він виглядає трохи темніше при огляді вниз в обох випадках.
Якщо ви використовуєте безшовну плиткову 3D-текстуру замість наклейки для підробленої їдкої їжі, ви можете уникнути розтягування на вертикальні поверхні. Сила розсіяного світла біля поверхні змінюється в трьох вимірах, тому використання 2D-текстури зазвичай створює розтягнення десь на сцені. Можна моделювати зміни кутів світла, проектуючи вершинні положення підлоги в іншу систему координат.
Іншою можливістю є обчислення щільності світла на основі положення поверхні в системі координат світла, хоча це, швидше за все, коштуватиме певної продуктивності.
Каустики повинні згасати швидше, ніж розсіяне світло зі збільшенням глибини.
Кольори розкидаються по-різному, тому світлий колір повинен змінюватися зі збільшенням глибини. Це також запобігає різким узліссям, де, наприклад, пляж перетинає водну поверхню.
Через заломлення світло потрапляє на океанське дно набагато крутіше, ніж зазвичай. Стаття у Вікіпедії про закон Снелла має формули для кутів та векторів.
Я вважаю, що ефект освітлення неба в Minecraft прямо знижується - все затьмарюється тим, що знаходиться над ними, незалежно від того, де знаходиться сонце. Тоді місцеве освітлення від смолоскипів тощо застосовується з ефектом випадання - чим далі від джерела світла, тим менше світла отримує куб.
Якщо зробити це таким чином, кожен шар води сукупно затінить шар під ним, тож кожен стає прогресивно темнішим. Дерево листя надає подібний відтінок, однак воно не є кумулятивним. Ви отримуєте однаковий відтінок під деревом, будь то 1 або 100 кубів листя.
Одне поняття, що це метод, який застосовується, - це те, що вода не стає темнішою, якщо далі від глядача - лише під час спуску вниз. Так, ефект туману дає удар на відстань, але не ефект темної води.
Отже, основна формула для обчислення освітлення була б приблизно такою в псевдокоді ...
light_on_cube = 1.0
for each cube above target cube, from lowest to highest {
if cube being examined is tree foliage
light_on_cube = 0.5
else if cube being examined is water
light_on_cube = light_on_cube - 0.1
else if cube being examined is solid
light_on_cube = 0
}
Це не ідеально підходить для розрахунку освітлення під навісами або в печерах, оскільки це було б темно під накидом за допомогою цього методу. Але можна додати як локальні джерела світла (смолоскипи, пожежі тощо), так і трактувати блоки, освітлені сонцем, як джерела світла. Щось подібне може це зробити ...
Ідея тут полягає в тому, що якщо куб освітлений сонцем або факелом, куб поруч також буде певним чином засвічений. І чим далі ви будете від того освітленого куба, тим менше світла буде. Це щось на зразок хитрості для оцінки дифузного освітлення, але я думаю (?), Що це спрацює.
Можливо, я не розумію питання, але чому ви не можете просто змінити колір блоків залежно від їх глибини?
Якщо у вас глибина d (в блоках, починаючи з 0), то розумним рівнянням яскравості буде:
L = (1- m ) e - kd + m
Код: L = (1.0 - m) * exp(-k * d) + m;
k керує тим, наскільки швидко стає темніше (вище = швидше). Доцільне значення було б 0,5.
m - мінімальна яскравість, яку ви бажаєте.
L варіюється від 0 до 1.
Якщо ви не знаєте, як змінити колір блоків у будь-якому графічному API, який ви використовуєте, то запитайте це як окреме запитання (вказуючи, який API ви використовуєте та чи використовуєте ви шейдери чи ні).
e^-kd
Біт просто експонентний спад, який є стандартною функцією для речей , які поступово наближаються до нуля в протягом деякого значення (глибини). Множення на (1-m)
додавання та додавання m
просто розширюють та компенсують занепад так, що він закінчується як мінімум, m
але все ще починається з 1
. en.wikipedia.org/wiki/Exponential_decay