La iluminación basada en píxeles es un problema común en muchas aplicaciones OpenGL, ya que la iluminación estándar de OpenGL tiene muy mala calidad.Generic GLSL Lighting Shader
Quiero utilizar un programa GLSL para tener iluminación basada en píxeles en mi programa OpenGL en lugar de por vértice. Solo iluminación difusa, pero con niebla, textura y textura alfa por lo menos.
Empecé con this shader:
texture.vert:
varying vec3 position;
varying vec3 normal;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
normal = normalize(gl_NormalMatrix * gl_Normal);
position = vec3(gl_ModelViewMatrix * gl_Vertex);
}
texture.frag:
uniform sampler2D Texture0;
uniform int ActiveLights;
varying vec3 position;
varying vec3 normal;
void main(void)
{
vec3 lightDir;
float attenFactor;
vec3 eyeDir = normalize(-position); // camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0,0.0,0.0,0.0);
vec4 lightSpecular = vec4(0.0,0.0,0.0,0.0);
// iterate all lights
for (int i=0; i<ActiveLights; ++i)
{
// attenuation and light direction
if (gl_LightSource[i].position.w != 0.0)
{
// positional light source
float dist = distance(gl_LightSource[i].position.xyz, position);
attenFactor = 1.0/(gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation * dist * dist);
lightDir = normalize(gl_LightSource[i].position.xyz - position);
}
else
{
// directional light source
attenFactor = 1.0;
lightDir = gl_LightSource[i].position.xyz;
}
// ambient + diffuse
lightAmbientDiffuse += gl_FrontLightProduct[i].ambient*attenFactor;
lightAmbientDiffuse += gl_FrontLightProduct[i].diffuse * max(dot(normal, lightDir), 0.0) * attenFactor;
// specular
vec3 r = normalize(reflect(-lightDir, normal));
lightSpecular += gl_FrontLightProduct[i].specular *
pow(max(dot(r, eyeDir), 0.0), gl_FrontMaterial.shininess) *
attenFactor;
}
// compute final color
vec4 texColor = gl_Color * texture2D(Texture0, gl_TexCoord[0].xy);
gl_FragColor = texColor * (gl_FrontLightModelProduct.sceneColor + lightAmbientDiffuse) + lightSpecular;
float fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale; // Intensität berechnen
fog = clamp(fog, 0.0, 1.0); // Beschneiden
gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); // Nebelfarbe einmischen
}
Los comentarios son alemán porque es un sitio alemán donde fue publicada este código , lo siento.
Pero todo lo que hace este sombreador es hacer que todo sea muy oscuro. Sin efectos de iluminación en absoluto, sin embargo, los códigos de sombreado se compilan. Si solo uso GL_LIGHT0 en el sombreador de fragmentos, parece que funciona, pero solo es razonable para los polígonos que miran hacia la cámara y el polígono de mi piso es extremadamente oscuro. Además, los quads con texturas RGBA no muestran signos de transparencia. Uso glRotate/Translate estándar para la matriz Modelview y glVertex/Normal para mis polígonos. La iluminación OpenGL funciona bien, aparte del hecho de que se ve feo en superficies muy grandes. Comprobé tres veces mis normales, están bien.
¿Hay algún error en el código anterior? O Dime por qué no existe un Shader de iluminación genérico para esta tarea real (luz basada en puntos con caída de distancia: una vela si se quiere) - ¿no debería haber solo una forma correcta de hacerlo? No quiero los efectos de bache/normal/paralaje/toon/desenfoque/cualesquiera. Solo quiero que mi iluminación funcione mejor con polígonos más grandes.
Todos los tutoriales que encontré son útiles solo para iluminar un solo objeto cuando la cámara está a 0,0,0 de cara ortogonal al objeto. Lo anterior es el único que se encuentra que al menos se parece a lo que quiero hacer.
Lo obvio primero: ¿ha enlazado una muestra, son correctos sus cordones de textura y normales, ¿muestra la geometría si establece gl_FragColor en un color fijo?Con los sombreadores me resulta más fácil entenderlos usando y agregando pequeñas características de una en una, a falta de poder entrar y rastrearlas: p. – Robinson
La muestra es TEXTURE_2D y está ligada a las polis renderizadas. Los cordones de textura son correctos, ya que la iluminación de OpenGL normal funciona de manera impecable. Los normales son perfectos (como ya se dijo). Sí, muestra la Geometría al configurar gl_FragColor en un color fijo o solo en texColor. – Rock