WebGL / GLSL - как работает ShaderToy?

я стучал вокруг Shadertoy -https://www.shadertoy.com/ - недавно, в попытке узнать больше о OpenGL и GLSL в частности.

из того, что я понимаю до сих пор, пользователь OpenGL сначала должен подготовить всю геометрию для использования и настроить сервер OpenGL (количество разрешенных огней, хранение текстуры и т. д.). После этого пользователь должен предоставить по крайней мере одну программу шейдера вершин и одну программу шейдера фрагментов перед OpenGL программа компилируется.

однако, когда я смотрю на образцы кода на Shadertoy, я вижу только одну программу шейдеров, и большая часть используемой геометрии, похоже, записана непосредственно в код GLSL.

Как это работает?

Я предполагаю, что вершинный шейдер уже подготовлен заранее, и что редактируемый/образец шейдера является только шейдером фрагментов. Но тогда это не объясняет геометрию в некоторых более сложных примеров...

может кто-нибудь объясните, как работает Shadertoy?

4 ответов


ShaderToy-это инструмент для написания пиксельных шейдеров.

что такое пиксельные шейдеры?

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

так, атрибуты всегда один и тот же, а также вершинный шейдер:

positions = [ [-1,1], [1,1], [-1,-1], [1,-1] ]
uv = [ [0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0] ]

и этот quad отображается как TRIANGLE_STRIP. Кроме того, вместо установки UVs явно, некоторые предпочитают использовать встроенную переменнуюgl_FragCoord, который затем делится, например, на uniform vec2 uScreenResolution.

вершинный шейдер:

attribute vec2 aPos;
attribute vec2 aUV;
varying vec2 vUV;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
    vUV = aUV;
}

и фрагмент шейдера будет выглядеть примерно так:

uniform vec2 uScreenResolution;
varying vec2 vUV;

void main() {
    // vUV is equal to gl_FragCoord/uScreenResolution
    // do some pixel shader related work
    gl_FragColor = vec3(someColor);
}

ShaderToy может предоставить вам несколько униформ по умолчанию,iResolution (ака uScreenResolution),iGlobalTime, iMouse,... который вы можете использовать в своем пиксельном шейдере.

для кодирования геометрии непосредственно в шейдер фрагментов (он же пиксельный шейдер) разработчик использует то, что называется трассировкой лучей. Это довольно сложная область программирования, но короче: Вы представляете свою геометрию через некоторые математические формулы, а затем в pixel shader, когда вы хотите проверить, является ли какой-то пиксель частью вашей геометрии, вы используете эту формулу для получения этой информации. Google-ing немного должен дайте вам много ресурсов, чтобы прочитать, из чего и как точно построены трассировщики лучей, и это может помочь: как сделать трассировку лучей в современном OpenGL?

надеюсь, что это помогает.


ShaderToy отображает простой GLSL, который запрограммирован для обработки всего освещения, геометрии и т. д. Это не геометрия вершин, это большая часть его, 3D-материал, или вы можете делать 2D-шейдеры и т. д.

любой цвет и пространственная математика могут быть запрограммированы на языке GLSL. Комбинации продвинутых алгоритмов делают изоповерхности, фигуры, а затем проецируют текстуры на изоповерхности, и raycasting, отправляя воображаемые линии от зрителя на расстояние, перехватывает что-либо на пути, есть многие методы raycasting для 3D.

посетить www.iquilezles.org для представления о различных инструментах, которые используются в shadertoy / glsl graphics


Это просто в основном нажатие исходного кода GLSL pixel shader непосредственно на графическую карту.Настоящая магия происходит в невероятно умных алгоритмах, которые люди используют для создания удивительных эффектов, таких как Рэй марш, Рэй кастинг, Рэй трассировка. лучше всего взглянуть на некоторые другие живые песочницы GLSL, такие как:http://glsl.heroku.com/ и http://webglplayground.net/. Его в основном создание окна обычно два треугольника, которые представляют экран, а затем шейдер работает на каждом пикселе так же, как трассировщик лучей.
Я смотрел на них некоторое время, и алгоритмы, которые люди используют, сногсшибательны, вам понадобятся серьезные математические отбивные и посмотрите исходный код "демо-кодирования", чтобы обернуть вокруг них голову. Многие на shader toy, просто взорвите свой разум ! Итак, чтобы подвести итог, вам просто нужно изучить кодирование и алгоритмы шейдеров GLSL. Не простое решение.


традиционно в компьютерной графике геометрия создается с использованием вершин и визуализируется с использованием некоторых видов материалов (например, текстур с подсветкой). В GLSL вершинный шейдер обрабатывает вершины, а фрагментный (пиксельный) шейдер обрабатывает материалы.

но это не единственный способ определения формы. Точно так же, как текстура может быть процедурно определена (вместо поиска ее текселов), форма может быть процедурно определена (вместо поиска ее геометрия.)

таким образом, подобно трассировке лучей, эти шейдеры фрагментов могут создавать фигуры без их геометрии, определенной вершинами.

есть еще больше способов определения фигур. Е. Г. данные объем (воксели), поверхности кривые, и так далее. Текст компьютерной графики должен охватывать некоторые из них.