Главная -
Статьи -
Проекты -
Ссылки -
Скачать -
Из гельминтов -
Юмор, приколы -
Почитать -
Обо мне -
Мысли -
Гостевая -

Расширение NV_texture_shader в его использование в OpenGL

Впервые появившееся на графических ускорителях GeForce 3 расширение NV_texture_shader позволяет изменить механизм применения текстур в OpenGL. Вместо традиционной модели OpenGL вводится понятие шагов текстурирования (texture stage), каждому такому шагу соответствует текстурный блок и на каждом из этих шагов работает одна из 21 предопределенных программ (шейдеров, shaders), опредеяющая выходной цвет для данного текстурного блока.

Каждая из этих программ в качестве входных данных берет интерполированные текстурные координаты (s,t,r,q) для соответствующего текстурного блока и выдает два значения - RGBA-значение, которое выступает как значение с данного текстурного блока (например, при работе с register combiner's) и результат данного шага, который может быть использован на следующих шагах.

Отдельные программы могут приводить к различным побочным эффектам - отбрасыванию данного фрагмента или изменению значения глубины для данного фрагмента в буфере глубины.

Реализация текстурирования с использованием расширения NV_texture_shader

Рис 1. Реализация текстурирования с использованием расширения NV_texture_shader

Для проверки поддержки расширения NV_texture_shader следует использовать

	isExtensionSupported ( "GL_NV_texture_shader" )

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

Используемые программы (собственно и называемые шейдерами - texture shaders) можно разбить на четыре группы:

  1. Обычные операции текстурирования
  2. Специальные режимы текстурирования
  3. Режимы, зависящие от результатов другого шага
  4. Режимы, зависящие от результатов другого шага и использующие скалярное произведение

Для включение этих шейдеров служит команда

	glEnable ( GL_TEXTURE_SHADER_NV );

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

Также обратите внимание на то, что некоторые шейдеры возвращают в качестве выходного RGBA значения нулевой вектор (0,0,0,0) независимо от текстуры, выбранной в данном блоке текстурирования.

Обычные операции текстурирования

1. Одномерные текстуры (Texture 1D)

Данная операция возвращает значение одномерной текстуры по параметру (s/q).

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s,t,r,q)Texture 1D(s/q)Любаяtex(s/q)

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_1D );

2. Двухмерные текстуры (Texture 2D)

Данная операция возвращает значение двухмерной текстуры по параметру (s/q,t/q).

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s,t,r,q)Texture 2D(s/q,t/q)Любаяtex(s/q,t/q)

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

2. Прямоугольные текстуры (texture rectange)

Это новый тип текстуры (NV_texture_rectangle) позволяющий размерам текстуры width и height не являться степенью двух, а быть произвольными целыми числами.

Текстурные координаты s и t для таких текстур принимают значения в области [0,width]x[0,height] вместо единичного квадрата.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s,t,r,q)Texture rectangle(s/q,t/q)Любая прямоугольнаяtex(s/q,t/q)

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_RECTANGLE_NV );

2. Кубические текстуры (Texture Cube Map)

Этот шейдер соответствует обычной кубичесмкой карте.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s,t,r)Texture cube map(q,t,r)Любая кубическаяcubeMap(s,t,r)

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB );

Специальные режимы текстурирования

1. None

Данный шейдер вообще не обращается к текстуре, игнорирует переданные текстурные координаты и всегда возвращает нулевой вектор (0,0,0,0).

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE );

2. Pass through

Данный шейдер также не обращается к текстуре и просто возвращает в качестве выходного RGBA значения текстурыне координаты, усеченные по отрезку [0,1].

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s,t,r,q)r=clamp(s)
g=clamp(t)
b=clamp(q)
a=clamp(q)
нетЛюбая(r,g,b,a)

Установить данный режим можно командой

	glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV );

3. Отсечение фрагмента (cull fragment)

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

Для каждой текстурной координаты ставится свое условие прохождения. Это условие может быть либо GL_GEQUAL (значение соответствующей координаты больше или равно нулю), либо GL_LESS (значение соответствующей координаты отритцательно).

