(Изменить): исходный код, который я разместил, был предназначен как для gouraud, так и для теневого фона. Я изменил это так, чтобы это было просто затенением фонга и отправлено ниже. Сетка слишком велика, чтобы описывать ее здесь, так как она генерируется из патча Безье.
В Open GL 3 Mesa 9 у меня есть некоторые проблемы с плоским и фоновым затенением. Кажется, что независимо от того, что я делаю, я получаю плоские заштрихованные фигуры с крошечными гранями (плоскостями) и не могу заставить работать затенение Блинна-Фонга.
Вот мои шейдеры:
(Вершинный шейдер)
//material parameters
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;attribute vec4 vPosition;
//attribute vec4 vColor;
attribute vec4 vNormal;
attribute vec4 vControlColor;
attribute vec2 texcoord;uniform mat4 model_view;
uniform mat4 projection;
uniform int flag;
uniform int phong_flag;
uniform vec4 eye_position;
//lighting parameters
uniform vec4 light_1; //light 1 position
uniform vec4 light_2; //light 2 positionvarying vec4 control_color;
varying vec4 color;
varying vec4 position;
varying vec4 normal;
varying vec2 st;
void
main()
{
control_color = vControlColor;
position = vPosition;
normal = vNormal;
tex_coords = texcoord;
st = texcoord;
gl_Position = projection*model_view*vPosition;
}
И мой фрагмент шейдера:
//material parameters
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform float Shininess;
uniform vec4 eye_position;
uniform int phong_flag;//lighting parameters
uniform vec4 light_1; //light 1 position
uniform vec4 light_2; //light 2 position
varying vec4 light_2_transformed; //light 2 transformed position
uniform int Control_Point_Flag;
uniform sampler2D texMap;
varying vec4 color;
varying vec4 position;
varying vec4 normal;
varying vec4 control_color;
varying vec2 st;
void
main()
{
vec4 N = normalize(normal);
vec4 E = normalize(eye_position - position);
vec4 L1 = normalize(light_1 - position);
vec4 L2 = normalize(light_2 - position);
vec4 H1 = normalize( L1 + E);
vec4 H2 = normalize( L2 + E);
//calculate ambient component
vec4 ambient = AmbientProduct;//calculate diffuse componenent
float k_d_1 = max(dot(L1,N), 0.0);
float k_d_2 = max(dot(L2,N), 0.0);
vec4 diffuse1 = k_d_1*DiffuseProduct;
vec4 diffuse2 = k_d_2*DiffuseProduct;
//calculate specular componenent
float k_s_1 = pow(max(dot(N, H1), 0.0), Shininess);
float k_s_2 = pow(max(dot(N, H2), 0.0), Shininess);
vec4 specular1 = k_s_1*SpecularProduct;
vec4 specular2 = k_s_2*SpecularProduct;
//if specular color is behind the camera, discard it
if (dot(L1, N) < 0.0) {
specular1 = vec4(0.0, 0.0, 0.0, 1.0);
}
if (dot(L2, N) < 0.0) {
specular2 = vec4(0.0, 0.0, 0.0, 1.0);
}vec4 final_color = ambient + diffuse1 + diffuse2 + specular1 + specular2;
final_color.a = 1.0;
/* gl_FragColor = final_color; */
gl_FragColor = final_color*texture2D(texMap, st);
}
Все ли хорошо выглядит для моих шейдеров?
Что стоит отметить:
position
, Твоя вершина «position
Таким образом, все, что передается из вашего приложения OpenGL, не подвержено влиянию каких-либо преобразований, которые вы, возможно, пытаетесь выполнить, хотя они физически правильно размещены, потому что вы используете матрицы для gl_Position
,Тем не менее, ваши нормальные векторы на стороне OpenGL могут быть виновником. Увидеть этот вопрос для хорошего объяснения возможного источника нежелательного плоского затенения.
Как примечание: оба ваших шейдера кажутся более сложными, чем они должны быть. Иными словами, у них слишком много переменных, которые не используются, и слишком много вещей, которые можно сжать в меньшее количество строк. Это просто ведение домашнего хозяйства, но это облегчит отслеживание вашего кода.
Других решений пока нет …