Есть необходимость задавать для вершин некоторую величину, которая должна интерполироваться в процессе растеризации и уже в интерполированном виде поступать на вход фрагментного шейдера, который на основе интерполированного значения должен вычислять цвет.
Можно ли как-то обойтись без вертексного шейдера, каким-то образом заставив фиксированную часть OpenGL-конвейера интерполировать при растеризации кастомные атрибуты вершин, точно так же, как она интерполирует стандартные атрибуты (цвет, нормали, позицию), чтобы получить интерполированные значения кастомных атрибутов на входе фрагментного шейдера. Уж больно не хочется реализовывать всю вертексную часть фиксированного конвейера вручную в вертексном шейдере.
Насколько я понял, в GLSL для интерполяции предназначены varying variable, которые я могу (если праивльно понял) задать произвольно в качестве входных в фрагментном шейдере, но не знаю, можно ли и как сопоставить произвольную varying variable нужному кастомному атрибуту.
Версию OpenGL API в студию. Не varying, а лучше атрибут вершины.
Нет.
Версия - черт ее знает, пусть, скажем, 3.x.
Не varying, а лучше атрибут вершины
ну я так и хочу задавать - пользовательский атрибут у каждой вершины. но как заполучить интерполированные значения этого атрибута в фрагментном шейдере без реализации вертексного шейдера? Собственно, у меня уже почти получилось обойтись только фрагментным шейдером, когда я вместо пользовательского атрибута использовал атрибут цвета для передачи нужного значения, но возникла проблема из-за клиппирования значений цвета еще до интерполяции.
Нет
А как вообще правильно реализовать то, что мне нужно? Каждой вершине приписано значение из неограниченного диапазона, есть функция зависимости цвета от этого значения, в промежуточных точках примитивов цвет должен определяться интерполяцией приписанного значения, но не интерполяцией цвета. Являются ли шейдеры единственным путем решения данной задачи, или, может быть, есть способ попроще?
Dmitry_Milk
> Можно ли как-то обойтись без вертексного шейдера, каким-то образом заставив
> фиксированную часть OpenGL-конвейера интерполировать при растеризации кастомные
> атрибуты вершин, точно так же, как она интерполирует стандартные атрибуты
> (цвет, нормали, позицию), чтобы получить интерполированные значения кастомных
> атрибутов на входе фрагментного шейдера.
Нельзя.
Ты можешь использовать вершинный шейдер без фрагментного, но наоборот делать нельзя.
> А как вообще правильно реализовать то, что мне нужно?
Использовать вершинный шейдер.
Если версия 3.0 или выше, то фиксированного конвейера там уже нет. Все равно придется использовать вершинный шейдер, хочешь ты этого или нет. См. урок №2
А почему такое нежелание заюзать вершинный шейдер?
Все, спасибо всем ответившим, сделал вертексный шейдер тоже.
Не так сложно оказалось, ftransform сделал все, что нужно.
Осталось победить юниформ, зараза не хочет раскрывать свой локейшн.
Ты можешь использовать вершинный шейдер без фрагментного, но наоборот делать нельзя.
Все же похоже можно. Во-первых еще до того, как я запостил сюда вопрос, у меня уже работала версия только с фрагментным шейдером, но без вершинного (необходимые данные я передевал через атрибут цвета).
Да и в спецификациях OpenGL мне такого запрета нигде не встречалось. Вот, например, спецификация Version 4.4 (Core Profile) - March 19, 2014 (http://www.opengl.org/registry/doc/glspec44.core.pdf), Chapter 7 Programs and Shaders
Vertex shaders describe the operations that occur on vertex attributes. Tessel-
lation control and evaluation shaders are used to control the operation of the tes-
sellator, and are described in section 11.2. Geometry shaders affect the processing
of primitives assembled from vertices (see section 11.3). Fragment shaders affect
the processing of fragments during rasterization (see section 15). A single program
object can contain all of these shaders, or any subset thereof.
Dmitry_Milk
> Все же похоже можно. Во-первых еще до того, как я запостил сюда вопрос, у меня
> уже работала версия только с фрагментным шейдером, но без вершинного
> (необходимые данные я передевал через атрибут цвета).
Я ошибся. Ты прав. Вот из спеки 2.1:
If the program object has no vertex shader, or no program object is currently in use, the fixed-function method for processing vertices is used instead.
> Да и в спецификациях OpenGL мне такого запрета нигде не встречалось. Вот,
> например, спецификация Version 4.4 (Core Profile) - March 19, 2014
> (http://www.opengl.org/registry/doc/glspec44.core.pdf), Chapter 7 Programs and
> Shaders
В OpenGL 4.4 Core у тебя нет FFP. В компатибл профиле только если использовать.
ИМХО лучше не мешать ФФП и шейдеры, а лучше вообще ФФП не использовать ни в каком виде.
Всё равно они заменяются на шейдеры, ибо ГПУ уже давно ФФП не умеют.
> Осталось победить юниформ, зараза не хочет раскрывать свой локейшн.
Что ты имеешь ввиду? Возвращает -1?
Что ты имеешь ввиду? Возвращает -1?
Да, -1. Оба шейдера скомпилированы успешно, программа слинкована успешно. Шейдеры работают как нужно. Причем юниформная переменная (скалярный float) получает, похоже, по умолчанию, значение 1. (странно, почему не 0).
Dmitry_Milk
-1 может возвращаться, если ты нигде не используешь юниформ.
вертексный
in uniform float intensity_scale; out varying float intensity; void main() { gl_Position = ftransform(); intensity = gl_Vertex.y * intensity_scale; }
фрагментный
in float intensity; void main() { gl_FragColor = smoothstep(vec4(0, 0, -0.125, -1), vec4(0.5, 0.0625, -0.0625, 0), intensity * vec4(1, 1, -1, 0)) - clamp(vec4(0, (intensity - 0.5) * 2, 0, 0), 0.0, 1.0); }
Оба шейдера скомпилированы успешно, программа слинкована успешно, выбрана и работает
glGetUniformLocation(program, "intensity_scale") возвращает -1
напиши просто
uniform float intensity_scale;
Dmitry_Milk
> in uniform float intensity_scale;
> out varying float intensity;
Не правильно.
uniform float intensity_scale; out float intensity;
Ещё ИМХО надо добавить версию ГЛСЛ.
И хорошо бы избавится от ftransform().
Да, лучше сразу полностью переходить на OpenGL 3.3+
Дальше будет проще.
Тема в архиве.