Если для хотя бы одной из четырех текстурных координат условие прохождения не выполняется, то фрагмент отбрасывается. В противном случае фрагмент проходит и в качестве выходного RGBA значения выступает нулевой вектор (0,0,0,0).

Пример.
    int  cullModes [4] = { GL_LESS, GL_LESS, GL_GEQUAL, GL_LESS };

    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV );
    glTexEnviv ( GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV, cullModes );

Режимы, зависящие от результатов другого шага

Все шейдеры из этой группы позволяют взять значение из одной текстуры и использовать его для адресации другой текстуры.

Поэтому данный шаг всегда использует RGBA результат другого шага, причем эти шаги не обязаны следовать друг за другом. Для простоты мы будем нумеровать шаги, начиная с нуля.

1. Dependent alpha-red texturing

Данный шейдер берет красную (R) и альфа (А) компоненты с одного из шагов текстурирования (не обязательно предыдущего) и использует их в качестве текстурных координат для доступа к другой двухмерной текстуре.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0зависят от приложениязависит от текстурызависит от текстурыЛюбая 2D RGBA текстураRGBA
1игнорируютсянет(a,r)Любая 2D RGBA текстураtex1(r,a)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB );

2. Dependent green-blue texturing

Данный шейдер полностью аналогичен предыдущему и отличается от него только тем, что в качестве текстурных координат для доступа к другой текстуре используются зеленая (G) и синяя (B) компоненты.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0зависят от приложениязависит от текстурызависит от текстурыЛюбая 2D RGBA текстураRGBA
1игнорируютсянет(g,b)Любая 2D RGBA текстураtex1(g,b)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB );

3. Offset texture 2D

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

При этом полученные из текстуры два значения умножаются на матрицу 2х2 из вещественных чисел и полученные значения добавляются к обычным текстурным координатам.

Этот шейдер использует новые форматы текстур - GL_DSDT_NV (два знаковых канала, по 8 бит на канал), GL_DSDT_MAG_NV (три 8-битовых канала, последний из них беззнаковый) и GL_DSDT_MAG_INTENSITY_NV (четыре канала, последние два беззнаковых) канала).

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s0,t0,r0q0)Texture 2D(s0/q0,t0/q0)2D DSDT(0,0,0,0)
ds,dt
1(s1,t1)Texture 2Ds'1=s1+k0*ds+k2*dt
t'1=t1+k1*ds+k3*dt
Любая 2D RGBA текстураtex1(s'1,t'1)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    float	k [4] = { 0.3, 0.5, 0.7, 0.5 };

    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB );
    glTexEnvfv ( GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, k );

4. Offset texture 2D scale

Данный шейдер аналогичен предыдущему, но здесь RGB компоненты выходного цвета подвергаются масштабированию при помощи коэффициента MAG, вычисляемого при помощи задаваемых пользователем значений kscale и kbias.

Обратите внимание, что альфа канал масштабированию не подвергается.

В случае, если текстура, задающая смещение, имеет формат GL_DSDT_MAG_INTENSITY, то на соответствующем текстурном блоке возвращается яркость во всех каналах ((i,i,i,i)).

tex1(s'1,t'1)
ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s0,t0,r0q0)Texture 2D(s0/q0,t0/q0)2D DSDT_MAG(0,0,0,0)
ds,dt,mag
1(s1,t1)s'1=s1+k0*ds+k2*dt
t'1=t1+k1*ds+k3*dt
M=kscale*mag+kbias
tex(s'1,t'1)Любая 2D RGBA текстура(R*M,G*M,B*M,A)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    float	k [4] = { 0.3, 0.5, 0.7, 0.5 };

    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );
    glTexEnvfv ( GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,   k );
    glTexEnvf  ( GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, 0.7 );
    glTexEnvf  ( GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV,  0.2 );

Шейдеры, использующие скалярное произведение

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

1. Dot Product

