Comments 40
Для тех у кого «шейдеры = магия», это как раз то, что позволяет дать начальное понимание этой кухни.
https://www.shadertoy.com/results?query=tag%3Dgame
uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
Инпут с клавиатуры тоже появился вскоре как текстура. Но основная проблема была в том, что негде было промежуточный стейт хранить. И только с появлением рендера в текстуру стало возможным писать вот такие игры.Было бы здорово в будущем увидеть статью о тех подходах, которые используют в реальных шейдерах для игр. Например, хотя все примеры из статьи мне показались тривиальными, я всё равно не могу понять, как таким методом попиксельной обработки можно из верхней половины картинки из майнкрафта получить нижнюю.
Например, вода. Как я понимаю, там каким-то образом должен учитываться наклон поверхности относительно линии взгляда и окружающие объекты, причём с учётом их положения в 3D-пространстве. Я даже предположить не могу, как всё это получается только лишь попиксельными манипуляциями с плоской картинкой.
Или освещённость. Там явно как-то учитывается, какой стороной поверхности повёрнуты к солнцу. Как этого добиться с помощью принципов, описанных в статье?
Движок игры создаёт дополнительные однобитные (обычно) маски — например, картинку, в которой каждый пиксель тем темнее, чем под более острым углом повёрнута к камере поверхность, с которой он взят. Или картинку, в которой каждый пиксель тем темнее, чем дальше от камеры поверхность под ним. И всё это тоже скармливается шейдеру. Вместе с картами теней и прочей мурой. Не всякий шейдер, кстати, как-то влияет на выходную картинку — некоторые выполняют чисто технические задачи.
Например диффузная компонента обычного Фонга — это косинус угла между инвертированной нормалью и направлением света.
Скалярное произведение двух векторов это результат умножения длин векторов на косинус между ними: |a||b|cos(ab)
Если длины векторов равны единицы, то скалярное произведение вернет косинус. Именно то, что нам нужно для освещения.
Для specular компоненты фонга — вектор луча сначала отражают вдоль нормали, а потом смотрят насколько он попадает в глаз. Через то же самое скалярное произведение.
Углы там никто не считает, а скалярное произведение от нормализованных векторов возвращает косинус угла, вот его и используют.
А теперь то же самое, но по русски и чуть подробнее. Я не игродел, а описал решение как оно было сделано в одной программе для проектирования шкафов (из ДСП). Там уровень освещенности поверхности рассчитывался, реально, в шейдере.
Млиииин! ОдноБАЙТные маски у меня там были.
https://habrahabr.ru/company/infopulse/blog/324476/#comment_10129732
А вот в псевдокоде вычисление коэффициента диффузного освещения (diffK)
vec3 N = normalize(pixelNormal); // pixelNormal - нормаль к поверхности в освещаемом пикселе
vec3 lightN = normalize(lightDir); // lightDir - вектор от источника света на освещаемый пиксель
float diffK = dot(-N, lightN); //косинус угла между этими векторами, наш коэффициент диффузного освещения
diffK = clamp(diffK, 0, 1); //но нас интересуют только положительные косинусы, обрезаем отрицательную часть
new_pic(x,y) = old_pic( x+dx(x,y), y+dy(x,y) )
где d — ограниченная и (почти) гладкая функция.
Тут подробнее ответил
Интересно, почему переменные называются юниформные? И откуда они берутся? Если их передает ShaderToy, то, получается, в голом JS без обвязки написанные шейдеры перестанут работать? Если нет, то где полный список?
Крайне надеюсь на продолжение.
https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders-part-2--cms-24111
https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders-part-3--cms-24351
Так что да, все равно надеюсь на продолжение =)
спасибо за статью, вечер удался
https://www.shadertoy.com/view/XdfcWl
даже руки зачесались. слегка перепилил, вроде стало ещё круче. ))
https://www.shadertoy.com/view/lssyDl
На мой вкус слишком шумно получается :)
Еще сделал вариацию своего прошлого: https://www.shadertoy.com/view/4dscWs
Единственным предназначением шейдера является вернуть четыре числа: r, g, b и a.
Люблю когда простые вещи объясняют просто. Отличная статья, спасибо за перевод!
Руководство начинающего программиста графических шейдеров