c++ - obj - opengl vertex index
OpenGL-normales de vértices en OBJ (1)
mapas normales / de relieve
Brinde detalles finos sin aumentar la complejidad de la geometría, lo que significa más detalles con un costo de rendimiento muy bajo. Los mapas normales / de relieve son opcionales o bastos.
sombreado normal (sombreador de fragmentos)
Normal es el vector perpendicular al fragmento / cara / primitivo, hay dos usos para él:
iluminación superficial opaca
tengamos:
-
color
- por fragmento / cara / color primitivo (modulado con textura) -
normal
- por fragmento / cara / primitiva 3D vector normal (apuntando fuera de malla) -
lt_ambient,lt_direct
- el color y la fuerza de las luces -
lt_direct_dir
- dirección direccional de la luz
entonces la salida es fácil:
-
fragment_color=(lt_ambient+(lt_direct*dot(lt_direct_dir,-normal))*color;
esto se llama sombreado normal
dot
devuelve elcos(angle between light and normal)
si quiere tener geometrías en los lados de la cabina y luego usafabs(dot(...))
. Los vectores de color y fuerza de la luz sumados no deberían exceder 1.0 por canal; de lo contrario, la sujeción podría causar artefactos de color. Use por ejemplo:-
lt_ambient=(0.2,0.2,0.2)
-
lt_direct =(0.8,0.8,0.8)
como
lt_direct_dir
puede usar(fragment_xyz-Sun.xyz)
y normalizar en vector unitario o usar la dirección de visualización de la cámara. Debe tener un vector unitario para el producto escalado, de lo contrario no funcionará correctamente-
reflexión
si tiene un mapa de entorno ( cube_map ), puede agregar reflejos. Obtienes las coordenadas del fragmento
(x,y,z)
ynormal
para que puedas calcular la dirección de la dirección de visualización reflejada y agregar el texel al que apunta al resultado fragment_color.Hay más cosas como reflejos especulares y diferentes ecuaciones de luz, pero creo que primero debes comenzar con sombreado normal. Cuando tienes lo básico, entonces no hay problema para entender las cosas más avanzadas, solo recuerda lo que hay detrás ...
[edit1] así como eres novato, obviamente necesitas un ejemplo completo para comenzar:
Así que aquí completa el ejemplo GL + VAO / VBO + GLSL + shaders en C ++. Como uso el entorno de Borland, está en la aplicación de formulario VCL, así que simplemente ignore las cosas de VCL y extraiga solo lo que necesita. Así es como esto luce:
Esa cruz es mi posición de punto de luz para verificar visualmente la corrección y esa flecha (dibujada a mano) muestra la dirección promedio de la luz.
normal_shading.glsl_vert
// Vertex
#version 400 core
layout(location = 0) in vec3 pos;
layout(location = 2) in vec3 nor;
layout(location = 3) in vec3 col;
uniform mat4 m_model; // model matrix
uniform mat4 m_normal; // model matrix with origin=(0,0,0)
uniform mat4 m_view; // inverse of camera matrix
uniform mat4 m_proj; // projection matrix
out vec3 pixel_pos; // fragment position [GCS]
out vec3 pixel_col; // fragment surface color
out vec3 pixel_nor; // fragment surface normal [GCS]
void main()
{
pixel_col=col;
pixel_pos=(m_model*vec4(pos,1)).xyz;
pixel_nor=(m_normal*vec4(nor,1)).xyz;
gl_Position=m_proj*m_view*m_model*vec4(pos,1);
}
normal_shading.glsl_frag
// Fragment
#version 400 core
uniform vec3 lt_pnt_pos;// point light source position [GCS]
uniform vec3 lt_pnt_col;// point light source color&strength
uniform vec3 lt_amb_col;// ambient light source color&strength
in vec3 pixel_pos; // fragment position [GCS]
in vec3 pixel_col; // fragment surface color
in vec3 pixel_nor; // fragment surface normal [GCS]
out vec4 col;
void main()
{
float li;
vec3 c,lt_dir;
lt_dir=normalize(lt_pnt_pos-pixel_pos); // vector from fragment to point light source in [GCS]
li=dot(pixel_nor,lt_dir);
if (li<0.0) li=0.0;
c=pixel_col*(lt_amb_col+(lt_pnt_col*li));
col=vec4(c,1.0);
}
gl_simple.h
//---------------------------------------------------------------------------
#define GLEW_STATIC
#include "glew.c"
#include <gl/gl.h>
#include <gl/glu.h>
//---------------------------------------------------------------------------
//--- OpenGL GL example -----------------------------------------------------
//---------------------------------------------------------------------------
int xs,ys; // screen size
HDC hdc=NULL; // device context
HGLRC hrc=NULL; // rendering context
int gl_inicialized=0;
int gl_init(HWND Handle);
void gl_exit();
void gl_draw();
void gl_resize(int _xs,int _ys);
//---------------------------------------------------------------------------
//--- OpenGL GLSL example ---------------------------------------------------
//---------------------------------------------------------------------------
GLint prog_id=0, // whole program
vert_id=0, // vertex shader
frag_id=0; // fragment shader
char glsl_log[4096];// compile/link GLSL log
int glsl_logs=0;
void glsl_init(char *vert,char *frag); // create/compile/link GLSL program
void glsl_exit();
//---------------------------------------------------------------------------
//--- OpenGL VAO example ----------------------------------------------------
//---------------------------------------------------------------------------
#pragma pack(1)
//#define vao_indices
GLuint vbo[4]={-1,-1,-1,-1};
GLuint vao[4]={-1,-1,-1,-1};
const GLfloat vao_pos[]=
{
// x y z //ix
-1.0,-1.0,-1.0, //0
+1.0,-1.0,-1.0, //1
+1.0,+1.0,-1.0, //2
-1.0,+1.0,-1.0, //3
-1.0,-1.0,+1.0, //4
+1.0,-1.0,+1.0, //5
+1.0,+1.0,+1.0, //6
-1.0,+1.0,+1.0, //7
#ifndef vao_indices
-1.0,-1.0,-1.0, //0
+1.0,-1.0,-1.0, //1
+1.0,-1.0,+1.0, //5
-1.0,-1.0,+1.0, //4
+1.0,-1.0,-1.0, //1
+1.0,+1.0,-1.0, //2
+1.0,+1.0,+1.0, //6
+1.0,-1.0,+1.0, //5
+1.0,+1.0,-1.0, //2
-1.0,+1.0,-1.0, //3
-1.0,+1.0,+1.0, //7
+1.0,+1.0,+1.0, //6
-1.0,+1.0,-1.0, //3
-1.0,-1.0,-1.0, //0
-1.0,-1.0,+1.0, //4
-1.0,+1.0,+1.0, //7
#endif
};
const GLfloat vao_col[]=
{
// r g b //ix
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,0.0,1.0, //4
1.0,0.0,1.0, //5
1.0,1.0,1.0, //6
0.0,1.0,1.0, //7
#ifndef vao_indices
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,0.0,1.0, //5
0.0,0.0,1.0, //4
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
1.0,1.0,1.0, //6
1.0,0.0,1.0, //5
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,1.0,1.0, //7
1.0,1.0,1.0, //6
0.0,1.0,0.0, //3
0.0,0.0,0.0, //0
0.0,0.0,1.0, //4
0.0,1.0,1.0, //7
#endif
};
#ifndef vao_indices
const GLfloat vao_nor[]=
{
// nx ny nz //ix
0.0, 0.0,-1.0, //0
0.0, 0.0,-1.0, //1
0.0, 0.0,-1.0, //2
0.0, 0.0,-1.0, //3
0.0, 0.0,+1.0, //4
0.0, 0.0,+1.0, //5
0.0, 0.0,+1.0, //6
0.0, 0.0,+1.0, //7
0.0,-1.0, 0.0, //0
0.0,-1.0, 0.0, //1
0.0,-1.0, 0.0, //5
0.0,-1.0, 0.0, //4
+1.0, 0.0, 0.0, //1
+1.0, 0.0, 0.0, //2
+1.0, 0.0, 0.0, //6
+1.0, 0.0, 0.0, //5
0.0,+1.0, 0.0, //2
0.0,+1.0, 0.0, //3
0.0,+1.0, 0.0, //7
0.0,+1.0, 0.0, //6
-1.0, 0.0, 0.0, //3
-1.0, 0.0, 0.0, //0
-1.0, 0.0, 0.0, //4
-1.0, 0.0, 0.0, //7
};
#endif
#ifdef vao_indices
const GLuint vao_ix[]=
{
0,1,2,3,
4,5,6,7,
0,1,5,4,
1,2,6,5,
2,3,7,6,
3,0,4,7,
};
#endif
#pragma pack()
void vao_init();
void vao_exit();
void vao_draw();
//---------------------------------------------------------------------------
//--- bodies: ---------------------------------------------------------------
//---------------------------------------------------------------------------
int gl_init(HWND Handle)
{
if (gl_inicialized) return 1;
hdc = GetDC(Handle); // get device context
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) ); // set the pixel format for the DC
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
hrc = wglCreateContext(hdc); // create current rendering context
if(hrc == NULL)
{
ShowMessage("Could not initialize OpenGL Rendering context !!!");
gl_inicialized=0;
return 0;
}
if(wglMakeCurrent(hdc, hrc) == false)
{
ShowMessage("Could not make current OpenGL Rendering context !!!");
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
return 0;
}
gl_resize(1,1);
glEnable(GL_DEPTH_TEST); // Zbuf
glDisable(GL_CULL_FACE); // vynechavaj odvratene steny
glDisable(GL_TEXTURE_2D); // pouzivaj textury, farbu pouzivaj z textury
glDisable(GL_BLEND); // priehladnost
glShadeModel(GL_SMOOTH); // gourard shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color
gl_inicialized=1;
glewInit();
return 1;
}
//---------------------------------------------------------------------------
void gl_exit()
{
if (!gl_inicialized) return;
wglMakeCurrent(NULL, NULL); // release current rendering context
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
}
//---------------------------------------------------------------------------
void gl_resize(int _xs,int _ys)
{
xs=_xs;
ys=_ys;
if (xs<=0) xs = 1; // Prevent a divide by zero
if (ys<=0) ys = 1;
if (!gl_inicialized) return;
glViewport(0,0,xs,ys); // Set Viewport to window dimensions
glMatrixMode(GL_PROJECTION); // operacie s projekcnou maticou
glLoadIdentity(); // jednotkova matica projekcie
gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
glMatrixMode(GL_TEXTURE); // operacie s texturovou maticou
glLoadIdentity(); // jednotkova matica textury
glMatrixMode(GL_MODELVIEW); // operacie s modelovou maticou
glLoadIdentity(); // jednotkova matica modelu (objektu)
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void glsl_init(char *vert,char *frag)
{
const int _size=1024;
GLint status,siz=0,i;
const char * VS = vert;
const char * FS = frag;
glsl_logs=0;
if (prog_id<=0) prog_id=glCreateProgram();
if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER); else glDetachShader(prog_id,vert_id);
if (vert)
{
glShaderSource(vert_id, 1, &VS,NULL);
glCompileShader(vert_id);
glAttachShader(prog_id,vert_id);
glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status);
const char t[]="[Vertex]/r/n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(vert_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER); else glDetachShader(prog_id,frag_id);
if (frag)
{
glShaderSource(frag_id, 1, &FS,NULL);
glCompileShader(frag_id);
glAttachShader(prog_id,frag_id);
glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status);
const char t[]="[Fragment]/r/n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(frag_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
glLinkProgram(prog_id);
glGetProgramiv(prog_id,GL_LINK_STATUS,&status);
const char t[]="[Program]/r/n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(prog_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
glReleaseShaderCompiler();
glsl_log[glsl_logs]=0;
}
//------------------------------------------------------------------------------
void glsl_exit()
{
glUseProgram(0);
if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); }
if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); }
if (prog_id>0) { glDeleteShader(prog_id); }
glsl_log[0]=0;
}
//---------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vao_init()
{
GLuint i;
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);
glBindVertexArray(vao[0]);
i=0; // vertex
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
i=1; // indices
#ifdef vao_indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,4,GL_UNSIGNED_INT,GL_FALSE,0,0);
#endif
i=2; // normal
#ifndef vao_indices
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_nor),vao_nor,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
#endif
i=3; // color
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
}
//---------------------------------------------------------------------------
void vao_exit()
{
glDeleteVertexArrays(4,vao);
glDeleteBuffers(4,vbo);
}
//---------------------------------------------------------------------------
void vao_draw()
{
glBindVertexArray(vao[0]);
#ifndef vao_indices
glDrawArrays(GL_QUADS,0,sizeof(vao_pos)/sizeof(GLfloat)); // QUADS ... no indices
#endif
#ifdef vao_indices
glDrawElements(GL_QUADS,sizeof(vao_idx)/sizeof(GLuint),GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!)
#endif
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Fuente de forma principal de la aplicación VCL:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "gl_simple.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
GLfloat lt_pnt_pos[3]={+2.5,+2.5,+2.5};
GLfloat lt_pnt_col[3]={0.8,0.8,0.8};
GLfloat lt_amb_col[3]={0.2,0.2,0.2};
//---------------------------------------------------------------------------
void gl_draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// load values into shader
GLint i,id;
GLfloat m[16];
glUseProgram(prog_id);
id=glGetUniformLocation(prog_id,"lt_pnt_pos"); glUniform3fv(id,1,lt_pnt_pos);
id=glGetUniformLocation(prog_id,"lt_pnt_col"); glUniform3fv(id,1,lt_pnt_col);
id=glGetUniformLocation(prog_id,"lt_amb_col"); glUniform3fv(id,1,lt_amb_col);
glGetFloatv(GL_MODELVIEW_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_model" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
m[12]=0.0; m[13]=0.0; m[14]=0.0;
id=glGetUniformLocation(prog_id,"m_normal" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
for (i=0;i<16;i++) m[i]=0.0; m[0]=1.0; m[5]=1.0; m[10]=1.0; m[15]=1.0;
id=glGetUniformLocation(prog_id,"m_view" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
glGetFloatv(GL_PROJECTION_MATRIX,m);
id=glGetUniformLocation(prog_id,"m_proj" ); glUniformMatrix4fv(id,1,GL_FALSE,m);
// draw VAO cube
vao_draw();
// turn of shader
glUseProgram(0);
// rotate the cube to see animation
glMatrixMode(GL_MODELVIEW);
glRotatef(1.0,0.0,1.0,0.0);
glRotatef(1.0,1.0,0.0,0.0);
// render point light source in [GCS]
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLfloat x,y,z,d=0.25;
x=lt_pnt_pos[0];
y=lt_pnt_pos[1];
z=lt_pnt_pos[2];
glBegin(GL_LINES);
glColor3fv(lt_pnt_col);
glVertex3f(x-d,y,z);
glVertex3f(x+d,y,z);
glVertex3f(x,y-d,z);
glVertex3f(x,y+d,z);
glVertex3f(x,y,z-d);
glVertex3f(x,y,z+d);
glEnd();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
gl_init(Handle);
int hnd,siz; char vertex[4096],fragment[4096];
hnd=FileOpen("normal_shading.glsl_vert",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,vertex ,siz); vertex [siz]=0; FileClose(hnd);
hnd=FileOpen("normal_shading.glsl_frag",fmOpenRead); siz=FileSeek(hnd,0,2); FileSeek(hnd,0,0); FileRead(hnd,fragment,siz); fragment[siz]=0; FileClose(hnd);
glsl_init(vertex,fragment);
hnd=FileCreate("GLSL.txt"); FileWrite(hnd,glsl_log,glsl_logs); FileClose(hnd);
vao_init();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
gl_exit();
glsl_exit();
vao_exit();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
gl_resize(ClientWidth,ClientHeight);
glMatrixMode(GL_PROJECTION);
glTranslatef(0,0,-15.0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled)
{
GLfloat dz=2.0;
if (WheelDelta<0) dz=-dz;
glMatrixMode(GL_PROJECTION);
glTranslatef(0,0,dz);
gl_draw();
}
//---------------------------------------------------------------------------
No se olvide de cambiar los diseños a los suyos, agregue texturas y cosas solo si esto ya está funcionando y siempre verifique el GLSL.txt
(compilación / registro de enlaces) para ver si todo es como debe ser.
También necesitas GLEW para esto, así que mira
- GLEW sourceforge
- Construyendo glew en windows con mingw32
Quiero saber cómo puedo usar las normales de los vértices para el efecto del rayo. Actualmente, lo que tengo es que puedo enviar coords de vértice y de textura al sombreador y usarlos, pero con las normales, no sé cómo usarlas en el programa de sombreado. Debajo está lo que tengo hasta ahora.
// vertex shader
layout(location = 0) in vec4 vert;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texcoord;
uniform mat4 m_model;
uniform mat4 m_view;
uniform mat4 m_proj;
void main() {
gl_Position = m_proj * m_view * m_model * vert;
}
// fragment shader
in vec2 fragtexcoord;
out vec4 color;
uniform sampler2D textureunit;
void main(void) {
color = texture(textureunit, fragtexcoord);
}
EDITAR Aquí están mis sombreadores por ahora.
sombreador de vértices
layout(location = 0) in vec4 vert;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texcoord;
layout(location = 3) in vec4 normal;
out vec4 LightIntensity;
uniform vec4 LightPosition;
uniform vec4 Kd;
uniform vec4 Ld;
uniform mat4 m_model;
uniform mat4 m_view;
uniform mat4 m_proj;
void main() {
gl_Position = m_proj * m_view * m_model * vert;
mat4 normalmatrix = transpose(inverse(m_view));
vec4 tnorm = normalize(normalmatrix * normal);
vec4 eyeCoords = m_model * vec4(vert);
vec4 s = normalize(vec4(LightPosition - eyeCoords));
LightIntensity = Ld * Kd * max(dot(s, tnorm), 0.0);
}
Fragmento sombreador.
in vec4 LightIntensity;
out vec4 color;
void main(void) {
color = vec4(LightIntensity);
}
Actualmente obtiene un cubo negro sin sombreado. Probablemente hice algo mal aquí en el sombreado, que no tengo ni idea de cuál :(
ACTUALIZAR:
vértice
layout(location = 0) in vec4 vert;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texcoord;
layout(location = 3) in vec4 normal;
out vec2 fragtexcoord;
out vec4 fragnormal;
uniform mat4 m_model;
uniform mat4 m_view;
uniform mat4 m_proj;
void main() {
gl_Position = m_proj * m_view * m_model * vert;
fragtexcoord = texcoord;
fragnormal = normal;
}
fragmento
in vec2 fragtexcoord;
in vec4 fragnormal;
out vec4 fragment_color;
uniform sampler2D textureunit;
void main(void) {
vec4 lt_ambient = vec4(0.2, 0.2, 0.2, 1.0);
vec4 lt_direct = vec4(0.8, 0.8, 0.8, 1.0);
vec4 lt_direct_dir = vec4(1.5, 1.0, 1.0, 1.0);
vec4 color = texture(textureunit, fragtexcoord);
fragment_color = (lt_ambient + (lt_direct * dot(lt_direct_dir, -fragnormal))) * color;
}
No sé qué poner para lt_direct_dir por eso tiene valores como ese :)
ACTUALIZACIÓN: A continuación están los sombreadores de trabajo para mí
// vertex shader
layout(location = 0) in vec4 vert;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 texcoord;
layout(location = 3) in vec4 normal;
out vec4 fragposition;
out vec4 fragcolor;
out vec4 fragnormal;
out vec2 fragtexcoord;
uniform mat4 m_model;
uniform mat4 m_view;
uniform mat4 m_proj;
uniform vec4 lightpos;
void main() {
gl_Position = m_proj * m_view * m_model * vert;
mat4 m_normal = transpose(inverse(m_model));
fragposition = m_model * vert;
fragnormal = m_normal * normal;
fragtexcoord = texcoord;
}
// fragment shader
in vec4 fragposition;
in vec4 fragnormal;
in vec2 fragtexcoord;
out vec4 fragment_color;
uniform sampler2D textureunit;
void main() {
vec4 lt_pnt_pos = vec4(2.5, 2.5, 2.5, 1.0);
vec4 lt_pnt_col = vec4(0.8, 0.8, 0.8, 1.0);
vec4 lt_amb_col = vec4(0.2, 0.2, 0.2, 1.0);
vec4 lt_dir = normalize(lt_pnt_pos - fragposition);
float li = dot(fragnormal, lt_dir);
if(li < 0.0) {
li = 0.0;
}
vec4 color = texture(textureunit, fragtexcoord);
fragment_color = color * (lt_amb_col + (lt_pnt_col * li));
}