Программирование шейдеров, создание легкого взаимодействия с изображением

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

Как я должен сделать это хорошим способом, я не хочу использовать свет openGL по умолчанию, хочу определить один сам.

Допустим, я создаю цвет из переменной lightColor, коэффициента блеска с плавающей точкой и vec3 lightPos с x, y а также z положение источника света. В конвейере по умолчанию положения света выражаются в координатах камеры. Как мне сделать это наилучшим образом?

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

1 ответ

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

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

#version 120

attribute vec4 Position;
attribute vec2 TexCoord;
attribute vec3 Normal;

uniform vec4 LightPosition;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;

varying vec2 texCoord;
varying float DiffuseIntensity;
varying float SpecularIntensity;

void main()
{
    vec3 lightPosition= vec3(LightPosition);
    float shininess = 30.0;

    vec3 ecPosition = vec3(ViewMatrix * ModelMatrix * Position);
    vec3 tnorm = normalize(NormalMatrix * Normal);
    vec3 lightVec = normalize(lightPosition - ecPosition);
    vec3 reflectVec = reflect(-lightVec, tnorm);
    vec3 viewVec = normalize(-ecPosition);
    float spec = clamp(dot(reflectVec, viewVec), 0.0, 1.0);

    SpecularIntensity = pow(spec, shininess / 5.0);

    DiffuseIntensity = max(dot(lightVec, tnorm), 0.0);

    texCoord = TexCoord;

    gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * Position;
}

Фрагмент шейдера:

#version 120

uniform sampler2D Texture;
uniform vec4 Emission;
uniform vec4 Ambient;
uniform vec4 Diffuse;
uniform vec4 Specular;

varying vec2 texCoord;
varying float DiffuseIntensity;
varying float SpecularIntensity;

void main()
{
    vec3 emission = vec3(Emission);
    vec3 ambient = vec3(Ambient);
    vec3 diffuse = vec3(Diffuse);
    vec3 specular = vec3(Specular);

    vec3 lightColor = emission;
    lightColor = lightColor + ambient;
    lightColor = lightColor + (SpecularIntensity * specular);
    lightColor = lightColor + (DiffuseIntensity * diffuse);

    vec3 face = texture2D(Texture, texCoord).rgb * lightColor;
    face = clamp(face, 0.0, 1.0);

    gl_FragColor = vec4(face, 1.0);

}

РЕДАКТИРОВАТЬ:

Чтобы проиллюстрировать использование ключевого слова "отбросить" (которое можно использовать только в фрагментном шейдере), я изменил последние несколько строк фрагментного шейдера так:

vec3 face = texture2D(FaceTexture, texCoord).rgb * lightColor;
face = clamp(face, 0.0, 1.0);

if((texCoord[0] >= 0.45 && texCoord[0] <= 0.55) || (texCoord[1] >= 0.45 && texCoord[1] <= 0.55))
{
    discard;
}

gl_FragColor = vec4(face, 1.0);

Это создало крестообразное отверстие в текстуре. Конечно, вы можете использовать любое условие, которое вы хотите в операторе if.

Другие вопросы по тегам