Як я можу реалізувати оклюзійне освітлення в 2-грі на основі блоку?


11

Я хочу мати 2D освітлення, яке можна заблокувати в ігрових об'єктах. У моїй грі є вид зверху вниз, і всі об’єкти гри описуються прямокутниками.

Скажімо, у мене світ 10x10, і я розміщую світло на 1х1 і стіни навколо цього світла. Я хочу мати можливість бачити джерело світла на 1х1, але ніде більше, оскільки воно перекрите стінами.

Я чув, як працює лиття світлових променів, але як це реально працює?


1
Хотіли б побачити деякі мовно-агностичні відповіді на це питання.
Дашто

2
@Dashto: Вам потрібна робоча частина коду мовою, якою ви користуєтесь? Це неправильне місце для запитання ..
Кромстер

Що ви пробували? Коли ви говорите «ніде більше, щоб не було джерела світла», що ви маєте на увазі? Просто засвітив ти 1,1 блок, і все. Можливо, я не розумію вашого питання, чи можете ви опублікувати ілюстрацію?
Лоран Кувіду

1
@Krom Stern: Я прошу точно протилежне, насправді - концептуальна відповідь, яка не залежить від мови. Дві нитки, пов'язані як дублікати, не дуже говорять про ці поняття. Насправді більшість подібних питань на цьому веб-сайті просто мають відповіді із записом "Використовуйте цю бібліотеку!" що менш корисно для того, хто хоче зрозуміти, як це працює.
Дашто

@Dashto: Це важлива інформація, ви повинні додати це питання;)
Kromster

Відповіді:


13

Аміт Патель написав дуже приємну статтю про 2D-кастинг.

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

введіть тут опис зображення

Усі наочні приклади інтерактивні в дописі і дуже легко зрозуміти.

Вам також не потрібно обмежуватися коробкою, периметр, який ви простежуєте, може бути будь-якої форми, яка вам подобається.


1

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

Ось як це може виглядати .


Я просто запитав, як я використовую рентгенівський кастинг. Я про це знаю.
LiquidFeline

0

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

Спочатку створіть світлопроменевий об’єкт. Розмістіть світло за координатами x, y.

#include <math.h>
int i = 0;
if ( sqrt( abs( light.x - vertex.x )^2 + abs( light.y - vertex.y )^2 ) <= light.radius)
{
    lightOccludingVertices[i] = vertex;
    i++;
}

//If two or more vertices are both a member of an individual wall,
//illuminate the triangular area between the light, the furthest 
//vertex on the x-axis, and the furthest vertex on the y-axis

Це не гарантовано для роботи увігнутого багатокутника, але він повинен спрацьовувати добре для будь-яких опуклих багатокутників.

Це спрацює, якщо ваші оклюзійні предмети (стіни, персонаж, літаючі фіолетові їдять люди) будуть намальовані на екран після застосування освітлення. Інакше половина стіни виявиться значно яскравішою, ніж інша половина. Якщо ваш точковий світло рівновіддалений від двох пар вершин однієї стіни (рівно наполовину більше, ніж висота вашої стіни), застосуйте трикутник до двох найближчих вершин, а не двох далі.

Я також повинен зазначити, що для цього методу потрібна динамічно створена вершинна точка, де край радіуса світла відповідає поверхні оклюзійного об'єкта. Це створює мінімум 3 вершини для будь-якого оклюзійного об'єкта і дозволить стінам, що простягаються повз радіус світла (або поза екраном), також блокувати будь-яке світло.

Детальніше про увігнуті та опуклі багатокутники

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