opengl - texture - Sombreador de iluminación GLSL genérico
texture in opengl c++ (1)
Le sugeriría encarecidamente que lea este artículo para ver cómo se realiza el rayo ADS estándar dentro de GLSL. Eso es GL 4.0 pero no es un problema para ajustarlo a su versión:
También opera en el espacio de visualización (cámara), por lo que NO "T" niega el vector de ojos:
vec3 eyeDir = normalize(-position);
Tuve problemas muy similares a los suyos porque también negué el vector ocular, olvidando que se transforma en el espacio de la vista. Sus cálculos difusos y especulares también parecen estar equivocados en el escenario actual. En su lugar, no usaría datos del tubería fija en absoluto, de lo contrario, ¿cuál es el punto de hacerlo en un shader? Este es el método para calcular difuso y especular en el rayo de puntos ADS por fragmento:
void ads( int lightIndex,out vec3 ambAndDiff, out vec3 spec )
{
vec3 s = vec3(lights[lightIndex].Position - posOut) ;
vec3 v = normalize( posOut.xyz );
vec3 n = normalize(normOut);
vec3 h = normalize(v+s) ;// half vector (read in the web on what it is )
vec3 diffuse = ((Ka+ lights[lightIndex].Ld) * Kd * max( 0.0,dot(n, v) )) ;
spec = Ks * pow( max(0.0, dot(n,h) ), Shininess ) ;
ambAndDiff = diffuse ;
/// Ka-material ambient factor
/// Kd-material diffuse factor
/// Ks-material specular factor.
/// lights[lightIndex].Ld-lights diffuse factor;you may also add La and Ls if you want to have even more control of the light shading.
}
Además, no te sugiero que utilices la ecuación de atenuación que tienes aquí, es difícil de controlar. Si quieres agregar atenuación basada en el radio de luz, hay una bonita publicación en el blog:
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 una calidad muy baja.
Quiero usar un programa GLSL para tener iluminación basada en píxeles en mi programa OpenGL en lugar de por vértice. Solo difunde la iluminación, pero con niebla, textura y textura-alfa al menos.
Comencé con este shader :
textura.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);
}
textura.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 alemanes porque es un sitio alemán donde se publicó este código, lo siento.
Pero todo lo que hace este shader es hacer que todo sea muy oscuro. No tiene ningún efecto de iluminación, pero los códigos de sombreado se compilan. Si solo uso GL_LIGHT0 en el fragmento de sombreado, entonces parece que funciona, pero solo es razonable para los polígonos que se enfrentan a la cámara y mi polígono de piso es extremadamente oscuro. También los quads con texturas RGBA no muestran signos de transparencia. Utilizo 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 fea en superficies muy grandes. Revisé tres veces mis normales, están bien.
¿Hay algo mal en el código anterior? O Dígame por qué no hay un Shader de iluminación genérico para esta tarea real (luz basada en puntos con caída de distancia: una vela, si así lo desea). ¿No debería haber una sola manera correcta de hacer esto? No quiero efectos bump / normal / parallax / toon / blur / lo que sea. Solo quiero que mi iluminación funcione mejor con polígonos más grandes.
Todos los tutoriales que encontré solo son útiles para iluminar un solo objeto cuando la cámara se encuentra en 0,0,0 con orientación ortogonal al objeto. Lo anterior es el único encontrado que al menos se parece a lo que quiero hacer.