Этот шейдер просто вычисляет скалярное произведение RGB значения предыдущего шага (они могут быть знаковыми или беззнаковыми, в последнем случае они могут преобразованы в отрезок [-1,1]) (GL_SIGNED_RGB_NV или GL_SIGNED_RGBA_NV), а также 16-битовые текстуры (GL_SIGNED_HILO_NV, GL_UNSIGNED_HILO_NV).

При использовании безнаковых RGB(A) текстур можно задать преобразование их в отрезок [-1,1] или же использовать их как они есть.

Это осуществляется следующей командой

    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, param );

В случае, когда параметр param принимает значение GL_EXPAND_NORMAL_NV происходит преобразование компонент в отрезок [-1,1] аналогично тому, как это делается в расширении register combiners. В случае, когда значение параметра равно GL_UNSIGNED_IDENTITY_NV компоненты используются в скалярном произведении как они есть, без каких-либо преобразований.

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

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

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

2. Dot Product Texture 2D

Данный шейдер вычисляет два скалярных произведения и использует их для обращения к текстуре. Предыдущим шагом должно быть скалярное произведение (GL_DOT_PRODUCT_NV).

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0Зависит от приложенияЗависит от текстурыЗависит от текстуреЛюбая RGB(A)(r0,g0,b0)
1(s1,t1,r1)ux=((r0,g0,b0),(s1,t1,r1))НетНет(0,0,0,0)
2(s2,t2,r2)uy=((r0,g0,b0),(s2,t2,r2))tex(ux,uy)2D RGBAtex2D(ux,uy)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

3. Dot Product Rectange

Полностью анаологичен предыдущему шейдеру, но на последнем шаге используется текстура типа NV_texture_rectange.

4. Dot Product Texture Cube Map

Данный шейдер аналогичен dot product texure 2D, но здесь используется два промежуточных скалярных произведения, еще одно вычисляется на этом шаге и три полученных значения используются для доступа к кубической карте.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0Зависит от приложенияЗависит от текстурыЗависит от текстуреЛюбая RGB(A)(r0,g0,b0)
1(s1,t1,r1)ux=((r0,g0,b0),(s1,t1,r1))НетНет(0,0,0,0)
2(s2,t2,r2)uy=((r0,g0,b0),(s2,t2,r2))НетНет(0,0,0,0)
3(s3,t3,r3)uz=((r0,g0,b0),(s3,t3,r3))u=(ux,uy,uz)Cube Map RGBAcubeMap(ux,uy,uz)

