2015-08-13 2 views
-1

Я пытаюсь понять, как работает кодирование в openGL. Я нашел этот код в Интернете, и я хочу четко его понять.Объяснение принципа работы openGL

Для моих вершинных шейдеров у меня есть:

Vertex

uniform vec3 fvLightPosition; 
    varying vec2 Texcoord; 
    varying vec2 Texcoordcut; 
    varying vec3 ViewDirection; 
    varying vec3 LightDirection; 
    uniform mat4 extra; 

    attribute vec3 rm_Binormal; 
    attribute vec3 rm_Tangent; 

    uniform float fSinTime0_X; 
    uniform float fCosTime0_X; 

    void main(void) 
    { 
     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * extra; 
     Texcoord = gl_MultiTexCoord0.xy; 
     Texcoordcut = gl_MultiTexCoord0.xy; 

     vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex; 

     vec3 rotationLight = vec3(fCosTime0_X,0, fSinTime0_X); 
     ViewDirection = - fvObjectPosition.xyz; 
     LightDirection = (-rotationLight) * (gl_NormalMatrix); 
    } 

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

uniform vec4 fvAmbient; 
uniform vec4 fvSpecular; 
uniform vec4 fvDiffuse; 
uniform float fSpecularPower; 

uniform sampler2D baseMap; 
uniform sampler2D bumpMap; 

varying vec2 Texcoord; 
varying vec2 Texcoordcut; 
varying vec3 ViewDirection; 
varying vec3 LightDirection; 

void main(void) 
{ 
    vec3 fvLightDirection = normalize(LightDirection); 
    vec3 fvNormal   = normalize((texture2D(bumpMap, Texcoord).xyz * 2.0) - 1.0); 
    float fNDotL   = dot(fvNormal, fvLightDirection); 
    vec3 fvReflection  = normalize(((2.0 * fvNormal) * fNDotL) - fvLightDirection); 
    vec3 fvViewDirection = normalize(ViewDirection); 
    float fRDotV   = max(0.0, dot(fvReflection, fvViewDirection)); 
    vec4 fvBaseColor  = texture2D(baseMap, Texcoord); 

    vec4 fvTotalAmbient = fvAmbient * fvBaseColor; 
    vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; 
    vec4 fvTotalSpecular = fvSpecular * (pow(fRDotV, fSpecularPower)); 


    if(fvBaseColor == vec4(1,1,1,1)){ 
     discard; 
    }else{ 
    gl_FragColor = (fvTotalDiffuse + fvTotalSpecular); 
    } 



} 

Кто-нибудь, кто может мне объяснить, что все делает? Я понимаю основную идею этого. Но не часто зачем вам это нужно, и что происходит, когда вы используете другие переменные? Что происходит, так это то, что свет вокруг чайника начинается и удаляется во времени. Как это правильно связано с переменными cosinus и sinus? Что, если я хочу, чтобы свет исходил сверху и уходил на дно чайника?

Кроме того,

  • Что эти строки означают?

    vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

  • И почему здесь минус перед переменной?

    ViewDirection = - fvObjectPosition.xyz;

  • Почему мы используем отрицательное вращение?

    LightDirection = (-rotationLight) * (gl_NormalMatrix);

  • Почему они используют * 2.0) - 1.0 для расчета нормального вектора? Разве это невозможно с Normal = normalize (gl_NormalMatrix * gl_Normal);?

    vec3 fvNormal = normalize ((texture2D (bumpMap, Texcoord) .xyz * 2.0) - 1.0);

+0

Может быть, это только у меня, но я думаю, что ваш вопрос является слишком широким. Вы говорите нам, что понимаете основную идею, но тогда ваши дальнейшие вопросы не очень специфичны. Код - это реализация модели освещения, я угадываю Phong, вы можете увидеть, как работает модель: https://en.wikipedia.org/wiki/Phong_reflection_model Вам понадобится базовое понимание матричной и векторной математики для следовать. Как только вы поймете модель, обратите внимание, что код изменяет только входящий угол света. Возможно, вы могли бы перефразировать свои вопросы или начать с основ. –

+0

Я обновил немного подробнее, какие вещи я не понял. –

+0

@TimDirks добавил ответ, отредактировал ваши теги (добавил [glsl], чтобы включить подсветку синтаксиса) – Spektre

