Программирование шейдеров, создание легкого взаимодействия с изображением
Я пытаюсь изучить программирование шейдеров в 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.