Часто в качестве текстурных координат на очередном шаге служат очередные компоненты базиса касательного пространства (t,b,n) - сперва (tx,bx,nx), потом (ty,by,ny) и наконец (tz,bz,nz).

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 3
    glActiveTextureARB ( GL_TEXTURE3_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

5. Dot Product Constant Eye Reflect Cube Map

Данный шейдер, как и предыдущий, использует три скалярных произведения для получения трехмерного вектора, но для доступа к кубической карте использется не сам полученный вектор u, а отраженный вектор r, вычисляемый по следующей формуле:

r=2*u*(u,e)/(u,u)-e

Здесь e - это положение наблюдателя, которое считается постоянным и задается отдельной командой.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0Зависит от приложенияЗависит от текстурыЗависит от текстуреЛюбая RGB(A)(r0,g0,b0)
1(s1,t1,r1)ux=((r0,g0,b0),(s1,t1,r1))НетНет(0,0,0,0)
2(s2,t2,r2)uy=((r0,g0,b0),(s2,t2,r2))НетНет(0,0,0,0)
3(s3,t3,r3)uz=((r0,g0,b0),(s3,t3,r3))
u=(ux,uy,uz)
r=2u(u,e)/(u,u)-e
(rx,ry,rz)Cube Map RGBAcubeMap(rx,ry,rz)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 3
    float	eye [3] = { -5, 0, 0 };

    glActiveTextureARB ( GL_TEXTURE3_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );
    glTexEnvfv ( GL_TEXTURE_SHADER_NV, GL_CONSTANT_EYE_NV, eye );

6. Dot Product Reflect Cube Map

Этот шейдер аналогичен предыдущему, но здесь координаты наблюдателя передаются в текстурной координате q.

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0Зависит от приложенияЗависит от текстурыЗависит от текстуреЛюбая RGB(A)(r0,g0,b0)
1(s1,t1,r1,q1)ux=((r0,g0,b0),(s1,t1,r1))НетНет(0,0,0,0)
2(s2,t2,r2,q2)uy=((r0,g0,b0),(s2,t2,r2))НетНет(0,0,0,0)
3(s3,t3,r3,q3)uz=((r0,g0,b0),(s3,t3,r3))
u=(ux,uy,uz)
e=(q1,q2,q3)
r=2u(u,e)/(u,u)-e
(rx,ry,rz)Cube Map RGBAcubeMap(rx,ry,rz)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 3
    glActiveTextureARB ( GL_TEXTURE3_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

7. Dot Product Diffuse Cube Map

Предыдущие расширение для получения отраженного вектора r вычисляет вектор u, который фактически является преобразованным в касательное пространство вектором нормали (возможно не единичным).

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

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

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0Зависит от приложенияЗависит от текстурыЗависит от текстуреЛюбая RGB(A)(r0,g0,b0)
1(s1,t1,r1,q1)ux=((r0,g0,b0),(s1,t1,r1))НетНет(0,0,0,0)
2(s2,t2,r2,q2)uy=((r0,g0,b0),(s2,t2,r2))
uz=((r0,g0,b0),(s3,t3,r3))
(ux,uy,uz)Cube Map RGBAcubeMap(ux,uy,uz)
3(s3,t3,r3,q3)u=(ux,uy,uz)
e=(q1,q2,q3)
r=2u(u,e)/(u,u)-e
(rx,ry,rz)Cube Map RGBAcubeMap(rx,ry,rz)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 3
    glActiveTextureARB ( GL_TEXTURE3_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

8.Dot Product Depth Replace

Этот шейдер позволяет выводить грань, параллельную экрану, с заданной картой глубин (depth sprite). Для получения наибольшой точности лучше всего использовать беззнаковую текстуру HILO.

По текстуре на данном шаге вычисляется два скалярных произведения, отношение которых и дает значение глубины. Если это значение лежит в пределах [znear,zfar], то он записывается в буфер глубины. В противном случае фрагмент отбрасывается.

Предыдущим шагом должно быть скалярное произведение.

Работа шейдера dot product depth replace

Рис. 2 Работа шейдера dot product depth replace (рисунок взят из презентации компании NVDIA)

ШагТекстурные
координаты
ШейдерОбращение к текстуреФормат текстурыВыходное значение
0(s0,t0,r0,q0)Texture 2D(s0/q0,t0/q0)Беззнаковая HILO(0,0,0,0)
1(zscale,zscale/216,zbias)Z=(zscale,zscale/216,zbias),(H,L,1))НетНет(0,0,0,0)
2(wscale,wscale/216,wbias)W=(wscale,wscale/216,wbias),(H,L,1))
zw=Z/W
НетНет(0,0,0,0)

Пример.
                              // setup stage 0
    glActiveTextureARB ( GL_TEXTURE0_ARB );
    glTexEnvi ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D );

                              // setup stage 1
    glActiveTextureARB ( GL_TEXTURE1_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

                              // setup stage 2
    glActiveTextureARB ( GL_TEXTURE2_ARB );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV );
    glTexEnvi  ( GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,  GL_TEXTURE0_ARB );

Обратите внимание, что в ряду случаев при неправильном задании данных, шаг текстурирование может находится в ошибочном (inconsistent) состоянии. В этом случае данный шаг работает, как если бы в нем была установлена операция GL_NONE.

Узнать состояние шага можно при помощи следующего фрагмента кода

    GLint consistent;

    glActiveTextureARB ( stage_to_check );
    glGetTexEnviv      ( GL_TEXTURE_SHADER_NV, GL_SHADER_CONSISTENT_NV, &consistent );

При подготовке статьи использовались материалы компании NVIDIA.

Дополнительную информацию по данному расширению можно найти на OpenGL Extension Registry, а также на сайте компании NVIDIA.


Copyright © 2004 Алексей В. Боресков