ответ

0

Как это правильно связана с COSINUS и пазухи переменных?

Вы можете отправить данные в формулую шейдерную переменную с помощью функции glUniform. Например: в вашем вершинном шейдере у вас есть 2 значения с плавающей точкой, поэтому вы будете вызывать glUniform1f два раза каждый раз с другим местоположением и другим значением.
Или вы можете вставить переменные с плавающей точкой для одной переменной vec2 так:
uniform vec2 fSinValues; и заполнить их с glUniform2f(location, sinVal, cosVal);

Что делать, если я хочу, чтобы свет идет сверху и идет ко дну чайника?

Если вы хотите, чтобы ваш свет вращается в другом направлении, просто передать грех и потому значений в другом пространстве координат здесь: vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);

+0

Что означает эта строка? * vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex; И почему здесь минус перед переменной? ViewDirection = - fvObjectPosition.xyz; –

+0

Предположим, у вас есть куб в пространстве. Вы хотите нарисовать куб, чтобы он выглядел где-то в пространстве. Чтобы добиться этого эффекта, вам нужно умножить каждую вершину куба на набор матриц. Таким образом, умножая вершины на матрицы, он преобразует куб из трехмерного пространства в 2D-пространство, которое является вашим экраном. Если я не ошибаюсь, кусок кода 'ViewDirection = - fvObjectPosition.xyz' вычисляет направление вашего взгляда относительно вершины, поэтому вы можете рассчитать правильное освещение. – ProXicT

2

слишком ленив, чтобы полностью анализировать код без контекста Проппер того, что вы отправка шейдеры ... но ваши подвопросы достаточно легко:

  1. Что эти строки означают?vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

    Это преобразует gl_Vertex (точки краев полигона) из системы координат объекта/модели в систему координат камеры. Другими словами, он применяет все вращения и переводы ваших вершин. Ось z - это ось обзора камеры, указывающая на или с экрана, и x,y оси такие же, как и экраны. Пока не применяются выступы/обрезки/зажимки! Полученная точка хранится в fvObjectPosition 4D vector (x,y,z,w) Я настоятельно рекомендую вам прочитать Understanding 4x4 homogenous transform matrices, а также ссылки, которые также стоит посмотреть.

  2. И почему здесь минус перед переменной?ViewDirection = - fvObjectPosition.xyz;

    Скорее всего потому, что вам нужно направление от поверхности камеры так direction_from_surface=camera_pos-surface_pos как ваш surface_pos уже в системе координат камеры затем положение камеры в тех же координатах (0,0,0) поэтому результат direction_from_surface=(0,0,0)-surface_pos=-surface_pos или вы получили отрицательный результат Z оси направления взгляда (зависит от формата ваших матриц). Трудно определить без фоновой информации.

  3. Почему мы используем отрицательное вращение?LightDirection = (-rotationLight) * (gl_NormalMatrix);

    , скорее всего, по тем же причинам, что и пули 2

  4. Почему они используют *2.0)-1.0 для расчета normalvector?

    Использование шейдера normal/bump mapping, что означает, что вы получили текстуру с нормальными векторами, закодированными как RGB. Как RGB текстуры зажаты в диапазоне <0,1> и вектор нормали координаты находятся в диапазоне <-1,+1> то вам просто нужно изменить масштаб Текселем Итак:

    • RGB*2.0 находится в диапазоне <0,2>
    • RGB*2.0-1.0 находится в диапазоне <-1,+1>

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

    • плоская поверхность имеет normal=(0.0,0.0,+1.0) поэтому в RGB было бы (0.5,0.5,1.0)

    То есть общий цвет голубовато/пурпурного часто видели в текстур (см ссылку выше).

    Но Да, вы можете использовать Normal = normalize(gl_NormalMatrix * gl_Normal);

    Но это устранит рельефности/нормальную карту, и вы бы получили только плоские поверхности вместо этого. Что-то вроде этого:

  5. Light

    vec3(fCosTime0_X,0, fSinTime0_X) выглядит как направление света. Он вращается вокруг оси y. Если вы хотите изменить направление света на что-то другое просто сделать его однородным и передать его непосредственно в шейдер вместо fCosTime0_X,fSinTime0_X

Смежные вопросы